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@
libdir = @libdir@
datarootdir = @datarootdir@
datadir = @datadir@
mandir = @mandir@
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
#--------------------------------------------------------------------
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

View File

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

18
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh
# 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,
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite'
PACKAGE_VERSION='3.8.6'
PACKAGE_STRING='sqlite 3.8.6'
PACKAGE_VERSION='3.8.7'
PACKAGE_STRING='sqlite 3.8.7'
PACKAGE_BUGREPORT=''
# 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.
# This message is too long to be a string in the A/UX 3.1 sh.
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]...
@ -1548,7 +1548,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.8.6:";;
short | recursive ) echo "Configuration of sqlite 3.8.7:";;
esac
cat <<\_ACEOF
@ -1664,7 +1664,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
sqlite configure 3.8.6
sqlite configure 3.8.7
generated by GNU Autoconf 2.62
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
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
$ $0 $@
@ -14021,7 +14021,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
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
CONFIG_FILES = $CONFIG_FILES
@ -14074,7 +14074,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\
sqlite config.status 3.8.6
sqlite config.status 3.8.7
configured by $0, generated by GNU Autoconf 2.62,
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.
D 2014-08-19T00:33:22.234
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-21T16:09:36.975
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in d5ad373b7a23525414b8843b3084cf90c560d92f
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.msc f1bbf555916b6e60887d86cea62f27e6a26cdb24
F Makefile.vxworks 034289efa9d591b04b1a73598623119c306cbba0
F README.md 64f270c43c38c46de749e419c22f0ae2f4499fe8
F VERSION 1c877615a9db323e3cd301e3d57d853f9d5c4a07
F VERSION 53a0b870e7f16d3b06623c31d233a304c163a6af
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F addopcodes.awk 9eb448a552d5c0185cf62c463f9c173cedae3811
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
@ -23,22 +23,22 @@ F autoconf/depcomp 0b26f101e3bc9fd1ff0be1da9fb4a82371142f92 x
F autoconf/install-sh 06ee6336e63bb845c8439d777c32eb2eccc4fbf1 x
F autoconf/ltmain.sh 7a658a24028f02331c1d2446562758083c5eadd1
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/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/license.terms 13bd403c9610fd2b76ece0ab50c4c5eda933d523
F autoconf/tea/pkgIndex.tcl.in 3ef61715cf1c7bdcff56947ffadb26bc991ca39d
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/nmakehlp.c 2070e086f39866b353a482d3a14dedaf26196506
F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
F config.h.in 0921066a13130082764ab4ab6456f7b5bebe56de
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
F configure 513f1e2464c3673bcdb5471b13d98e7eeb6f5ca2 x
F configure ad59a5f48b3c59a92b5506040a22fbe3f733a9d8 x
F configure.ac 4cf9f60785143fa141b10962ccc885d973792e9a
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1
@ -138,6 +138,7 @@ F ext/rtree/rtreeB.test c85f9ce78766c4e68b8b89fbf2979ee9cfa82b4e
F ext/rtree/rtreeC.test df158dcc81f1a43ce7eef361af03c48ec91f1e06
F ext/rtree/rtreeD.test 636630357638f5983701550b37f0f5867130d2ca
F ext/rtree/rtreeE.test 388c1c8602c3ce55c15f03b509e9cf545fb7c41f
F ext/rtree/rtreeF.test 66deb9fd1611c7ca2e374adba63debdc2dbb12b4
F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195
F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea
F ext/rtree/sqlite3rtree.h 83349d519fe5f518b3ea025d18dd1fe51b1684bd
@ -183,7 +184,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c fa057e30794bfd867963b44a3a42710a45c335a1
F src/btree.c 4195fed5741b4dbcc9831b623aec487258f3e62d
F src/btree.h 4245a349bfe09611d7ff887dbc3a80cee8b7955a
F src/btreeInt.h cf180d86b2e9e418f638d65baa425c4c69c0e0e3
F src/build.c 5abf794fe8a605f2005b422e98a3cedad9b9ef5b
@ -191,7 +192,7 @@ F src/callback.c fcff28cf0df2403dd2f313bb8d1b8f31f6f3cd64
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c 0231df905e2c4abba4483ee18ffc05adc321df2a
F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
F src/delete.c 50b74c1dde25d1ebcb4fa5c870762e6470ee46f1
F src/delete.c cb7a757eb829ebb046c66f6399435c6636fe1314
F src/expr.c f749009cf4a8534efb5e0d5cd7c9fb1fb0f2836c
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 8545f3b36da47473e10800ea4fb0810fd4062514
@ -200,7 +201,7 @@ F src/global.c 1e4bd956dc2f608f87d2a929abc4a20db65f30e4
F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c b1f57e168d39fed8a0d3d891bf38091b104dd707
F src/insert.c 3d41db1398a5863c4a1c064d2082d0dc43274628
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
F src/legacy.c febc2a9e7ad6c1a6191c7b5b9170b325d263f343
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
@ -239,7 +240,7 @@ F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
F src/resolve.c 0ea356d32a5e884add23d1b9b4e8736681dd5697
F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be
F src/select.c ea48e891406ccdf748f3eb02893e056d134a0fea
F src/shell.c 220564b70a2115e2157688f8faa6bb751ffe019a
F src/shell.c 34be9dc9e7b96081488acebecae6cd92632397a6
F src/sqlite.h.in 021a1f5c50e83060675d994a6014fd409e611d9e
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
@ -247,7 +248,7 @@ F src/sqliteInt.h d60dbbadfd64374a5a2f362fc6f45899540c2c8e
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c 7ada527ce7916adcabad7997c10f09680aac7c9b
F src/tclsqlite.c 30d8f4ba516061832cfe10d7c71d84e17bff1918
F src/test1.c 14409a611e9c27c6c522c610bbff5561f05c1558
F src/test2.c 98049e51a17dc62606a99a9eb95ee477f9996712
F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c
@ -268,8 +269,8 @@ F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f
F src/test_func.c d3013ce36f19ac72a99c73864930fd1fa41832f8
F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32
F src/test_intarray.c 87847c71c3c36889c0bcc9c4baf9d31881665d61
F src/test_intarray.h 2ece66438cfd177b78d1bfda7a4180cd3a10844d
F src/test_intarray.c db4614c2262a06abc4409dc048d59c580c38320f
F src/test_intarray.h 9dc57417fb65bc7835cc18548852cc08cc062202
F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64
F src/test_loadext.c a5251f956ab6af21e138dc1f9c0399394a510cb4
F src/test_malloc.c 1ff5b1243d96124c9a180f3b89424820a1f337f3
@ -302,7 +303,7 @@ F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
F src/vdbe.c ff9bec31cc128e98d852ebee6e5d4e160846e0c5
F src/vdbe.h ca3b6df299adce6e2f499c57e42ae54f142ae823
F src/vdbeInt.h 5eee1752eff410de9373196e2b327f7deefb3920
F src/vdbeapi.c 52335de5ff97bba93d6779d8df87feab5d53d7df
F src/vdbeapi.c 11d97cd50ca78f6c6ce796d0c78913ef27f5383d
F src/vdbeaux.c 22aabbdea2394cea26e35b2190fa9111e4bc18c2
F src/vdbeblob.c d7c232d1c6afc7ee1176c38b7d81b2e17af15ceb
F src/vdbemem.c d90a1e8acf8b63dc9d14cbbea12bfec6cec31394
@ -312,7 +313,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
F src/wal.c 264df50a1b33124130b23180ded2e2c5663c652a
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45
F src/where.c ab20f9c24a422ee8900831b343c3d1e5e7aca87b
F src/where.c 4c499d185827a492643cf017ae5e3aa0523f9f18
F src/whereInt.h 923820bee9726033a501a08d2fc69b9c1ee4feb3
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@ -718,7 +719,7 @@ F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
F test/memdb.test fcb5297b321b562084fc79d64d5a12a1cd2b639b
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
F test/memsubsys1.test f97cfd0b30e85c2f1ed16d642e7ac58006be84b2
F test/memsubsys1.test bf270964ab83bc2da5927960f78304a866fb9a9d
F test/memsubsys2.test 3a1c1a9de48e5726faa85108b02459fae8cb9ee9
F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd
F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc
@ -849,6 +850,7 @@ F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
F test/skipscan1.test 28c7faa41a0d7265040ecb0a0abd90c0904270b2
F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a
F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5
F test/skipscan5.test d8b9692b702745a0e41c23f9da6beac81df01196
F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f
F test/softheap1.test 40562fe6cac6d9827b7b42b86d45aedf12c15e24
@ -1034,7 +1036,7 @@ F test/tkt3997.test a335fa41ca3985660a139df7b734a26ef53284bd
F test/tkt4018.test 7c2c9ba4df489c676a0a7a0e809a1fb9b2185bd1
F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7
F test/tpch01.test 04adbf8d8300fa60a222f28d901abd76e7be6dd4
F test/trace.test 4b36a41a3e9c7842151af6da5998f5080cdad9e5
F test/trace.test 73a5508100f7fccfbc3f8018d5f6963ed478eea0
F test/trace2.test 93b47ca6996c66b47f57224cfb146f34e07df382
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76
@ -1165,7 +1167,7 @@ F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
F tool/lemon.c 3ff0fec22f92dfb54e62eeb48772eddffdbeb0d6
F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc
F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6
F tool/mkautoconfamal.sh f8d8dbf7d62f409ebed5134998bf5b51d7266383
F tool/mkautoconfamal.sh 5dc5010e2e748a9e1bba67baca5956a2c2deda7b
F tool/mkkeywordhash.c dfff09dbbfaf950e89af294f48f902181b144670
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
F tool/mkpragmatab.tcl 78a77b2c554d534c6f2dc903130186ed15715460
@ -1181,7 +1183,7 @@ F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b
F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5
F tool/showdb.c b9ee6b6c81a094bf33badbf7e9da34cdbc0cce25
F tool/showdb.c bd073a78bce714a0e42d92ea474b3eb8cb53be5d
F tool/showjournal.c 053eb1cc774710c6890b7dd6293300cc297b16a5
F tool/showstat4.c c39279d6bd37cb999b634f0064f6f86ad7af008f
F tool/showwal.c 3209120269cdf9380f091459e47b776b4f81dfd3
@ -1203,7 +1205,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P b69f7dd1f35846c3bb9f4f160d50c4f03796f887
R 8c550f2382b76c35956caff857ef2faa
P 6d5b9332e8d8bb572ac98b0f4e47e59ad12aac26 7029b3404d3f5f698a496934f3a3f2972051b257
R a953db417f3d0f990497f5e1512b276c
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){
const int hdr = pPage->hdrOffset; /* Local cache of pPage->hdrOffset */
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 gap; /* First byte of gap between cell pointers and cell content */
int rc; /* Integer return code */
@ -1212,25 +1211,26 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
usableSize = pPage->pBt->usableSize;
assert( nByte < usableSize-8 );
nFrag = data[hdr+7];
assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf );
gap = pPage->cellOffset + 2*pPage->nCell;
top = get2byteNotZero(&data[hdr+5]);
if( gap>top ) return SQLITE_CORRUPT_BKPT;
assert( gap<=65536 );
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+1==top );
testcase( gap==top );
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.
*/
if( gap+2<=top && (data[hdr+1] || data[hdr+2]) ){
int pc, addr;
for(addr=hdr+1; (pc = get2byte(&data[addr]))>0; addr=pc){
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==3 );
if( x<4 ){
if( data[hdr+7]>=60 ) goto defragment_page;
/* Remove the slot from the free-list. Update the number of
** fragmented bytes within the page. */
memcpy(&data[addr], &data[pc], 2);
data[hdr+7] = (u8)(nFrag + x);
data[hdr+7] += (u8)x;
}else if( size+pc > usableSize ){
return SQLITE_CORRUPT_BKPT;
}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 allocation. If not, defragment.
/* The request could not be fulfilled using a freelist slot. Check
** to see if defragmentation is necessary.
*/
testcase( gap+2+nByte==top );
if( gap+2+nByte>top ){
defragment_page:
testcase( pPage->nCell==0 );
rc = defragmentPage(pPage);
if( rc ) return rc;
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.
** The first byte of the new free block is pPage->aDisk[start]
** and the size of the block is "size" bytes.
** The first byte of the new free block is pPage->aData[iStart]
** and the size of the block is iSize bytes.
**
** Most of the effort here is involved in coalesing adjacent
** free blocks into a single big free block.
** Adjacent freeblocks are coalesced.
**
** 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){
int addr, pbegin, hdr;
int iLast; /* Largest possible freeblock offset */
unsigned char *data = pPage->aData;
static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
u16 iPtr; /* Address of pointer to next freeblock */
u16 iFreeBlk; /* Address of the next freeblock */
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( sqlite3PagerIswriteable(pPage->pDbPage) );
assert( start>=pPage->hdrOffset+6+pPage->childPtrSize );
assert( (start + size) <= (int)pPage->pBt->usableSize );
assert( iStart>=pPage->hdrOffset+6+pPage->childPtrSize );
assert( iEnd <= pPage->pBt->usableSize );
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 ){
/* Overwrite deleted information with zeros when the secure_delete
** option is enabled */
memset(&data[start], 0, size);
memset(&data[iStart], 0, iSize);
}
/* Add the space back into the linked list of freeblocks. Note that
** even though the freeblock list was checked by btreeInitPage(),
** 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.
/* The list of freeblocks must be in ascending order. Find the
** spot on the list where iStart should be inserted.
*/
hdr = pPage->hdrOffset;
addr = hdr + 1;
iLast = pPage->pBt->usableSize - 4;
assert( start<=iLast );
while( (pbegin = get2byte(&data[addr]))<start && pbegin>0 ){
if( pbegin<addr+4 ){
return SQLITE_CORRUPT_BKPT;
iPtr = hdr + 1;
if( data[iPtr+1]==0 && data[iPtr]==0 ){
iFreeBlk = 0; /* Shortcut for the case when the freelist is empty */
}else{
while( (iFreeBlk = get2byte(&data[iPtr]))>0 && iFreeBlk<iStart ){
if( iFreeBlk<iPtr+4 ) return SQLITE_CORRUPT_BKPT;
iPtr = iFreeBlk;
}
addr = pbegin;
}
if( pbegin>iLast ){
return SQLITE_CORRUPT_BKPT;
}
assert( pbegin>addr || pbegin==0 );
put2byte(&data[addr], start);
put2byte(&data[start], pbegin);
put2byte(&data[start+2], size);
pPage->nFree = pPage->nFree + (u16)size;
if( iFreeBlk>iLast ) return SQLITE_CORRUPT_BKPT;
assert( iFreeBlk>iPtr || iFreeBlk==0 );
/* Coalesce adjacent free blocks */
addr = hdr + 1;
while( (pbegin = get2byte(&data[addr]))>0 ){
int pnext, psize, x;
assert( pbegin>addr );
assert( pbegin <= (int)pPage->pBt->usableSize-4 );
pnext = get2byte(&data[pbegin]);
psize = get2byte(&data[pbegin+2]);
if( pbegin + psize + 3 >= pnext && pnext>0 ){
int frag = pnext - (pbegin+psize);
if( (frag<0) || (frag>(int)data[hdr+7]) ){
return SQLITE_CORRUPT_BKPT;
/* At this point:
** iFreeBlk: First freeblock after iStart, or zero if none
** iPtr: The address of a pointer iFreeBlk
**
** Check to see if iFreeBlk should be coalesced onto the end of iStart.
*/
if( iFreeBlk && iEnd+3>=iFreeBlk ){
nFrag = iFreeBlk - iEnd;
if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_BKPT;
iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]);
iSize = iEnd - iStart;
iFreeBlk = get2byte(&data[iFreeBlk]);
}
/* If iPtr is another freeblock (that is, if iPtr is not the freelist pointer
** in the page header) then check to see if iStart should be coalesced
** onto the end of iPtr.
*/
if( iPtr>hdr+1 ){
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 the cell content area begins with a freeblock, remove it. */
if( data[hdr+1]==data[hdr+5] && data[hdr+2]==data[hdr+6] ){
int top;
pbegin = get2byte(&data[hdr+1]);
memcpy(&data[hdr+1], &data[pbegin], 2);
top = get2byte(&data[hdr+5]) + get2byte(&data[pbegin+2]);
put2byte(&data[hdr+5], top);
if( iStart==get2byte(&data[hdr+5]) ){
/* The new freeblock is at the beginning of the cell content area,
** so just extend the cell content area rather than create another
** freelist entry */
if( iPtr!=hdr+1 ) return SQLITE_CORRUPT_BKPT;
put2byte(&data[hdr+1], iFreeBlk);
put2byte(&data[hdr+5], iEnd);
}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;
}

View File

@ -473,10 +473,11 @@ void sqlite3DeleteFrom(
** triggers.
*/
if( !isView ){
testcase( IsVirtual(pTab) );
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iTabCur, aToOpen,
&iDataCur, &iIdxCur);
assert( pPk || iDataCur==iTabCur );
assert( pPk || iIdxCur==iDataCur+1 );
assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur );
assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 );
}
/* Set up a loop over the rowids/primary-keys that were found in the
@ -484,7 +485,8 @@ void sqlite3DeleteFrom(
*/
if( okOnePass ){
/* 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] ){
assert( pPk!=0 );
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
** of *piIdxCurs, depending on where the PRIMARY KEY index appears on the
** 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(
Parse *pParse, /* Parsing context */
@ -1642,9 +1645,9 @@ int sqlite3OpenTableAndIndices(
assert( op==OP_OpenRead || op==OP_OpenWrite );
if( IsVirtual(pTab) ){
assert( aToOpen==0 );
*piDataCur = 0;
*piIdxCur = 1;
/* This routine is a no-op for virtual tables. Leave the output
** variables *piDataCur and *piIdxCur uninitialized so that valgrind
** can detect if they are used by mistake in the caller. */
return 0;
}
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){
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"
" FROM sqlite_master UNION ALL"
" 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",
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"
" FROM sqlite_master UNION ALL"
" 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",
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 ){
rc = createIncrblobChannel(
interp, pDb, zDb, zTable, zColumn, iRow, isReadonly
interp, pDb, zDb, zTable, zColumn, (sqlite3_int64)iRow, isReadonly
);
}
#endif

View File

@ -216,7 +216,7 @@ static sqlite3_module intarrayModule = {
** explicitly by the application, the virtual table will be dropped implicitly
** by the system when the database connection is closed.
*/
int sqlite3_intarray_create(
SQLITE_API int sqlite3_intarray_create(
sqlite3 *db,
const char *zName,
sqlite3_intarray **ppReturn
@ -250,7 +250,7 @@ int sqlite3_intarray_create(
** any query against the corresponding virtual table. If the integer
** 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 */
int nElements, /* Number of elements in 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
** by the system when the database connection is closed.
*/
int sqlite3_intarray_create(
SQLITE_API int sqlite3_intarray_create(
sqlite3 *db,
const char *zName,
sqlite3_intarray **ppReturn
@ -115,7 +115,7 @@ int sqlite3_intarray_create(
** any query against the corresponding virtual table. If the integer
** 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 */
int nElements, /* Number of elements in 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);
v->doingRerun = 0;
while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
&& cnt++ < SQLITE_MAX_SCHEMA_RETRY
&& (rc2 = rc = sqlite3Reprepare(v))==SQLITE_OK ){
&& cnt++ < SQLITE_MAX_SCHEMA_RETRY ){
int savedPc = v->pc;
rc2 = rc = sqlite3Reprepare(v);
if( rc!=SQLITE_OK) break;
sqlite3_reset(pStmt);
v->doingRerun = 1;
if( savedPc>=0 ) v->doingRerun = 1;
assert( v->expired==0 );
}
if( rc2!=SQLITE_OK ){

View File

@ -3781,8 +3781,8 @@ static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){
sqlite3DebugPrintf(" %12s",
pItem->zAlias ? pItem->zAlias : pTab->zName);
if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
const char *zName;
if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){
const char *zName;
if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){
if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){
int i = sqlite3Strlen30(zName) - 1;
while( zName[i]!='_' ) i--;
@ -3803,7 +3803,11 @@ static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){
sqlite3DebugPrintf(" %-19s", 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);
#ifdef SQLITE_ENABLE_TREE_EXPLAIN
/* 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
** more expensive. */
assert( 42==sqlite3LogEst(18) );
if( pTerm==0
&& saved_nEq==saved_nSkip
if( saved_nEq==saved_nSkip
&& saved_nEq+1<pProbe->nKeyCol
&& pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */
&& (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK
@ -4328,9 +4331,17 @@ static int whereLoopAddBtreeIndex(
pNew->aLTerm[pNew->nLTerm++] = 0;
pNew->wsFlags |= WHERE_SKIPSCAN;
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;
whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter + nInMul);
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)){
u16 eOp = pTerm->eOperator; /* Shorthand for pTerm->eOperator */

View File

@ -124,7 +124,13 @@ do_test memsubsys1-3.1.3 {
} 0
do_test memsubsys1-3.1.4 {
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 {
set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
} 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
} {}
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
# happens on each execution.

View File

@ -62,7 +62,7 @@ mkdir -p tea/generic
echo "#ifdef USE_SYSTEM_SQLITE" > tea/generic/tclsqlite3.c
echo "# include <sqlite3.h>" >> 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
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"
" NNNt Decode freelist trunk page NNN\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"
);
}