Compare commits

..

1 Commits

Author SHA1 Message Date
drh 426504965c Add a new OP_BColumn opcode where the cursor is guaranteed to be of type
CURTYPE_BTREE and is thus able to skip some checks and run slightly faster.

FossilOrigin-Name: 093e0d10a81adc078dcb3e08e33ce89bdbe53789
2015-11-21 17:53:06 +00:00
111 changed files with 15541 additions and 3957 deletions
+1 -2
View File
@@ -402,7 +402,6 @@ TESTSRC = \
$(TOP)/src/test_tclvar.c \
$(TOP)/src/test_thread.c \
$(TOP)/src/test_vfs.c \
$(TOP)/src/test_windirent.c \
$(TOP)/src/test_wsd.c \
$(TOP)/ext/fts3/fts3_term.c \
$(TOP)/ext/fts3/fts3_test.c \
@@ -1156,7 +1155,7 @@ THREADTEST3_SRC = $(TOP)/test/threadtest3.c \
$(TOP)/test/tt3_lookaside1.c
threadtest3$(TEXE): sqlite3.lo $(THREADTEST3_SRC)
$(LTLINK) $(TOP)/test/threadtest3.c $(TOP)/src/test_multiplex.c sqlite3.lo -o $@ $(TLIBS)
$(LTLINK) $(TOP)/test/threadtest3.c sqlite3.lo -o $@ $(TLIBS)
threadtest: threadtest3$(TEXE)
./threadtest3$(TEXE)
+1 -2
View File
@@ -50,7 +50,7 @@ API_ARMOR = 0
!IFNDEF NO_WARN
!IF $(USE_FULLWARN)!=0
NO_WARN = -wd4054 -wd4055 -wd4100 -wd4127 -wd4130 -wd4152 -wd4189 -wd4206
NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4305 -wd4306 -wd4702 -wd4706
NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4244 -wd4305 -wd4306 -wd4702 -wd4706
!ENDIF
!ENDIF
@@ -1071,7 +1071,6 @@ TESTSRC = \
$(TOP)\src\test_tclvar.c \
$(TOP)\src\test_thread.c \
$(TOP)\src\test_vfs.c \
$(TOP)\src\test_windirent.c \
$(TOP)\src\test_wsd.c \
$(TOP)\ext\fts3\fts3_term.c \
$(TOP)\ext\fts3\fts3_test.c \
Vendored Executable
+1530
View File
File diff suppressed because it is too large Load Diff
Vendored Executable
+1773
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -10,7 +10,7 @@
#
AC_PREREQ(2.61)
AC_INIT(sqlite, --SQLITE-VERSION--, http://www.sqlite.org)
AC_INIT(sqlite, 3.7.5, http://www.sqlite.org)
AC_CONFIG_SRCDIR([sqlite3.c])
# Use automake.
+708
View File
@@ -0,0 +1,708 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2012-03-27.16; # UTC
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010,
# 2011, 2012 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by 'PROGRAMS ARGS'.
object Object file output by 'PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputting dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
# A tabulation character.
tab=' '
# A newline character.
nl='
'
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
cygpath_u="cygpath -u -f -"
if test "$depmode" = msvcmsys; then
# This is just like msvisualcpp but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvisualcpp
fi
if test "$depmode" = msvc7msys; then
# This is just like msvc7 but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvc7
fi
if test "$depmode" = xlc; then
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency informations.
gccflag=-qmakedep=gcc,-MF
depmode=gcc
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
## the command line argument order; so add the flags where they
## appear in depend2.am. Note that the slowdown incurred here
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
for arg
do
case $arg in
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
*) set fnord "$@" "$arg" ;;
esac
shift # fnord
shift # $arg
done
"$@"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say).
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## The second -e expression handles DOS-style file names with drive letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the "deleted header file" problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
tr ' ' "$nl" < "$tmpdepfile" |
## Some versions of gcc put a space before the ':'. On the theory
## that the space means something, we add a space to the output as
## well. hp depmode also adds that space, but also prefixes the VPATH
## to the object. Take care to not repeat it in the output.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like '#:fec' to the end of the
# dependency line.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr "$nl" ' ' >> "$depfile"
echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
xlc)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts '$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
tmpdepfile3=$dir.libs/$base.u
"$@" -Wc,-M
else
tmpdepfile1=$dir$base.u
tmpdepfile2=$dir$base.u
tmpdepfile3=$dir$base.u
"$@" -M
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
# Each line is of the form 'foo.o: dependent.h'.
# Do two passes, one to just change these to
# '$object: dependent.h' and one to simply 'dependent.h:'.
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
icc)
# Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'.
# However on
# $CC -MD -MF foo.d -c -o sub/foo.o sub/foo.c
# ICC 7.0 will fill foo.d with something like
# foo.o: sub/foo.c
# foo.o: sub/foo.h
# which is wrong. We want
# sub/foo.o: sub/foo.c
# sub/foo.o: sub/foo.h
# sub/foo.c:
# sub/foo.h:
# ICC 7.1 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using '\':
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
# tcc 0.9.26 (FIXME still under development at the moment of writing)
# will emit a similar output, but also prepend the continuation lines
# with horizontal tabulation characters.
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form 'foo.o: dependent.h',
# or 'foo.o: dep1.h dep2.h \', or ' dep3.h dep4.h \'.
# Do two passes, one to just change these to
# '$object: dependent.h' and one to simply 'dependent.h:'.
sed -e "s/^[ $tab][ $tab]*/ /" -e "s,^[^:]*:,$object :," \
< "$tmpdepfile" > "$depfile"
sed '
s/[ '"$tab"'][ '"$tab"']*/ /g
s/^ *//
s/ *\\*$//
s/^[^:]*: *//
/^$/d
/:$/d
s/$/ :/
' < "$tmpdepfile" >> "$depfile"
rm -f "$tmpdepfile"
;;
hp2)
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
# compilers, which have integrated preprocessors. The correct option
# to use with these is +Maked; it writes dependencies to a file named
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
"$@" -Wc,+Maked
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
"$@" +Maked
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
# Add 'dependent.h:' lines.
sed -ne '2,${
s/^ *//
s/ \\*$//
s/$/:/
p
}' "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in 'foo.d' instead, so we check for that too.
# Subdirectories are respected.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
# With Tru64 cc, shared objects can also be used to make a
# static library. This mechanism is used in libtool 1.4 series to
# handle both shared and static libraries in a single compilation.
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
#
# With libtool 1.5 this exception was removed, and libtool now
# generates 2 separate objects for the 2 libraries. These two
# compilations output dependencies in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
tmpdepfile2=$dir$base.o.d # libtool 1.5
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.o.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
tmpdepfile4=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
msvc7)
if test "$libtool" = yes; then
showIncludes=-Wc,-showIncludes
else
showIncludes=-showIncludes
fi
"$@" $showIncludes > "$tmpdepfile"
stat=$?
grep -v '^Note: including file: ' "$tmpdepfile"
if test "$stat" = 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The first sed program below extracts the file names and escapes
# backslashes for cygpath. The second sed program outputs the file
# name when reading, but also accumulates all include files in the
# hold buffer in order to output them again at the end. This only
# works with sed implementations that can handle large buffers.
sed < "$tmpdepfile" -n '
/^Note: including file: *\(.*\)/ {
s//\1/
s/\\/\\\\/g
p
}' | $cygpath_u | sort -u | sed -n '
s/ /\\ /g
s/\(.*\)/'"$tab"'\1 \\/p
s/.\(.*\) \\/\1:/
H
$ {
s/.*/'"$tab"'/
G
p
}' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvc7msys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for ':'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
"$@" $dashmflag |
sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' "$nl" < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no eat=no
for arg
do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
if test $eat = yes; then
eat=no
continue
fi
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-arch)
eat=yes ;;
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix=`echo "$object" | sed 's/^.*\././'`
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
# makedepend may prepend the VPATH from the source file name to the object.
# No need to regex-escape $object, excess matching of '.' is harmless.
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E |
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
IFS=" "
for arg
do
case "$arg" in
-o)
shift
;;
$object)
shift
;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E 2>/dev/null |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
echo "$tab" >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvcmsys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
+527
View File
@@ -0,0 +1,527 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2011-01-19.21; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
nl='
'
IFS=" "" $nl"
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
if test -z "$doit"; then
doit_exec=exec
else
doit_exec=$doit
fi
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_glob='?'
initialize_posix_glob='
test "$posix_glob" != "?" || {
if (set -f) 2>/dev/null; then
posix_glob=
else
posix_glob=:
fi
}
'
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
no_target_directory=
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *' '* | *'
'* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-t) dst_arg=$2
# Protect names problematic for `test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) no_target_directory=true;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for `test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call `install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for `test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
# Prefer dirname, but fall back on a substitute if dirname fails.
dstdir=`
(dirname "$dst") 2>/dev/null ||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$dst" : 'X\(//\)[^/]' \| \
X"$dst" : 'X\(//\)$' \| \
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
echo X"$dst" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'
`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writeable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
eval "$initialize_posix_glob"
oIFS=$IFS
IFS=/
$posix_glob set -f
set fnord $dstdir
shift
$posix_glob set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
eval "$initialize_posix_glob" &&
$posix_glob set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
$posix_glob set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
+9655
View File
File diff suppressed because it is too large Load Diff
+331
View File
@@ -0,0 +1,331 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
scriptversion=2012-01-06.13; # UTC
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi
msg="missing on your system"
case $1 in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
# Exit code 63 means version mismatch. This often happens
# when the user try to use an ancient version of a tool on
# a file that requires a minimum version. In this case we
# we should proceed has if the program had been absent, or
# if --run hadn't been passed.
if test $? = 63; then
run=:
msg="probably too old"
fi
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
autom4te touch the output file, or create a stub one
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
\`g' are ignored when checking the name.
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
esac
# normalize program name to check for.
program=`echo "$1" | sed '
s/^gnu-//; t
s/^gnu//; t
s/^g//; t'`
# Now exit if we have it, but it failed. Also exit now if we
# don't have it and --version was passed (most likely to detect
# the program). This is about non-GNU programs, so use $1 not
# $program.
case $1 in
lex*|yacc*)
# Not GNU programs, they don't have --version.
;;
*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
# Could not run --version or --help. This is probably someone
# running `$TOOL --version' or `$TOOL --help' to check whether
# $TOOL exists and not knowing $TOOL uses missing.
exit 1
fi
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case $program in
aclocal*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case $f in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
autom4te*)
echo 1>&2 "\
WARNING: \`$1' is needed, but is $msg.
You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;
bison*|yacc*)
echo 1>&2 "\
WARNING: \`$1' $msg. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if test $# -ne 1; then
eval LASTARG=\${$#}
case $LASTARG in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if test ! -f y.tab.h; then
echo >y.tab.h
fi
if test ! -f y.tab.c; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex*|flex*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if test $# -ne 1; then
eval LASTARG=\${$#}
case $LASTARG in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if test ! -f lex.yy.c; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
help2man*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit $?
fi
;;
makeinfo*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
# The file to touch is that specified with -o ...
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -z "$file"; then
# ... or it is the one specified with @setfilename ...
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '
/^@setfilename/{
s/.* \([^ ]*\) *$/\1/
p
q
}' $infile`
# ... or it is derived from the source name (dir/f.texi becomes f.info)
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
fi
# If the file does not exist, the user really needs makeinfo;
# let's fail without touching anything.
test -f $file || exit 1
touch $file
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and is $msg.
You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
+1 -1
View File
@@ -398,7 +398,7 @@ static void showSegmentStats(sqlite3 *db, const char *zTab){
if( sqlite3_step(pStmt)==SQLITE_ROW
&& (nLeaf = sqlite3_column_int(pStmt, 0))>0
){
nIdx = sqlite3_column_int(pStmt, 5);
int nIdx = sqlite3_column_int(pStmt, 5);
sqlite3_int64 sz;
printf("For level %d:\n", i);
printf(" Number of indexes...................... %9d\n", nIdx);
+1 -1
View File
@@ -544,7 +544,7 @@ int sqlite3Fts5AuxInit(fts5_api *pApi){
int rc = SQLITE_OK; /* Return code */
int i; /* To iterate through builtin functions */
for(i=0; rc==SQLITE_OK && i<(int)ArraySize(aBuiltin); i++){
for(i=0; rc==SQLITE_OK && i<sizeof(aBuiltin)/sizeof(aBuiltin[0]); i++){
rc = pApi->xCreateFunction(pApi,
aBuiltin[i].zFunc,
aBuiltin[i].pUserData,
+14 -33
View File
@@ -216,53 +216,34 @@ static int fts5ConfigParseSpecial(
if( sqlite3_strnicmp("prefix", zCmd, nCmd)==0 ){
const int nByte = sizeof(int) * FTS5_MAX_PREFIX_INDEXES;
const char *p;
int bFirst = 1;
if( pConfig->aPrefix==0 ){
if( pConfig->aPrefix ){
*pzErr = sqlite3_mprintf("multiple prefix=... directives");
rc = SQLITE_ERROR;
}else{
pConfig->aPrefix = sqlite3Fts5MallocZero(&rc, nByte);
if( rc ) return rc;
}
p = zArg;
while( 1 ){
while( rc==SQLITE_OK && p[0] ){
int nPre = 0;
while( p[0]==' ' ) p++;
if( bFirst==0 && p[0]==',' ){
p++;
while( p[0]==' ' ) p++;
}else if( p[0]=='\0' ){
break;
}
if( p[0]<'0' || p[0]>'9' ){
*pzErr = sqlite3_mprintf("malformed prefix=... directive");
rc = SQLITE_ERROR;
break;
}
if( pConfig->nPrefix==FTS5_MAX_PREFIX_INDEXES ){
*pzErr = sqlite3_mprintf(
"too many prefix indexes (max %d)", FTS5_MAX_PREFIX_INDEXES
);
rc = SQLITE_ERROR;
break;
}
while( p[0]>='0' && p[0]<='9' && nPre<1000 ){
nPre = nPre*10 + (p[0] - '0');
p++;
}
if( rc==SQLITE_OK && (nPre<=0 || nPre>=1000) ){
*pzErr = sqlite3_mprintf("prefix length out of range (max 999)");
while( p[0]==' ' ) p++;
if( p[0]==',' ){
p++;
}else if( p[0] ){
*pzErr = sqlite3_mprintf("malformed prefix=... directive");
rc = SQLITE_ERROR;
}
if( rc==SQLITE_OK && (nPre==0 || nPre>=1000) ){
*pzErr = sqlite3_mprintf("prefix length out of range: %d", nPre);
rc = SQLITE_ERROR;
break;
}
pConfig->aPrefix[pConfig->nPrefix] = nPre;
pConfig->nPrefix++;
bFirst = 0;
}
assert( pConfig->nPrefix<=FTS5_MAX_PREFIX_INDEXES );
return rc;
}
+4 -4
View File
@@ -407,7 +407,7 @@ static int fts5ExprPhraseIsMatch(
/* If the aStatic[] array is not large enough, allocate a large array
** using sqlite3_malloc(). This approach could be improved upon. */
if( pPhrase->nTerm>(int)ArraySize(aStatic) ){
if( pPhrase->nTerm>(sizeof(aStatic) / sizeof(aStatic[0])) ){
int nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm;
aIter = (Fts5PoslistReader*)sqlite3_malloc(nByte);
if( !aIter ) return SQLITE_NOMEM;
@@ -430,7 +430,7 @@ static int fts5ExprPhraseIsMatch(
}
if( rc!=SQLITE_OK ) goto ismatch_out;
sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
aIter[i].bFlag = (u8)bFlag;
aIter[i].bFlag = bFlag;
if( aIter[i].bEof ) goto ismatch_out;
}
@@ -543,7 +543,7 @@ static int fts5ExprNearIsMatch(int *pRc, Fts5ExprNearset *pNear){
/* If the aStatic[] array is not large enough, allocate a large array
** using sqlite3_malloc(). This approach could be improved upon. */
if( pNear->nPhrase>(int)ArraySize(aStatic) ){
if( pNear->nPhrase>(sizeof(aStatic) / sizeof(aStatic[0])) ){
int nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase;
a = (Fts5NearTrimmer*)sqlite3Fts5MallocZero(&rc, nByte);
}else{
@@ -2190,7 +2190,7 @@ int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){
int rc = SQLITE_OK;
void *pCtx = (void*)pGlobal;
for(i=0; rc==SQLITE_OK && i<(int)ArraySize(aFunc); i++){
for(i=0; rc==SQLITE_OK && i<(sizeof(aFunc) / sizeof(aFunc[0])); i++){
struct Fts5ExprFunc *p = &aFunc[i];
rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0);
}
+1 -1
View File
@@ -190,7 +190,7 @@ static void fts5HashAddPoslistSize(Fts5HashEntry *p){
assert( p->bDel==0 || p->bDel==1 );
if( nPos<=127 ){
pPtr[p->iSzPoslist] = (u8)nPos;
pPtr[p->iSzPoslist] = nPos;
}else{
int nByte = sqlite3Fts5GetVarintLen((u32)nPos);
memmove(&pPtr[p->iSzPoslist + nByte], &pPtr[p->iSzPoslist + 1], nSz);
+9 -10
View File
@@ -2393,7 +2393,7 @@ static int fts5MultiIterDoCompare(Fts5IndexIter *pIter, int iOut){
}
}
pRes->iFirst = (u16)iRes;
pRes->iFirst = iRes;
return 0;
}
@@ -2560,7 +2560,7 @@ static int fts5MultiIterAdvanceRowid(
pIter->iSwitchRowid = pOther->iRowid;
}
}
pRes->iFirst = (u16)(pNew - pIter->aSeg);
pRes->iFirst = (pNew - pIter->aSeg);
if( i==1 ) break;
pOther = &pIter->aSeg[ pIter->aFirst[i ^ 0x0001].iFirst ];
@@ -2711,7 +2711,7 @@ static void fts5MultiIterNew(
*ppOut = pNew = fts5MultiIterAlloc(p, nSeg);
if( pNew==0 ) return;
pNew->bRev = (0!=(flags & FTS5INDEX_QUERY_DESC));
pNew->bSkipEmpty = (u8)bSkipEmpty;
pNew->bSkipEmpty = bSkipEmpty;
pNew->pStruct = pStruct;
fts5StructureRef(pStruct);
@@ -3174,7 +3174,7 @@ static void fts5WriteFlushLeaf(Fts5Index *p, Fts5SegWriter *pWriter){
/* Set the szLeaf header field. */
assert( 0==fts5GetU16(&pPage->buf.p[2]) );
fts5PutU16(&pPage->buf.p[2], (u16)pPage->buf.n);
fts5PutU16(&pPage->buf.p[2], pPage->buf.n);
if( pWriter->bFirstTermInPage ){
/* No term was written to this page. */
@@ -3306,7 +3306,7 @@ static void fts5WriteAppendRowid(
** rowid-pointer in the page-header. Also append a value to the dlidx
** buffer, in case a doclist-index is required. */
if( pWriter->bFirstRowidInPage ){
fts5PutU16(pPage->buf.p, (u16)pPage->buf.n);
fts5PutU16(pPage->buf.p, pPage->buf.n);
fts5WriteDlidxAppend(p, pWriter, iRowid);
}
@@ -3464,7 +3464,7 @@ static void fts5TrimSegments(Fts5Index *p, Fts5IndexIter *pIter){
fts5BufferAppendBlob(&p->rc, &buf, pData->szLeaf-iOff, &pData->p[iOff]);
if( p->rc==SQLITE_OK ){
/* Set the szLeaf field */
fts5PutU16(&buf.p[2], (u16)buf.n);
fts5PutU16(&buf.p[2], buf.n);
}
/* Set up the new page-index array */
@@ -3830,7 +3830,7 @@ static void fts5FlushOneHash(Fts5Index *p){
iRowid += iDelta;
if( writer.bFirstRowidInPage ){
fts5PutU16(&pBuf->p[0], (u16)pBuf->n); /* first rowid on page */
fts5PutU16(&pBuf->p[0], pBuf->n); /* first rowid on page */
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid);
writer.bFirstRowidInPage = 0;
fts5WriteDlidxAppend(p, &writer, iRowid);
@@ -4627,8 +4627,7 @@ int sqlite3Fts5IndexWrite(
int nByte = fts5IndexCharlenToBytelen(pToken, nToken, pConfig->aPrefix[i]);
if( nByte ){
rc = sqlite3Fts5HashWrite(p->pHash,
p->iWriteRowid, iCol, iPos, (char)(FTS5_MAIN_PREFIX+i+1), pToken,
nByte
p->iWriteRowid, iCol, iPos, FTS5_MAIN_PREFIX+i+1, pToken, nByte
);
}
}
@@ -4678,7 +4677,7 @@ int sqlite3Fts5IndexQuery(
if( iIdx<=pConfig->nPrefix ){
Fts5Structure *pStruct = fts5StructureRead(p);
buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx);
buf.p[0] = FTS5_MAIN_PREFIX + iIdx;
if( pStruct ){
fts5MultiIterNew(p, pStruct, 1, flags, buf.p, nToken+1, -1, 0, &pRet);
fts5StructureRelease(pStruct);
+3 -3
View File
@@ -537,7 +537,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
for(i=0; i<pInfo->nConstraint; i++){
struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
int j;
for(j=0; j<(int)ArraySize(aConstraint); j++){
for(j=0; j<sizeof(aConstraint)/sizeof(aConstraint[0]); j++){
struct Constraint *pC = &aConstraint[j];
if( p->iColumn==aColMap[pC->iCol] && p->op & pC->op ){
if( p->usable ){
@@ -584,11 +584,11 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
/* Assign argvIndex values to each constraint in use. */
iNext = 1;
for(i=0; i<(int)ArraySize(aConstraint); i++){
for(i=0; i<sizeof(aConstraint)/sizeof(aConstraint[0]); i++){
struct Constraint *pC = &aConstraint[i];
if( pC->iConsIndex>=0 ){
pInfo->aConstraintUsage[pC->iConsIndex].argvIndex = iNext++;
pInfo->aConstraintUsage[pC->iConsIndex].omit = (unsigned char)pC->omit;
pInfo->aConstraintUsage[pC->iConsIndex].omit = pC->omit;
}
}
+1 -1
View File
@@ -338,7 +338,7 @@ int sqlite3Fts5StorageClose(Fts5Storage *p){
int i;
/* Finalize all SQL statements */
for(i=0; i<(int)ArraySize(p->aStmt); i++){
for(i=0; i<ArraySize(p->aStmt); i++){
sqlite3_finalize(p->aStmt[i]);
}
+2 -2
View File
@@ -256,7 +256,7 @@ static int fts5UnicodeAddExceptions(
int bToken;
READ_UTF8(zCsr, zTerm, iCode);
if( iCode<128 ){
p->aTokenChar[iCode] = (unsigned char)bTokenChars;
p->aTokenChar[iCode] = bTokenChars;
}else{
bToken = sqlite3Fts5UnicodeIsalnum(iCode);
assert( (bToken==0 || bToken==1) );
@@ -1220,7 +1220,7 @@ int sqlite3Fts5TokenizerInit(fts5_api *pApi){
int rc = SQLITE_OK; /* Return code */
int i; /* To iterate through builtin functions */
for(i=0; rc==SQLITE_OK && i<(int)ArraySize(aBuiltin); i++){
for(i=0; rc==SQLITE_OK && i<sizeof(aBuiltin)/sizeof(aBuiltin[0]); i++){
rc = pApi->xCreateTokenizer(pApi,
aBuiltin[i].zName,
(void*)pApi,
+6 -16
View File
@@ -42,8 +42,6 @@ foreach {tn opt} {
1 {prefix=x}
2 {prefix='x'}
3 {prefix='$'}
4 {prefix='1,2,'}
5 {prefix=',1'}
} {
set res [list 1 {malformed prefix=... directive}]
do_catchsql_test 2.$tn "CREATE VIRTUAL TABLE f1 USING fts5(x, $opt)" $res
@@ -120,15 +118,18 @@ do_catchsql_test 5.3 {
#-------------------------------------------------------------------------
# Errors in prefix= directives.
#
do_catchsql_test 6.1 {
CREATE VIRTUAL TABLE abc USING fts5(a, prefix=1, prefix=2);
} {1 {multiple prefix=... directives}}
do_catchsql_test 6.2 {
CREATE VIRTUAL TABLE abc USING fts5(a, prefix='1, 2, 1001');
} {1 {prefix length out of range (max 999)}}
} {1 {prefix length out of range: 1001}}
do_catchsql_test 6.3 {
CREATE VIRTUAL TAbLE abc USING fts5(a, prefix='1, 2, 0000');
} {1 {prefix length out of range (max 999)}}
} {1 {prefix length out of range: 0}}
do_catchsql_test 6.4 {
CREATE VIRTUAL TABLE abc USING fts5(a, prefix='1 , 1000000');
} {1 {prefix length out of range (max 999)}}
} {1 {malformed prefix=... directive}}
#-------------------------------------------------------------------------
# Duplicate tokenize= and other options.
@@ -203,16 +204,5 @@ do_catchsql_test 9.4.1 {
INSERT INTO abc(abc, rank) VALUES('nosuchoption', 1);
} {1 {SQL logic error or missing database}}
#-------------------------------------------------------------------------
# Too many prefix indexes. Maximum allowed is 31.
#
foreach {tn spec} {
1 {prefix="1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32"}
2 {prefix="1 2 3 4", prefix="5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32"}
} {
set sql "CREATE VIRTUAL TABLE xyz USING fts5(x, $spec)"
do_catchsql_test 10.$tn $sql {1 {too many prefix indexes (max 31)}}
}
finish_test
-42
View File
@@ -298,48 +298,6 @@ foreach {tn col pattern} {
do_execsql_test 6.$tn { SELECT rowid FROM t5($query) } $res
}
#-------------------------------------------------------------------------
# Check that the various ways of creating prefix indexes produce the
# same database on disk.
#
save_prng_state
foreach {tn create} {
1 { CREATE VIRTUAL TABLE tt USING fts5(x, y, prefix="1,2,3") }
2 { CREATE VIRTUAL TABLE tt USING fts5(x, y, prefix="1 2 3") }
3 { CREATE VIRTUAL TABLE tt USING fts5(x, y, prefix=1, prefix=2, prefix=3) }
4 { CREATE VIRTUAL TABLE tt USING fts5(x, y, prefix="1 2", prefix=3) }
} {
execsql { DROP TABLE IF EXISTS tt }
restore_prng_state
execsql $create
execsql {
INSERT INTO tt VALUES('cc b ggg ccc aa eee hh', 'aa g b hh a e');
INSERT INTO tt VALUES('cc bb cc gg j g cc', 'ii jjj ggg jjj cc cc');
INSERT INTO tt VALUES('h eee cc h iii', 'aaa iii dd iii dd');
INSERT INTO tt VALUES('jjj hh eee c e b gg', 'j bbb jj ddd jj');
INSERT INTO tt VALUES('ii hhh aaa ff c hhh iii', 'j cc hh bb e');
INSERT INTO tt VALUES('e fff hhh i aaa', 'g b aa gg c aa dd');
INSERT INTO tt VALUES('i aaa ccc gg hhh aa h', 'j bbb bbb d ff');
INSERT INTO tt VALUES('g f gg ff ff jjj d', 'jjj d j fff fff ee j');
INSERT INTO tt VALUES('a cc e ccc jjj c', 'ccc iii d bb a eee g');
INSERT INTO tt VALUES('jj hh hh bb bbb gg', 'j c jjj bb iii f');
INSERT INTO tt VALUES('a ggg g cc ccc aa', 'jjj j j aaa c');
INSERT INTO tt VALUES('ddd j dd b i', 'aaa bbb iii ggg ff ccc ddd');
INSERT INTO tt VALUES('jj ii hh c ii h gg', 'hhh bbb ddd bbb hh g ggg');
INSERT INTO tt VALUES('aa hhh ccc h ggg ccc', 'iii d jj a ff ii');
}
#db eval {SELECT rowid, fts5_decode(rowid, block) aS r FROM tt_data} {puts $r}
if {$tn==1} {
set ::checksum [execsql {SELECT md5sum(id, block) FROM tt_data}]
} else {
do_execsql_test 7.$tn {
SELECT md5sum(id, block) FROM tt_data
} [list $::checksum]
}
}
finish_test
+1 -111
View File
@@ -1181,7 +1181,7 @@ static void jsonTest1Func(
#endif /* SQLITE_DEBUG */
/****************************************************************************
** Scalar SQL function implementations
** SQL function implementations
****************************************************************************/
/*
@@ -1514,102 +1514,6 @@ static void jsonValidFunc(
sqlite3_result_int(ctx, rc);
}
/****************************************************************************
** Aggregate SQL function implementations
****************************************************************************/
/*
** json_group_array(VALUE)
**
** Return a JSON array composed of all values in the aggregate.
*/
static void jsonArrayStep(
sqlite3_context *ctx,
int argc,
sqlite3_value **argv
){
JsonString *pStr;
pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
if( pStr ){
if( pStr->zBuf==0 ){
jsonInit(pStr, ctx);
jsonAppendChar(pStr, '[');
}else{
jsonAppendChar(pStr, ',');
pStr->pCtx = ctx;
}
jsonAppendValue(pStr, argv[0]);
}
}
static void jsonArrayFinal(sqlite3_context *ctx){
JsonString *pStr;
pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
if( pStr ){
pStr->pCtx = ctx;
jsonAppendChar(pStr, ']');
if( pStr->bErr ){
sqlite3_result_error_nomem(ctx);
if( !pStr->bStatic ) sqlite3_free(pStr->zBuf);
}else{
sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed,
pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
pStr->bStatic = 1;
}
}else{
sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC);
}
sqlite3_result_subtype(ctx, JSON_SUBTYPE);
}
/*
** json_group_obj(NAME,VALUE)
**
** Return a JSON object composed of all names and values in the aggregate.
*/
static void jsonObjectStep(
sqlite3_context *ctx,
int argc,
sqlite3_value **argv
){
JsonString *pStr;
const char *z;
u32 n;
pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
if( pStr ){
if( pStr->zBuf==0 ){
jsonInit(pStr, ctx);
jsonAppendChar(pStr, '{');
}else{
jsonAppendChar(pStr, ',');
pStr->pCtx = ctx;
}
z = (const char*)sqlite3_value_text(argv[0]);
n = (u32)sqlite3_value_bytes(argv[0]);
jsonAppendString(pStr, z, n);
jsonAppendChar(pStr, ':');
jsonAppendValue(pStr, argv[1]);
}
}
static void jsonObjectFinal(sqlite3_context *ctx){
JsonString *pStr;
pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
if( pStr ){
jsonAppendChar(pStr, '}');
if( pStr->bErr ){
sqlite3_result_error_nomem(ctx);
if( !pStr->bStatic ) sqlite3_free(pStr->zBuf);
}else{
sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed,
pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
pStr->bStatic = 1;
}
}else{
sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC);
}
sqlite3_result_subtype(ctx, JSON_SUBTYPE);
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
/****************************************************************************
** The json_each virtual table
@@ -2108,15 +2012,6 @@ int sqlite3Json1Init(sqlite3 *db){
{ "json_test1", 1, 0, jsonTest1Func },
#endif
};
static const struct {
const char *zName;
int nArg;
void (*xStep)(sqlite3_context*,int,sqlite3_value**);
void (*xFinal)(sqlite3_context*);
} aAgg[] = {
{ "json_group_array", 1, jsonArrayStep, jsonArrayFinal },
{ "json_group_object", 2, jsonObjectStep, jsonObjectFinal },
};
#ifndef SQLITE_OMIT_VIRTUALTABLE
static const struct {
const char *zName;
@@ -2132,11 +2027,6 @@ int sqlite3Json1Init(sqlite3 *db){
(void*)&aFunc[i].flag,
aFunc[i].xFunc, 0, 0);
}
for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
rc = sqlite3_create_function(db, aAgg[i].zName, aAgg[i].nArg,
SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
0, aAgg[i].xStep, aAgg[i].xFinal);
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
+1 -9
View File
@@ -1717,23 +1717,17 @@ static void scriptCodeSqlFunc(
# define SCRIPT_LATIN 0x0001
# define SCRIPT_CYRILLIC 0x0002
# define SCRIPT_GREEK 0x0004
# define SCRIPT_HEBREW 0x0008
# define SCRIPT_ARABIC 0x0010
while( nIn>0 ){
c = utf8Read(zIn, nIn, &sz);
zIn += sz;
nIn -= sz;
if( c<0x02af && (c>=0x80 || midClass[c&0x7f]<CCLASS_DIGIT) ){
if( c<0x02af ){
scriptMask |= SCRIPT_LATIN;
}else if( c>=0x0400 && c<=0x04ff ){
scriptMask |= SCRIPT_CYRILLIC;
}else if( c>=0x0386 && c<=0x03ce ){
scriptMask |= SCRIPT_GREEK;
}else if( c>=0x0590 && c<=0x05ff ){
scriptMask |= SCRIPT_HEBREW;
}else if( c>=0x0600 && c<=0x06ff ){
scriptMask |= SCRIPT_ARABIC;
}
}
switch( scriptMask ){
@@ -1741,8 +1735,6 @@ static void scriptCodeSqlFunc(
case SCRIPT_LATIN: res = 215; break;
case SCRIPT_CYRILLIC: res = 220; break;
case SCRIPT_GREEK: res = 200; break;
case SCRIPT_HEBREW: res = 125; break;
case SCRIPT_ARABIC: res = 160; break;
default: res = 998; break;
}
sqlite3_result_int(context, res);
+2 -3
View File
@@ -312,7 +312,6 @@ TESTSRC = \
$(TOP)/src/test_tclvar.c \
$(TOP)/src/test_thread.c \
$(TOP)/src/test_vfs.c \
$(TOP)/src/test_windirent.c \
$(TOP)/src/test_wsd.c
# Extensions to be statically loaded.
@@ -795,8 +794,8 @@ THREADTEST3_SRC = $(TOP)/test/threadtest3.c \
$(TOP)/test/tt3_stress.c \
$(TOP)/test/tt3_lookaside1.c
threadtest3$(EXE): sqlite3.o $(THREADTEST3_SRC) $(TOP)/src/test_multiplex.c
$(TCCX) $(TOP)/test/threadtest3.c $(TOP)/src/test_multiplex.c sqlite3.o -o $@ $(THREADLIB)
threadtest3$(EXE): sqlite3.o $(THREADTEST3_SRC)
$(TCCX) $(TOP)/test/threadtest3.c sqlite3.o -o $@ $(THREADLIB)
threadtest: threadtest3$(EXE)
./threadtest3$(EXE)
+108 -110
View File
@@ -1,8 +1,8 @@
C Use\sthe\sOvflOffset()\smacro\sto\stry\sto\sremove\ssome\smagic\snumbers\sfrom\sbtree.c.
D 2015-12-30T20:50:11.553
F Makefile.in 28bcd6149e050dff35d4dcfd97e890cd387a499d
C Add\sa\snew\sOP_BColumn\sopcode\swhere\sthe\scursor\sis\sguaranteed\sto\sbe\sof\stype\nCURTYPE_BTREE\sand\sis\sthus\sable\sto\sskip\ssome\schecks\sand\srun\sslightly\sfaster.
D 2015-11-21T17:53:06.758
F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 5fff077fcc46de7714ed6eebb6159a4c00eab751
F Makefile.msc e928e68168df69b353300ac87c10105206653a03
F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7
F VERSION 8b9d3ac6f1962f94e06ba05462422a544f9c4e36
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
@@ -13,7 +13,13 @@ F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
F autoconf/Makefile.am 089e5ecdb5761e64ea1013ded02feb4d8b29927d
F autoconf/README 14458f1046c118efa721aadec5f227e876d3cd38
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
F autoconf/configure.ac 82c628c68f0f204d57343dc345b6dbd1789fb1bd
F autoconf/config.guess 94cc57e2a3fdb9c235b362ace86d77e89d188cad x
F autoconf/config.sub 1efb390a8fb4bfafd74783a15a8fb5311c84300e x
F autoconf/configure.ac 9a65da17e440466f9842288163f16f9b21298129
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 b438a7020446c8a8156e8d97c8914a04833da6fd
F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873
F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43
@@ -90,7 +96,7 @@ F ext/fts3/fts3_unicode2.c c3d01968d497bd7001e7dc774ba75b372738c057
F ext/fts3/fts3_write.c f442223e4a1914dc1fc12b65af7e4f2c255fa47c
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
F ext/fts3/tool/fts3view.c 5d78b668f4e9598af9147f8999632599fb0d9dd5
F ext/fts3/tool/fts3view.c 8e53d0190a7b3443764bbd32ad47be2bd852026d
F ext/fts3/unicode/CaseFolding.txt 8c678ca52ecc95e16bc7afc2dbf6fc9ffa05db8c
F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7
F ext/fts3/unicode/mkunicode.tcl 95cf7ec186e48d4985e433ff8a1c89090a774252
@@ -98,17 +104,17 @@ F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95
F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
F ext/fts5/fts5.h 8b9a13b309b180e9fb88ea5666c0d8d73c6102d9
F ext/fts5/fts5Int.h acf968e43d57b6b1caf7554d34ec35d6ed3b4fe8
F ext/fts5/fts5_aux.c 2dafc3aee0c70d643140c77d8d70daffa51a9e9e
F ext/fts5/fts5_aux.c 1f384972d606375b8fa078319f25ab4b5feb1b35
F ext/fts5/fts5_buffer.c 1e49512a535045e621246dc7f4f65f3593fa0fc2
F ext/fts5/fts5_config.c 0ee66188609a62342e9f9aeefa3c3e44518a4dd6
F ext/fts5/fts5_expr.c 8228aca3e9af626a1ca9b093d4d24b4f2488ad23
F ext/fts5/fts5_hash.c 25838d525e97f8662ff3504be94d0bad24f9a37e
F ext/fts5/fts5_index.c 578f46697080f11a1e26cd45a1c039c043a3111d
F ext/fts5/fts5_main.c e11b525778e6fce416d916bfa96926bd1ce4616d
F ext/fts5/fts5_storage.c 57c636d87cbb829d6147c8c8bf78fa53b9ebb526
F ext/fts5/fts5_config.c 6fc92c0b1bda5244c28a54c9ba740736bd5513d9
F ext/fts5/fts5_expr.c 28b15c9ae296204bc0a2e5cf7a667d840a9d2900
F ext/fts5/fts5_hash.c a9d4c1efebc2a91d26ad7ebdfcbf2678ceac405f
F ext/fts5/fts5_index.c b622a0a70f57a96469e6828da2dd70e0872aeb37
F ext/fts5/fts5_main.c 7581280ee242785477df67402f2853c66f77d45b
F ext/fts5/fts5_storage.c 9ea3d92178743758b6c54d9fe8836bbbdcc92e3b
F ext/fts5/fts5_tcl.c 3bf445e66de32137d4693694ff7b1fd6074e32bd
F ext/fts5/fts5_test_mi.c e96be827aa8f571031e65e481251dc1981d608bf
F ext/fts5/fts5_tokenize.c 504984ac6993323247221eebe3cd55bead01b5f8
F ext/fts5/fts5_tokenize.c 12c5d925286491a71bb3dad7c8924ce9cfd18320
F ext/fts5/fts5_unicode2.c 78273fbd588d1d9bd0a7e4e0ccc9207348bae33c
F ext/fts5/fts5_varint.c 3f86ce09cab152e3d45490d7586b7ed2e40c13f1
F ext/fts5/fts5_vocab.c 3742d0abfe8aa8c3cb4a7df56aa38f2e3c3fb1c2
@@ -133,7 +139,7 @@ F ext/fts5/test/fts5aux.test 8c687c948cc98e9a94be014df7d518acc1b3b74f
F ext/fts5/test/fts5auxdata.test 141a7cbffcceb1bd2799b4b29c183ff8780d586e
F ext/fts5/test/fts5bigpl.test 04ee0d7eebbebf17c31f5a0b5c5f9494eac3a0cb
F ext/fts5/test/fts5columnsize.test a8cfef21ffa1c264b9f670a7d94eeaccb5341c07
F ext/fts5/test/fts5config.test 42c1336cc6ed33d7e9c4a05dbce81721b765e7d0
F ext/fts5/test/fts5config.test ad2ff42ddc856aed2d05bf89dc1c578c8a39ea3b
F ext/fts5/test/fts5conflict.test 26f4e46c4d31e16221794832a990dc4e30e18de5
F ext/fts5/test/fts5content.test 9a952c95518a14182dc3b59e3c8fa71cda82a4e1
F ext/fts5/test/fts5corrupt.test c2ad090192708150d50d961278df10ae7a4b8b62
@@ -162,7 +168,7 @@ F ext/fts5/test/fts5phrase.test f6d1d464da5beb25dc56277aa4f1d6102f0d9a2f
F ext/fts5/test/fts5plan.test 6a55ecbac9890765b0e16f8c421c7e0888cfe436
F ext/fts5/test/fts5porter.test 7cdc07bef301d70eebbfa75dcaf45c3680e1d0e1
F ext/fts5/test/fts5porter2.test 2e65633d58a1c525d5af0f6c01e5a59155bb3487
F ext/fts5/test/fts5prefix.test efd42e00bb8e8a36383f25c838185508681c093f
F ext/fts5/test/fts5prefix.test 7ccbdf180ed561a912acef520519e85af8642239
F ext/fts5/test/fts5query.test f5ec25f5f2fbb70033424113cdffc101b1985a40
F ext/fts5/test/fts5rank.test 7e9e64eac7245637f6f2033aec4b292aaf611aab
F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b
@@ -191,14 +197,14 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
F ext/misc/fuzzer.c 4c84635c71c26cfa7c2e5848cf49fe2d2cfcd767
F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
F ext/misc/json1.c b7ed42db00f7429c0f0b5068209c95c41b531596
F ext/misc/json1.c 4f45afd9dbcd6feca8c528251efbb7fc09299a09
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
F ext/misc/series.c b8fb7befd85b3a9b4a10e701b30b2b79ca92b6d4
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
F ext/misc/spellfix.c df6efb90eb668d1860c9b59e4320e985e46dffa7
F ext/misc/spellfix.c b9065af7ab1f2597b505a8aa9892620866d502fc
F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
@@ -257,119 +263,119 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F main.mk ed77cbb97848c8dae1ab928245432f74b0580162
F main.mk ae99be5eb22933b1ecf80f94d41d25a3ea80aaf3
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421
F mptest/crash02.subtest f4ef05adcd15d60e5d2bd654204f2c008b519df8
F mptest/mptest.c 0d3f2eb8e373cb692ab362a6dddedd53e0978502
F mptest/mptest.c e7b499cb0cf8c3de65eaf24dec9b36daa4e013e4
F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d
F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 9d649e46c780166e416fb11dbd23f8d49aab8267
F src/analyze.c 977bd50c751bb939ef52917892e12bedbfcea7ce
F src/analyze.c 4c308880cf53c558070cb8513bdff4ffb1a38a77
F src/attach.c e944d0052b577703b9b83aac1638452ff42a8395
F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc
F src/bitvec.c 1a78d450a17c5016710eec900bedfc5729bf9bdf
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
F src/btree.c ec6627fbb483526e0f6e095c0a438191fe6386b3
F src/btree.c d3bdd8462a86492e2ebc9aca4a0168429017de25
F src/btree.h 2d76dee44704c47eed323356a758662724b674a0
F src/btreeInt.h dc698b04ae266bcce5f2eebba007133bf2339ef5
F src/build.c 5a8611a01cbf67c736d81304e054ec361ef8963d
F src/btreeInt.h 3ab435ed27adea54d040584b0bcc488ee7db1e38
F src/build.c 19f7585c9747d5043dae64bc82f9cac759f69700
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198
F src/date.c e4655393bb403fa310eef66cc4583d75d4d7fd93
F src/ctime.c 509ef9c64d1321f42448f111da86400b1799218a
F src/date.c fb1c99172017dcc8e237339132c91a21a0788584
F src/dbstat.c ffd63fc8ba7541476ced189b95e95d7f2bc63f78
F src/delete.c 00af9f08a15ddc5cba5962d3d3e5bf2d67b2e7da
F src/expr.c 38790e65d1219f2b7dc26458f39a5252fe7c60cd
F src/expr.c dfccb439a2a981d71970ce3d15effeb59b258798
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c e18b3dff7d47c7bcac5ac4fc178a89b9fd322b44
F src/func.c cf5e10af9125b245f1b962e8ba4d520a37818795
F src/global.c bd5a0af3f30b0c01be6db756c626cd3c33a3d260
F src/fkey.c 31900763094a3736a5fc887469202eb579fef2d0
F src/func.c ecdd69ec6a1e406f04cc73324be2ebbf6354197f
F src/global.c 508e4087f7b41d688e4762dcf4d4fe28cfbc87f9
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c 6b45cc86967da11aa024d034745f93f66d53f650
F src/insert.c e1d20ae8979e25519c2670233718676bedcfedc9
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
F src/loadext.c 84996d7d70a605597d79c1f1d7b2012a5fd34f2b
F src/main.c b9641a4f650230bfc5dbb0bebf7b33ff4d27586a
F src/malloc.c 8f787669e79de26efc42272b5797bc00fff527c6
F src/loadext.c 18586e45a215325f15096821e9c082035d4fb810
F src/main.c 91feb5c7e393ad8f0c434754114a3493c3b0617a
F src/malloc.c 337bbe9c7d436ef9b7d06b5dd10bbfc8f3025972
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
F src/mem5.c 262055c242fa7db59c5f07ad77fdc4e97888c054
F src/mem5.c 5c267678ba9f745a2ee58102a9f482d64a58577a
F src/memjournal.c 3eb2c0b51adbd869cb6a44780323f05fa904dc85
F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495
F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4
F src/mutex_unix.c 27bb6cc49485ee46711a6580ab7b3f1402211d23
F src/mutex_unix.c fc54f25b2a750d53b32512a4a728cec28039ae2a
F src/mutex_w32.c 5e6fe1c298fb5a8a15aaed4161d5759311431c17
F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7
F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8
F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf
F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
F src/os_unix.c 0ca6d8710366fbb01a275160f018334cd347cbda
F src/os_unix.c bddde71dc024574ace03ffee859abb99d152fd4a
F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
F src/pager.c 58d2593612acb6b542de6715b4af397ea1fa0a35
F src/pager.h bf25005b4656cd805af43487c3139fca9678d0cc
F src/pager.c 18341e2b759b447cbc82fb9215d08d9c5864e92e
F src/pager.h 87c4118a71ba3965184148b379a6d93179071091
F src/parse.y 23737e649c26ce327603799e57f5c2ff50e5e6ba
F src/pcache.c 73895411fa6b7bd6f0091212feabbe833b358d23
F src/pcache.h 1ff11adce609ba7de139b6abfabaf9a2bac947b5
F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051
F src/pcache1.c 902e1bc7bdaa81b40f8543407c5e2ac8ef4dc035
F src/pragma.c f3e7147299ca05ef4304a36f1fd6e002729c72c6
F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c
F src/pragma.h 3d94aebbebd2089899fecc01909bf2608b39507d
F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1
F src/printf.c af589a27b7d40f6f4f704e9eea99f02f18ad6d32
F src/printf.c f8fc8f04e75b1e983ef2793c27ec7a43b287e94a
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
F src/resolve.c a83b41104e6ff69855d03cd0aaa09e93927ec39f
F src/resolve.c f4c897ca76ca6d5e0b3f0499c627392ffe657c8e
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
F src/select.c f8fded11fc443a9f5a73cc5db069d06b34460e2f
F src/shell.c ace08b69cd9702143cf87b5bd20b744a56f832fd
F src/sqlite.h.in 7d87d71b9a4689c51fa092f48f16590ff71558e3
F src/select.c 0495e86f8377026fbd529a1a5bf62046cbb6eec5
F src/shell.c f0f59ea60ad297f671b7ae0fb957a736ad17c92c
F src/sqlite.h.in fa62718f73553f06b2f2e362fd09ccb4e1cbb626
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d
F src/sqliteInt.h 526c8514d0cb0768d014d04445c6eebd1d0b1a2c
F src/sqlite3ext.h 4b66e3e3435da4b4c8c83696d0349f0c503b3924
F src/sqliteInt.h 64256d193a16a147d9f6317cc4e095fdd3e0a2e9
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
F src/tclsqlite.c d9439b6a910985b7fff43ba6756bcef00de22649
F src/test1.c 4f1b42699068b7806af3111786f5ad760c2c1ff7
F src/test1.c 4004bcc1b3b361a9137acd1d875599ecbdd6f961
F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b
F src/test3.c a8887dabbbee3059af338f20d290084a63ed1b0f
F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e
F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1
F src/test6.c 41cacf3b0dd180823919bf9e1fbab287c9266723
F src/test7.c 9c89a4f1ed6bb13af0ed805b8d782bd83fcd57e3
F src/test8.c fa262391d3edea6490a71bfaa8fed477ccbbac75
F src/test8.c 610e3d523018ca63b08081795e76794a2121ec38
F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8
F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12
F src/test_backup.c 2e6e6a081870150f20c526a2e9d0d29cda47d803
F src/test_blob.c e5a7a81d61a780da79101aeb1e60d300af169e07
F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f
F src/test_config.c 0dee90328e3dedf8ba002ee94b6a7e7ea7726fe4
F src/test_config.c f2824de39f59d8d621e2d6ec5cc67006d000b2eb
F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
F src/test_fs.c 993c7eab65bed6add4bb48cca29775e963f710cf
F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f
F src/test_func.c 0d9c25956152adefee8881c6fadc8354793764d0
F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32
F src/test_intarray.c 870124b95ec4c645d4eb84f15efb7133528fb1a5
F src/test_intarray.h 9dc57417fb65bc7835cc18548852cc08cc062202
F src/test_journal.c 5360fbe1d1e4416ca36290562fd5a2e3f70f32aa
F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd
F src/test_malloc.c 96df9381a1ff1f6d3805ff7231b9baf1386aaabf
F src/test_multiplex.c 6a088d8d9d4aad4bec45dd8878af11b15900702d
F src/test_loadext.c a5251f956ab6af21e138dc1f9c0399394a510cb4
F src/test_malloc.c 27d9e11b6e9d30267465d41ad81edbe24256408b
F src/test_multiplex.c 9fefd23f6cc3fa9bf0748a5e453167e7b9f193ce
F src/test_multiplex.h c08e4e8f8651f0c5e0509b138ff4d5b43ed1f5d3
F src/test_mutex.c dbdfaff8580071f2212a0deae3325a93a737819c
F src/test_onefile.c 38f7cbe79d5bafe95bde683cc3a53b8ca16daf10
@@ -383,39 +389,37 @@ F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe
F src/test_sqllog.c 0d138a8180a312bf996b37fa66da5c5799d4d57b
F src/test_superlock.c 06797157176eb7085027d9dd278c0d7a105e3ec9
F src/test_syscall.c 2e21ca7f7dc54a028f1967b63f1e76155c356f9b
F src/test_tclvar.c d86412527da65468ee6fa1b8607c65d0af736bc4
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
F src/test_thread.c af391ec03d23486dffbcc250b7e58e073f172af9
F src/test_vfs.c 3b65d42e18b262805716bd96178c81da8f2d9283
F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
F src/test_windirent.c 8f5fada630348558d5745b334702f301da1ffc61
F src/test_windirent.h b12055cab6227f7be10f5c19296f67c60cc5e2a5
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c bbfb74450643cb5372a43ad4f6cffd7e9dfcecb0
F src/tokenize.c 5606871a377f390af7040ec3c12e0d183512d785
F src/treeview.c 78842e90c1f71269e7a73a1d4221b6fe360bab66
F src/trigger.c de3ed31ad3218a20d7d7e18bf1b3b734e78bda66
F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3
F src/utf.c 32d7f82aa921322f3e1c956f4b58f019ebd2c6b3
F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f
F src/update.c 40e51cd0883cb5bfd6abb7d8a7cd8aa47fab2945
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
F src/util.c e802e8e311a0d6c48cd1b3e89db164f6f0248d70
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
F src/vdbe.c 984c2be6691d3f67deb2e6747c2132150d776f32
F src/vdbe.c 8694c0e6497cd21e19e30ac059f933ac5d9abea2
F src/vdbe.h efb7a8c1459e31f3ea4377824c6a7e4cb5068637
F src/vdbeInt.h 75c2e82ee3357e9210c06474f8d9bdf12c81105d
F src/vdbeapi.c 020681b943e77766b32ae1cddf86d7831b7374ca
F src/vdbeaux.c 68082d9991fc1b8625d34c8b5db1775c9dee426e
F src/vdbeaux.c 16e21a6ae0c290f17f6e7395d80686622cafeaa2
F src/vdbeblob.c fdc4a81605ae7a35ae94a55bd768b66d6be16f15
F src/vdbemem.c fdd1578e47bea61390d472de53c565781d81e045
F src/vdbesort.c a7ec02da4494c59dfd071126dd3726be5a11459d
F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0
F src/vtab.c 2a8b44aa372c33f6154208e7a7f6c44254549806
F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
F src/wal.c 974928c988681c5157202c79dd9f26afaa7b5086
F src/wal.h 907943dfdef10b583e81906679a347e0ec6f1b1b
F src/wal.c 18b0ed49830cf04fe2d68224b41838a73ac6cd24
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba
F src/where.c c6d3d2f6af57d574a7365ee2b225a5024f2a6bec
F src/whereInt.h 78b6b4de94db84aecbdc07fe3e38f648eb391e9a
F src/wherecode.c dfbfe198e418b01f208b489e088edd230c91a4e7
F src/whereexpr.c eebba8340c90de73b3d3bbe8c43b84559b8e6e2c
F src/where.c 6aceb72cc58dc06922a9e1604d559c8ca4c3e728
F src/whereInt.h 7892bb54cf9ca0ae5c7e6094491b94c9286dc647
F src/wherecode.c 4c96182e7b25e4be54008dee2da5b9c2f8480b9b
F src/whereexpr.c bd4877cd4dd11f6ab551ef0054535ca3c6224950
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@@ -429,7 +433,7 @@ F test/alter4.test c461150723ac957f3b2214aa0b11552cd72023ec
F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
F test/analyze.test 3eb35a4af972f98422e5dc0586501b17d103d321
F test/analyze3.test 1dccda46a6c374018af617fba00bfe297a61d442
F test/analyze3.test 0f0ee6135b293a0e5af471a8423b80b688469d71
F test/analyze4.test eff2df19b8dd84529966420f29ea52edc6b56213
F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4
F test/analyze6.test f1c552ce39cca4ec922a7e4e0e5d0203d6b3281f
@@ -502,7 +506,7 @@ F test/cacheflush.test a755c93482ce2e20c04825304bef27e7b7ea0111
F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738
F test/capi3.test bf6f0308bbbba1e770dac13aa08e5c2ac61c7324
F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
F test/capi3c.test 06f6261f9e9b4ef6f76afcd9900f3665408af1c8
F test/capi3c.test fdc0d67a2cb8e8fc400d5b7735e330161ea057a2
F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
@@ -563,7 +567,7 @@ F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8
F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47
F test/cursorhint.test 432811b62bd5ffb812729f49bba3b9ad687550bb
F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65
F test/date.test 42973251b9429f2c41b77eb98a7b0b0ba2d3b2c0
F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204
F test/dbstatus2.test 10418e62b3db5dca070f0c3eef3ea13946f339c2
F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d
@@ -575,7 +579,7 @@ F test/descidx1.test 6d03b44c8538fe0eb4924e19fba10cdd8f3c9240
F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d
F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2
F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
F test/distinct.test a1783b960ad8c15a77cd9f207be072898db1026c
F test/distinct.test 175d49ee783febaf368192dfe7f5afbc68910230
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
F test/e_blobbytes.test 9bea1d3e2b20f3010b04abba58f6ba172301f49f
F test/e_blobclose.test df756753f571bc30e42e3a6cba2807576e49e716
@@ -604,7 +608,7 @@ F test/e_walckpt.test 65e29b6631e51f210f83e4ff11571e647ba93608
F test/e_walhook.test da3ea8b3483d1af72190337bda50155a91a4b664
F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
F test/enc2.test 83437a79ba1545a55fb549309175c683fb334473
F test/enc3.test 6807f7a7740a00361ca8d0ccd66bc60c8dc5f2b6
F test/enc3.test 90683ad0e6ea587b9d5542ca93568af9a9858c40
F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020
F test/eqp.test 85873fa5816c48915c82c4e74cb5c35a5b48160f
F test/errmsg.test f31592a594b44ee121371d25ddd5d63497bb3401
@@ -724,7 +728,7 @@ F test/fts3tok_err.test 52273cd193b9036282f7bacb43da78c6be87418d
F test/fts3varint.test 752c08ed5d32c5d7dc211b056f4ed68a76b7e36e
F test/fts4aa.test 10aac8e9d62c7357590acfabe3fad01e9a9ce1cb
F test/fts4check.test 9d9e818fd6cb29c0e007cd6d00447739d4fde430
F test/fts4content.test 8707425b926663f8ca81de866c007900442b5ec0
F test/fts4content.test abb0c77bc3da3df64fec72e00844d2257a90025d
F test/fts4docid.test e33c383cfbdff0284685604d256f347a18fdbf01
F test/fts4growth.test df10fde9f47cf5c71861e63fd8efcd573c4f7e53
F test/fts4growth2.test 2f063be1902a73cd087355837c52fed42ac11a5d
@@ -749,7 +753,7 @@ F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1
F test/fuzz3.test 53fabcd5f0f430f8b221282f6c12c4d0903c21eb
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
F test/fuzzcheck.c ccdcdc28579b2c9744696bca8726bdbd729eea11
F test/fuzzcheck.c 7c61352f20a28429b221f406f3854cf9c912f63b
F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664
F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
@@ -757,7 +761,7 @@ F test/fuzzdata4.db 1882f0055fb63214d8407ddc7aca9b0b1c59af21
F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
F test/hexlit.test d7b0a5f41123df1e43985b91b8b2e70f95282d21
F test/hexlit.test 1d312fa816dfd3650a3bb488093bc09a0c927f67
F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711
F test/hook.test 162d7cef7a2d2b04839fe14402934e6a1b79442f
F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4
@@ -787,7 +791,7 @@ F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7
F test/index6.test 7102ec371414c42dfb1d5ca37eb4519aa9edc23a
F test/index7.test 9c6765a74fc3fcde7aebc5b3bd40d98df14a527c
F test/indexedby.test 9c4cd331224e57f79fbf411ae245e6272d415985
F test/indexexpr1.test cb71b6586177b840e28110dd952178bb2bdfedc2
F test/indexexpr1.test bbb52b5d5717d9f23853826963b0af5110009366
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
F test/insert.test 38742b5e9601c8f8d76e9b7555f7270288c2d371
@@ -820,13 +824,12 @@ F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
F test/json101.test f0178422b3a2418f423fd0d3caf3571c8d1b9863
F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a
F test/json103.test 923b288a0610ec86c0951778f7db19cbcca36ad1
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
F test/like.test edcf6d0a055816fd793eab92454597c1be91f720
F test/like.test 4f2a71d36a536233727f71995fef900756705e56
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
F test/like3.test 3608a2042b6f922f900fbfd5d3ce4e7eca57f7c4
F test/like3.test 7b0525a39e4f25c4fd113de7e2e28eb712dcdedf
F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e
F test/loadext.test 648cb95f324d1775c54a55c12271b2d1156b633b
F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7
@@ -929,7 +932,7 @@ F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
F test/permutations.test 4ea119731c62d2f7d0aa86dd5b184cbb61ca411b
F test/pragma.test a44253f911e7d50127d4a08f927f47c861a4c772
F test/pragma2.test a9400a7289605280576098b97f5cde3f204075c0
F test/pragma2.test 00065068eeab2d15ea55465ec0f1e0a70e2c369e
F test/pragma3.test 6f849ccffeee7e496d2f2b5e74152306c0b8757c
F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc
F test/printf2.test 0b61566dd1c0f0b802f59dffa228c5dc5aa6b054
@@ -1015,8 +1018,6 @@ F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a
F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5
F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2
F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b
F test/snapshot.test efc6b4edc5d571161835f9dd8552e181ad1f0ac2
F test/snapshot_fault.test 25973aeb1b86a280800e0bcf1eb5ce70e9ef57ab
F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f
F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087
F test/sort.test 3f492e5b7be1d3f756728d2ff6edf4f6091e84cb
@@ -1036,9 +1037,8 @@ F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
F test/speedtest1.c f8bf04214e7b5f745feea99f7bde68b1c4870666
F test/spellfix.test 0597065ff57042df1f138e6a2611ae19c2698135
F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3
F test/spellfix3.test f7bf7b3482971473d32b6b00f6944c5c066cff97
F test/sqldiff1.test 8f6bc7c6a5b3585d350d779c6078869ba402f8f5
F test/sqllimits1.test a74ee2a3740b9f9c2437c246d8fb77354862a142
F test/sqllimits1.test 89b3d5aad05b99f707ee3786bdd4416dccf83304
F test/sqllog.test a8faa2df39610a037dd372ed872d124260d32953
F test/stat.test 8de91498c99f5298b303f70f1d1f3b9557af91bf
F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1
@@ -1049,10 +1049,10 @@ F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8
F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2
F test/symlink.test cbf6cb8c6c4b63a39e9f0f6b0d5c99e249dbc102
F test/symlink.test 2513f7c030df0f435c6415687ba8b739f3d312df
F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85
F test/syscall.test 2aa9e111b79fb385681ff8940124def6f8faab87
F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04
F test/syscall.test fba9ebdc6905d05bba6a835e691f20ed9ea2cc88
F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6
F test/tabfunc01.test cc33684f9480fcf1fd5ce287ac28d22971cad1cc
F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
@@ -1072,7 +1072,7 @@ F test/thread2.test f35d2106452b77523b3a2b7d1dcde2e5ee8f9e46
F test/thread_common.tcl 334639cadcb9f912bf82aa73f49efd5282e6cadd
F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b
F test/threadtest2.c a70a8e94bef23339d34226eb9521015ef99f4df8
F test/threadtest3.c 7ca82330041456afa52e4968196bb0867371f91b
F test/threadtest3.c 9ab4b168681c3a6f70f6c833ba08e0d48dd4af9b
F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925
F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c
F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660
@@ -1204,7 +1204,7 @@ F test/tkt3824.test 150aa00bb6220672e5f0eb14dc8eaa36750425f0
F test/tkt3832.test 2300d10d57562b89875b72148338ac3e14f8847d
F test/tkt3838.test 292e72489101cd1320d7278dc111c173ebf334d4
F test/tkt3841.test 4659845bc53f809a5932c61c6ce8c5bb9d6b947f
F test/tkt3871.test d921703d07c68f4fd5312073215a17fa34b0401d
F test/tkt3871.test 43ecbc8d90dc83908e2a454aef345acc9d160c6f
F test/tkt3879.test 2ad5bef2c87e9991ce941e054c31abe26ef7fb90
F test/tkt3911.test 74cd324f3ba653040cc6d94cc4857b290d12d633
F test/tkt3918.test ea78bf164e4d55cbde0d83c671ef6fbe930a0032
@@ -1259,10 +1259,10 @@ F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
F test/view.test f6c3a39e0c819891265e1d0754e99960d81ef6c9
F test/vtab1.test 7c4b81abd88361ada9cbe414c459efca26be6bda
F test/vtab1.test 6210e076997f176bedc300a87ad6404651b601dd
F test/vtab2.test f8cd1bb9aba7143eba97812d9617880a36d247ad
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
F test/vtab4.test 8e73ed268f3d596bc3590f45fc948fb40f28e9c3
F test/vtab4.test 942f8b8280b3ea8a41dae20e7822d065ca1cb275
F test/vtab5.test 889f444970393c73f1e077e2bdc5d845e157a391
F test/vtab6.test d2986cf418dc51e7fb81d12366bea2caa8b812df
F test/vtab7.test ae560ebea870ed04e9aa4177cc302f910faaabb5
@@ -1272,10 +1272,8 @@ F test/vtabA.test 1317f06a03597eee29f40a49b6c21e1aaba4285f
F test/vtabB.test 04df5dc531b9f44d9ca65b9c1b79f12b5922a796
F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292
F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96
F test/vtabE.test d5024aa42754962f6bb0afd261681686488e7afe
F test/vtabE.test 7c4693638d7797ce2eda17af74292b97e705cc61
F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e
F test/vtabH.test f77296bbf55675b72817cc10fbbcb236ac986abf
F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
F test/vtab_shared.test ea8778d5b0df200adef2ca7c00c3c37d4375f772
@@ -1312,8 +1310,8 @@ F test/where3.test 1ad55ba900bd7747f98b6082e65bd3e442c5004e
F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
F test/where7.test f520bcec2c3d12dc4615623b06b2aec7c2d67e94
F test/where8.test 98eedca0d375fb400b8377269c4b4686582dfb45
F test/where7.test 5a4b0abc207d71da4deecd734ad8579e8dd40aa8
F test/where8.test 2eafe74e01cc10355985874e1ff868ac03dbae5e
F test/where8m.test da346596e19d54f0aba35ebade032a7c47d79739
F test/where9.test 729c3ba9b47e8f9f1aab96bae7dad2a524f1d1a2
F test/whereA.test 4d253178d135ec46d1671e440cd8f2b916aa6e6b
@@ -1332,7 +1330,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c
F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c
F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972
F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d
F test/with1.test cef099a491eac9874f2c28bd2dc86394fb3e47b3
F test/with1.test 05c8fc7f809f178a8a0519f02c21fe430948c895
F test/with2.test 2b40da883658eb74ad8ad06afabe11a408e7fb87
F test/with3.test 511bacdbe41c49cf34f9fd1bd3245fe1575bca98
F test/withM.test e97f2a8c506ab3ea9eab94e6f6072f6cc924c991
@@ -1346,9 +1344,9 @@ F test/wordcount.c 2a0a6c0d0e8e8bbbac1f06d72a6791828c37c0cf
F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa
F test/zerodamage.test cf6748bad89553cc1632be51a6f54e487e4039ac
F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5
F tool/GetTclKit.bat 629d87562e0487c386db630033931d12d62e6372
F tool/GetTclKit.bat 8606413d3035c05373a0d7fae82ebf59ae9e16c3
F tool/addopcodes.tcl 4ca9c3ef196f08da30add5d07ce0c9458dc8c633
F tool/build-all-msvc.bat 204a039f985d5a4f4f9df3a3aa594fd17848c37e x
F tool/build-all-msvc.bat e42141ca3c3812315432f9813ef9eb78aa8d99c9 x
F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367
F tool/cg_anno.tcl 692ce4b8693d59e3a3de77ca97f4139ecfa641b0 x
F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2
@@ -1363,12 +1361,12 @@ F tool/lemon.c 799e73e19a33b8dd7767a7fa34618ed2a9c2397d
F tool/lempar.c 3ec1463a034b37d87d782be5f6b8b10a3b1ecbe7
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6
F tool/mkautoconfamal.sh 5a5441280b509d2bb3bdc71bfb63781b0d570373
F tool/mkautoconfamal.sh 4bdf61548a143e5977bd86ab93d68b694d10c8fa
F tool/mkkeywordhash.c 06ec0b78bd4fa68c12d90ef2bdfe76b039133ff8
F tool/mkopcodec.tcl edde8adc42621b5e598127f8cdc6d52cfe21f52b
F tool/mkopcodeh.tcl e04177031532b7aa9379ded50e820231ac4abd6e
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
F tool/mkpragmatab.tcl f0d5bb266d1d388cf86fce5ba01a891e95d72d41
F tool/mkpragmatab.tcl e94e55d247d4fe3be34f2a4f4edb03fdcd09ce5b
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
F tool/mksqlite3c-noext.tcl 87240b09c20042999b41d5fabe091b7111287835
F tool/mksqlite3c.tcl b66b4170f693602cd6985aed15d9509fe2f18c84
@@ -1382,7 +1380,7 @@ F tool/replace.tcl 7727c60a04299b65a92f5e1590896fea0f25b9e0
F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5
F tool/run-speed-test.sh 0ae485af4fe9f826e2b494be8c81f8ca9e222a4a
F tool/showdb.c 82dca79a999b2701c62417636345e9974151fdad
F tool/showdb.c d4476e000a64eca9f5e2c2f68741e747b9778e8d
F tool/showjournal.c 5bad7ae8784a43d2b270d953060423b8bd480818
F tool/showlocks.c 9920bcc64f58378ff1118caead34147201f48c68
F tool/showstat4.c bda40d6e395df7edb6e9ea630784d3d762c35b4b
@@ -1395,7 +1393,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
F tool/sqldiff.c 653db1a9294e0b34849c4504599c282a18d8b8c6
F tool/sqldiff.c db1232df457fdd4cbf2a919a497fc44bb18fb933
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f
@@ -1406,10 +1404,10 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 6a4cfc7ab62046eb718ce59eff6b632f239312ac
R c06b170488f3c7c74619bb001be96ae6
T *branch * ovfloffset-macro
T *sym-ovfloffset-macro *
P 198d191b2f5ef7d63ac0093c701955c9052fd734
R 047e676af06478b15f87435c78af3c91
T *branch * btree-column-opcode
T *sym-btree-column-opcode *
T -sym-trunk *
U drh
Z bc33053752556a2a7906fec188dea6ee
Z d7290cc1ec32ea2c40df94d6965d7340
+1 -1
View File
@@ -1 +1 @@
1541607d458069f5db890b4ebe1c7e14ddf4e360
093e0d10a81adc078dcb3e08e33ce89bdbe53789
+3 -3
View File
@@ -422,9 +422,9 @@ static void stringAppend(String *p, const char *z, int n){
if( n<0 ) n = (int)strlen(z);
if( p->n+n>=p->nAlloc ){
int nAlloc = p->nAlloc*2 + n + 100;
char *zNew = sqlite3_realloc(p->z, nAlloc);
if( zNew==0 ) fatalError("out of memory");
p->z = zNew;
char *z = sqlite3_realloc(p->z, nAlloc);
if( z==0 ) fatalError("out of memory");
p->z = z;
p->nAlloc = nAlloc;
}
memcpy(p->z+p->n, z, n);
+1 -1
View File
@@ -990,7 +990,7 @@ static void analyzeOneTable(
/* Do not gather statistics on views or virtual tables */
return;
}
if( sqlite3_strlike("sqlite_%", pTab->zName, 0)==0 ){
if( sqlite3_strnicmp(pTab->zName, "sqlite_", 7)==0 ){
/* Do not gather statistics on system tables */
return;
}
+23 -17
View File
@@ -1051,7 +1051,8 @@ static SQLITE_NOINLINE void btreeParseCellAdjustSizeForOverflow(
}else{
pInfo->nLocal = (u16)minLocal;
}
pInfo->nSize = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell) + 4;
pInfo->iOverflow = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell);
pInfo->nSize = pInfo->iOverflow + 4;
}
/*
@@ -1083,6 +1084,7 @@ static void btreeParseCellPtrNoPayload(
pInfo->nSize = 4 + getVarint(&pCell[4], (u64*)&pInfo->nKey);
pInfo->nPayload = 0;
pInfo->nLocal = 0;
pInfo->iOverflow = 0;
pInfo->pPayload = 0;
return;
}
@@ -1152,6 +1154,7 @@ static void btreeParseCellPtr(
pInfo->nSize = nPayload + (u16)(pIter - pCell);
if( pInfo->nSize<4 ) pInfo->nSize = 4;
pInfo->nLocal = (u16)nPayload;
pInfo->iOverflow = 0;
}else{
btreeParseCellAdjustSizeForOverflow(pPage, pCell, pInfo);
}
@@ -1190,6 +1193,7 @@ static void btreeParseCellPtrIndex(
pInfo->nSize = nPayload + (u16)(pIter - pCell);
if( pInfo->nSize<4 ) pInfo->nSize = 4;
pInfo->nLocal = (u16)nPayload;
pInfo->iOverflow = 0;
}else{
btreeParseCellAdjustSizeForOverflow(pPage, pCell, pInfo);
}
@@ -1305,8 +1309,8 @@ static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
if( *pRC ) return;
assert( pCell!=0 );
pPage->xParseCell(pPage, pCell, &info);
if( info.nLocal<info.nPayload ){
Pgno ovfl = get4byte(&pCell[OvflOffset(&info)]);
if( info.iOverflow ){
Pgno ovfl = get4byte(&pCell[info.iOverflow]);
ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC);
}
}
@@ -3344,11 +3348,11 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
if( eType==PTRMAP_OVERFLOW1 ){
CellInfo info;
pPage->xParseCell(pPage, pCell, &info);
if( info.nLocal<info.nPayload
&& pCell+info.nSize-1<=pPage->aData+pPage->maskPage
&& iFrom==get4byte(pCell+OvflOffset(&info))
if( info.iOverflow
&& pCell+info.iOverflow+3<=pPage->aData+pPage->maskPage
&& iFrom==get4byte(&pCell[info.iOverflow])
){
put4byte(pCell+OvflOffset(&info), iTo);
put4byte(&pCell[info.iOverflow], iTo);
break;
}
}else{
@@ -5990,13 +5994,13 @@ static int clearCell(
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
pPage->xParseCell(pPage, pCell, &info);
*pnSize = info.nSize;
if( info.nLocal==info.nPayload ){
if( info.iOverflow==0 ){
return SQLITE_OK; /* No overflow pages. Return without doing anything */
}
if( pCell+info.nSize-1 > pPage->aData+pPage->maskPage ){
if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){
return SQLITE_CORRUPT_BKPT; /* Cell extends past end of page */
}
ovflPgno = get4byte(pCell + info.nSize - 4);
ovflPgno = get4byte(&pCell[info.iOverflow]);
assert( pBt->usableSize > 4 );
ovflPageSize = pBt->usableSize - 4;
nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize;
@@ -6145,6 +6149,7 @@ static int fillInCell(
assert( info.nKey==nKey );
assert( *pnSize == info.nSize );
assert( spaceLeft == info.nLocal );
assert( pPrior == &pCell[info.iOverflow] );
}
#endif
@@ -6465,7 +6470,7 @@ static int rebuildPage(
pData = pEnd;
for(i=0; i<nCell; i++){
u8 *pCell = apCell[i];
if( SQLITE_WITHIN(pCell,aData,pEnd) ){
if( pCell>aData && pCell<pEnd ){
pCell = &pTmp[pCell - aData];
}
pData -= szCell[i];
@@ -6576,7 +6581,7 @@ static int pageFreeArray(
for(i=iFirst; i<iEnd; i++){
u8 *pCell = pCArray->apCell[i];
if( SQLITE_WITHIN(pCell, pStart, pEnd) ){
if( pCell>=pStart && pCell<pEnd ){
int sz;
/* No need to use cachedCellSize() here. The sizes of all cells that
** are to be freed have already been computing while deciding which
@@ -6854,8 +6859,8 @@ static int ptrmapCheckPages(MemPage **apPage, int nPage){
z = findCell(pPage, j);
pPage->xParseCell(pPage, z, &info);
if( info.nLocal<info.nPayload ){
Pgno ovfl = get4byte(&z[OvflOffset(&info)]);
if( info.iOverflow ){
Pgno ovfl = get4byte(&z[info.iOverflow]);
ptrmapGet(pBt, ovfl, &e, &n);
assert( n==pPage->pgno && e==PTRMAP_OVERFLOW1 );
}
@@ -7516,7 +7521,8 @@ static int balance_nonroot(
** overflow cell), we can skip updating the pointer map entries. */
if( iOld>=nNew
|| pNew->pgno!=aPgno[iOld]
|| !SQLITE_WITHIN(pCell,aOld,&aOld[usableSize])
|| pCell<aOld
|| pCell>=&aOld[usableSize]
){
if( !leafCorrection ){
ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno, &rc);
@@ -9161,9 +9167,9 @@ static int checkTreePage(
if( info.nPayload>info.nLocal ){
int nPage; /* Number of pages on the overflow chain */
Pgno pgnoOvfl; /* First page of the overflow chain */
assert( pc + info.nSize - 4 <= usableSize );
assert( pc + info.iOverflow <= usableSize );
nPage = (info.nPayload - info.nLocal + usableSize - 5)/(usableSize - 4);
pgnoOvfl = get4byte(&pCell[info.nSize - 4]);
pgnoOvfl = get4byte(&pCell[info.iOverflow]);
#ifndef SQLITE_OMIT_AUTOVACUUM
if( pBt->autoVacuum ){
checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage);
+1 -7
View File
@@ -470,16 +470,10 @@ struct CellInfo {
u8 *pPayload; /* Pointer to the start of payload */
u32 nPayload; /* Bytes of payload */
u16 nLocal; /* Amount of payload held locally, not on overflow */
u16 iOverflow; /* Offset to overflow page number. Zero if no overflow */
u16 nSize; /* Size of the cell content on the main b-tree page */
};
/* If X is a pointer to a CellInfo object for a cell, then OvflOffset(X) is
** the offset from the start of that cell to the first overflow page number
** for for that cell.
*/
#define OvflOffset(X) ((X)->nSize-4)
/*
** Maximum depth of an SQLite B-Tree structure. Any B-Tree deeper than
** this will be declared corrupt. This value is calculated based on a
+15 -9
View File
@@ -376,7 +376,12 @@ Table *sqlite3LocateTable(
}
pParse->checkSchema = 1;
}
#if SQLITE_USER_AUTHENTICATION
else if( pParse->db->auth.authLevel<UAUTH_User ){
sqlite3ErrorMsg(pParse, "user not authenticated");
p = 0;
}
#endif
return p;
}
@@ -1635,7 +1640,7 @@ static int resizeIndexObject(sqlite3 *db, Index *pIdx, int N){
zExtra = sqlite3DbMallocZero(db, nByte);
if( zExtra==0 ) return SQLITE_NOMEM;
memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn);
pIdx->azColl = (const char**)zExtra;
pIdx->azColl = (char**)zExtra;
zExtra += sizeof(char*)*N;
memcpy(zExtra, pIdx->aiColumn, sizeof(i16)*pIdx->nColumn);
pIdx->aiColumn = (i16*)zExtra;
@@ -1816,7 +1821,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
if( !hasColumn(pPk->aiColumn, j, i) ){
assert( j<pPk->nColumn );
pPk->aiColumn[j] = i;
pPk->azColl[j] = sqlite3StrBINARY;
pPk->azColl[j] = "BINARY";
j++;
}
}
@@ -2866,7 +2871,7 @@ Index *sqlite3AllocateIndexObject(
p = sqlite3DbMallocZero(db, nByte + nExtra);
if( p ){
char *pExtra = ((char*)p)+ROUND8(sizeof(Index));
p->azColl = (const char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol);
p->azColl = (char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol);
p->aiRowLogEst = (LogEst*)pExtra; pExtra += sizeof(LogEst)*(nCol+1);
p->aiColumn = (i16*)pExtra; pExtra += sizeof(i16)*nCol;
p->aSortOrder = (u8*)pExtra;
@@ -3143,7 +3148,7 @@ Index *sqlite3CreateIndex(
for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
Expr *pCExpr; /* The i-th index expression */
int requestedSortOrder; /* ASC or DESC on the i-th expression */
const char *zColl; /* Collation sequence name */
char *zColl; /* Collation sequence name */
sqlite3StringToId(pListItem->pExpr);
sqlite3ResolveSelfReference(pParse, pTab, NC_IdxExpr, pListItem->pExpr, 0);
@@ -3189,7 +3194,7 @@ Index *sqlite3CreateIndex(
}else if( j>=0 ){
zColl = pTab->aCol[j].zColl;
}
if( !zColl ) zColl = sqlite3StrBINARY;
if( !zColl ) zColl = "BINARY";
if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){
goto exit_create_index;
}
@@ -3218,7 +3223,7 @@ Index *sqlite3CreateIndex(
assert( i==pIndex->nColumn );
}else{
pIndex->aiColumn[i] = XN_ROWID;
pIndex->azColl[i] = sqlite3StrBINARY;
pIndex->azColl[i] = "BINARY";
}
sqlite3DefaultRowEst(pIndex);
if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex);
@@ -4342,8 +4347,9 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){
if( pKey ){
assert( sqlite3KeyInfoIsWriteable(pKey) );
for(i=0; i<nCol; i++){
const char *zColl = pIdx->azColl[i];
pKey->aColl[i] = zColl==sqlite3StrBINARY ? 0 :
char *zColl = pIdx->azColl[i];
assert( zColl!=0 );
pKey->aColl[i] = strcmp(zColl,"BINARY")==0 ? 0 :
sqlite3LocateCollSeq(pParse, zColl);
pKey->aSortOrder[i] = pIdx->aSortOrder[i];
}
-6
View File
@@ -63,9 +63,6 @@ static const char * const azCompileOpt[] = {
#if SQLITE_DISABLE_LFS
"DISABLE_LFS",
#endif
#if SQLITE_ENABLE_8_3_NAMES
"ENABLE_8_3_NAMES",
#endif
#if SQLITE_ENABLE_API_ARMOR
"ENABLE_API_ARMOR",
#endif
@@ -161,9 +158,6 @@ static const char * const azCompileOpt[] = {
#ifdef SQLITE_INT64_TYPE
"INT64_TYPE",
#endif
#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
"LIKE_DOESNT_MATCH_BLOBS",
#endif
#if SQLITE_LOCK_TRACE
"LOCK_TRACE",
#endif
+7 -14
View File
@@ -65,7 +65,6 @@ struct DateTime {
char validHMS; /* True (1) if h,m,s are valid */
char validJD; /* True (1) if iJD is valid */
char validTZ; /* True (1) if tz is valid */
char tzSet; /* Timezone was set explicitly */
};
@@ -159,7 +158,6 @@ static int parseTimezone(const char *zDate, DateTime *p){
p->tz = sgn*(nMn + nHr*60);
zulu_time:
while( sqlite3Isspace(*zDate) ){ zDate++; }
p->tzSet = 1;
return *zDate!=0;
}
@@ -592,18 +590,13 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){
}
#ifndef SQLITE_OMIT_LOCALTIME
else if( strcmp(z, "utc")==0 ){
if( p->tzSet==0 ){
sqlite3_int64 c1;
computeJD(p);
c1 = localtimeOffset(p, pCtx, &rc);
if( rc==SQLITE_OK ){
p->iJD -= c1;
clearYMD_HMS_TZ(p);
p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
}
p->tzSet = 1;
}else{
rc = SQLITE_OK;
sqlite3_int64 c1;
computeJD(p);
c1 = localtimeOffset(p, pCtx, &rc);
if( rc==SQLITE_OK ){
p->iJD -= c1;
clearYMD_HMS_TZ(p);
p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
}
}
#endif
+5 -21
View File
@@ -853,7 +853,6 @@ static int dupedExprSize(Expr *p, int flags){
*/
static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
Expr *pNew = 0; /* Value to return */
assert( flags==0 || flags==EXPRDUP_REDUCE );
if( p ){
const int isReduced = (flags&EXPRDUP_REDUCE);
u8 *zAlloc;
@@ -888,11 +887,9 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
assert( ExprHasProperty(p, EP_Reduced)==0 );
memcpy(zAlloc, p, nNewSize);
}else{
u32 nSize = (u32)exprStructSize(p);
int nSize = exprStructSize(p);
memcpy(zAlloc, p, nSize);
if( nSize<EXPR_FULLSIZE ){
memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize);
}
memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize);
}
/* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */
@@ -982,7 +979,6 @@ static With *withDup(sqlite3 *db, With *p){
** part of the in-memory representation of the database schema.
*/
Expr *sqlite3ExprDup(sqlite3 *db, Expr *p, int flags){
assert( flags==0 || flags==EXPRDUP_REDUCE );
return exprDup(db, p, flags, 0);
}
ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){
@@ -2468,7 +2464,7 @@ void sqlite3ExprCodeLoadIndexColumn(
assert( pIdx->aColExpr );
assert( pIdx->aColExpr->nExpr>iIdxCol );
pParse->iSelfTab = iTabCur;
sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut);
sqlite3ExprCode(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut);
}else{
sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pIdx->pTable, iTabCur,
iTabCol, regOut);
@@ -3321,25 +3317,13 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, pExpr->iTable, target);
}else{
inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
assert( pParse->pVdbe!=0 || pParse->db->mallocFailed );
assert( pParse->pVdbe || pParse->db->mallocFailed );
if( inReg!=target && pParse->pVdbe ){
sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target);
}
}
}
/*
** Make a transient copy of expression pExpr and then code it using
** sqlite3ExprCode(). This routine works just like sqlite3ExprCode()
** except that the input expression is guaranteed to be unchanged.
*/
void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){
sqlite3 *db = pParse->db;
pExpr = sqlite3ExprDup(db, pExpr, 0);
if( !db->mallocFailed ) sqlite3ExprCode(pParse, pExpr, target);
sqlite3ExprDelete(db, pExpr);
}
/*
** Generate code that will evaluate expression pExpr and store the
** results in register target. The results are guaranteed to appear
@@ -3834,7 +3818,7 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){
}
return 2;
}
if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){
if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken ){
if( pA->op==TK_FUNCTION ){
if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
}else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
+4 -2
View File
@@ -249,7 +249,7 @@ int sqlite3FkLocateIndex(
int i, j;
for(i=0; i<nCol; i++){
i16 iCol = pIdx->aiColumn[i]; /* Index of column in parent tbl */
const char *zDfltColl; /* Def. collation for column */
char *zDfltColl; /* Def. collation for column */
char *zIdxCol; /* Name of indexed column */
if( iCol<0 ) break; /* No foreign keys against expression indexes */
@@ -258,7 +258,9 @@ int sqlite3FkLocateIndex(
** the default collation sequence for the column, this index is
** unusable. Bail out early in this case. */
zDfltColl = pParent->aCol[iCol].zColl;
if( !zDfltColl ) zDfltColl = sqlite3StrBINARY;
if( !zDfltColl ){
zDfltColl = "BINARY";
}
if( sqlite3StrICmp(pIdx->azColl[i], zDfltColl) ) break;
zIdxCol = pParent->aCol[iCol].zName;
+1 -19
View File
@@ -747,7 +747,7 @@ static int patternCompare(
}
c2 = Utf8Read(zString);
if( c==c2 ) continue;
if( noCase && sqlite3Tolower(c)==sqlite3Tolower(c2) ){
if( noCase && c<0x80 && c2<0x80 && sqlite3Tolower(c)==sqlite3Tolower(c2) ){
continue;
}
if( c==matchOne && zPattern!=zEscaped && c2!=0 ) continue;
@@ -763,13 +763,6 @@ int sqlite3_strglob(const char *zGlobPattern, const char *zString){
return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, 0)==0;
}
/*
** The sqlite3_strlike() interface.
*/
int sqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){
return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc)==0;
}
/*
** Count the number of times that the LIKE operator (or GLOB which is
** just a variation of LIKE) gets called. This is used for testing
@@ -802,17 +795,6 @@ static void likeFunc(
int nPat;
sqlite3 *db = sqlite3_context_db_handle(context);
#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
if( sqlite3_value_type(argv[0])==SQLITE_BLOB
|| sqlite3_value_type(argv[1])==SQLITE_BLOB
){
#ifdef SQLITE_TEST
sqlite3_like_count++;
#endif
sqlite3_result_int(context, 0);
return;
}
#endif
zB = sqlite3_value_text(argv[0]);
zA = sqlite3_value_text(argv[1]);
-5
View File
@@ -260,8 +260,3 @@ int sqlite3PendingByte = 0x40000000;
** the vdbe.c file.
*/
const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER;
/*
** Name of the default collating sequence
*/
const char sqlite3StrBINARY[] = "BINARY";
+20 -7
View File
@@ -1408,7 +1408,7 @@ void sqlite3GenerateConstraintChecks(
int x;
if( iField==XN_EXPR ){
pParse->ckBase = regNewData+1;
sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i);
sqlite3ExprCode(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i);
pParse->ckBase = 0;
VdbeComment((v, "%s column %d", pIdx->zName, i));
}else{
@@ -1709,6 +1709,20 @@ int sqlite3_xferopt_count;
#ifndef SQLITE_OMIT_XFER_OPT
/*
** Check to collation names to see if they are compatible.
*/
static int xferCompatibleCollation(const char *z1, const char *z2){
if( z1==0 ){
return z2==0;
}
if( z2==0 ){
return 0;
}
return sqlite3StrICmp(z1, z2)==0;
}
/*
** Check to see if index pSrc is compatible as a source of data
** for index pDest in an insert transfer optimization. The rules
@@ -1744,7 +1758,7 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){
if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){
return 0; /* Different sort orders */
}
if( sqlite3_stricmp(pSrc->azColl[i],pDest->azColl[i])!=0 ){
if( !xferCompatibleCollation(pSrc->azColl[i],pDest->azColl[i]) ){
return 0; /* Different collating sequences */
}
}
@@ -1905,7 +1919,7 @@ static int xferOptimization(
if( pDestCol->affinity!=pSrcCol->affinity ){
return 0; /* Affinity must be the same on all columns */
}
if( sqlite3_stricmp(pDestCol->zColl, pSrcCol->zColl)!=0 ){
if( !xferCompatibleCollation(pDestCol->zColl, pSrcCol->zColl) ){
return 0; /* Collating sequence must be the same on all columns */
}
if( pDestCol->notNull && !pSrcCol->notNull ){
@@ -2052,10 +2066,9 @@ static int xferOptimization(
** a VACUUM command. In that case keys may not be written in strictly
** sorted order. */
for(i=0; i<pSrcIdx->nColumn; i++){
const char *zColl = pSrcIdx->azColl[i];
assert( sqlite3_stricmp(sqlite3StrBINARY, zColl)!=0
|| sqlite3StrBINARY==zColl );
if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break;
char *zColl = pSrcIdx->azColl[i];
assert( zColl!=0 );
if( sqlite3_stricmp("BINARY", zColl) ) break;
}
if( i==pSrcIdx->nColumn ){
idxInsFlags = OPFLAG_USESEEKRESULT;
+1 -5
View File
@@ -410,11 +410,7 @@ static const sqlite3_api_routines sqlite3Apis = {
sqlite3_bind_zeroblob64,
/* Version 3.9.0 and later */
sqlite3_value_subtype,
sqlite3_result_subtype,
/* Version 3.10.0 and later */
sqlite3_status64,
sqlite3_strlike,
sqlite3_db_cacheflush
sqlite3_result_subtype
};
/*
+8 -94
View File
@@ -445,10 +445,9 @@ int sqlite3_config(int op, ...){
break;
}
case SQLITE_CONFIG_PAGECACHE: {
/* EVIDENCE-OF: R-18761-36601 There are three arguments to
** SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned memory (pMem),
** the size of each page cache line (sz), and the number of cache lines
** (N). */
/* EVIDENCE-OF: R-31408-40510 There are three arguments to
** SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned memory, the size
** of each page buffer (sz), and the number of pages (N). */
sqlite3GlobalConfig.pPage = va_arg(ap, void*);
sqlite3GlobalConfig.szPage = va_arg(ap, int);
sqlite3GlobalConfig.nPage = va_arg(ap, int);
@@ -2829,9 +2828,9 @@ static int openDatabase(
** EVIDENCE-OF: R-52786-44878 SQLite defines three built-in collating
** functions:
*/
createCollation(db, sqlite3StrBINARY, SQLITE_UTF8, 0, binCollFunc, 0);
createCollation(db, sqlite3StrBINARY, SQLITE_UTF16BE, 0, binCollFunc, 0);
createCollation(db, sqlite3StrBINARY, SQLITE_UTF16LE, 0, binCollFunc, 0);
createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0);
createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0);
createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0);
createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0);
if( db->mallocFailed ){
@@ -2840,7 +2839,7 @@ static int openDatabase(
/* EVIDENCE-OF: R-08308-17224 The default collating function for all
** strings is BINARY.
*/
db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, sqlite3StrBINARY, 0);
db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0);
assert( db->pDfltColl!=0 );
/* Parse the filename/URI argument. */
@@ -3340,7 +3339,7 @@ int sqlite3_table_column_metadata(
primarykey = 1;
}
if( !zCollSeq ){
zCollSeq = sqlite3StrBINARY;
zCollSeq = "BINARY";
}
error_out:
@@ -3421,9 +3420,6 @@ int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
if( op==SQLITE_FCNTL_FILE_POINTER ){
*(sqlite3_file**)pArg = fd;
rc = SQLITE_OK;
}else if( op==SQLITE_FCNTL_VFS_POINTER ){
*(sqlite3_vfs**)pArg = sqlite3PagerVfs(pPager);
rc = SQLITE_OK;
}else if( fd->pMethods ){
rc = sqlite3OsFileControl(fd, op, pArg);
}else{
@@ -3866,85 +3862,3 @@ int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
pBt = sqlite3DbNameToBtree(db, zDbName);
return pBt ? sqlite3BtreeIsReadonly(pBt) : -1;
}
#ifdef SQLITE_ENABLE_SNAPSHOT
/*
** Obtain a snapshot handle for the snapshot of database zDb currently
** being read by handle db.
*/
int sqlite3_snapshot_get(
sqlite3 *db,
const char *zDb,
sqlite3_snapshot **ppSnapshot
){
int rc = SQLITE_ERROR;
#ifndef SQLITE_OMIT_WAL
int iDb;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
return SQLITE_MISUSE_BKPT;
}
#endif
sqlite3_mutex_enter(db->mutex);
iDb = sqlite3FindDbName(db, zDb);
if( iDb==0 || iDb>1 ){
Btree *pBt = db->aDb[iDb].pBt;
if( 0==sqlite3BtreeIsInTrans(pBt) ){
rc = sqlite3BtreeBeginTrans(pBt, 0);
if( rc==SQLITE_OK ){
rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot);
}
}
}
sqlite3_mutex_leave(db->mutex);
#endif /* SQLITE_OMIT_WAL */
return rc;
}
/*
** Open a read-transaction on the snapshot idendified by pSnapshot.
*/
int sqlite3_snapshot_open(
sqlite3 *db,
const char *zDb,
sqlite3_snapshot *pSnapshot
){
int rc = SQLITE_ERROR;
#ifndef SQLITE_OMIT_WAL
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
return SQLITE_MISUSE_BKPT;
}
#endif
sqlite3_mutex_enter(db->mutex);
if( db->autoCommit==0 ){
int iDb;
iDb = sqlite3FindDbName(db, zDb);
if( iDb==0 || iDb>1 ){
Btree *pBt = db->aDb[iDb].pBt;
if( 0==sqlite3BtreeIsInReadTrans(pBt) ){
rc = sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), pSnapshot);
if( rc==SQLITE_OK ){
rc = sqlite3BtreeBeginTrans(pBt, 0);
sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), 0);
}
}
}
}
sqlite3_mutex_leave(db->mutex);
#endif /* SQLITE_OMIT_WAL */
return rc;
}
/*
** Free a snapshot handle obtained from sqlite3_snapshot_get().
*/
void sqlite3_snapshot_free(sqlite3_snapshot *pSnapshot){
sqlite3_free(pSnapshot);
}
#endif /* SQLITE_ENABLE_SNAPSHOT */
+2 -2
View File
@@ -358,7 +358,7 @@ void sqlite3ScratchFree(void *p){
scratchAllocOut--;
#endif
if( SQLITE_WITHIN(p, sqlite3GlobalConfig.pScratch, mem0.pScratchEnd) ){
if( p>=sqlite3GlobalConfig.pScratch && p<mem0.pScratchEnd ){
/* Release memory from the SQLITE_CONFIG_SCRATCH allocation */
ScratchFreeslot *pSlot;
pSlot = (ScratchFreeslot*)p;
@@ -394,7 +394,7 @@ void sqlite3ScratchFree(void *p){
*/
#ifndef SQLITE_OMIT_LOOKASIDE
static int isLookaside(sqlite3 *db, void *p){
return SQLITE_WITHIN(p, db->lookaside.pStart, db->lookaside.pEnd);
return p>=db->lookaside.pStart && p<db->lookaside.pEnd;
}
#else
#define isLookaside(A,B) 0
+19 -10
View File
@@ -25,7 +25,7 @@
**
** This memory allocator uses the following algorithm:
**
** 1. All memory allocation sizes are rounded up to a power of 2.
** 1. All memory allocations sizes are rounded up to a power of 2.
**
** 2. If two adjacent free blocks are the halves of a larger block,
** then the two blocks are coalesced into the single larger block.
@@ -117,7 +117,7 @@ static SQLITE_WSD struct Mem5Global {
/*
** Lists of free blocks. aiFreelist[0] is a list of free blocks of
** size mem5.szAtom. aiFreelist[1] holds blocks of size szAtom*2.
** aiFreelist[2] holds free blocks of size szAtom*4. And so forth.
** and so forth.
*/
int aiFreelist[LOGMAX+1];
@@ -183,7 +183,9 @@ static void memsys5Link(int i, int iLogsize){
}
/*
** Obtain or release the mutex needed to access global data structures.
** If the STATIC_MEM mutex is not already held, obtain it now. The mutex
** will already be held (obtained by code in malloc.c) if
** sqlite3GlobalConfig.bMemStat is true.
*/
static void memsys5Enter(void){
sqlite3_mutex_enter(mem5.mutex);
@@ -193,8 +195,9 @@ static void memsys5Leave(void){
}
/*
** Return the size of an outstanding allocation, in bytes.
** This only works for chunks that are currently checked out.
** Return the size of an outstanding allocation, in bytes. The
** size returned omits the 8-byte header overhead. This only
** works for chunks that are currently checked out.
*/
static int memsys5Size(void *p){
int iSize, i;
@@ -227,12 +230,16 @@ static void *memsys5MallocUnsafe(int nByte){
/* Keep track of the maximum allocation request. Even unfulfilled
** requests are counted */
if( (u32)nByte>mem5.maxRequest ){
/* Abort if the requested allocation size is larger than the largest
** power of two that we can represent using 32-bit signed integers. */
if( nByte > 0x40000000 ) return 0;
mem5.maxRequest = nByte;
}
/* Abort if the requested allocation size is larger than the largest
** power of two that we can represent using 32-bit signed integers.
*/
if( nByte > 0x40000000 ){
return 0;
}
/* Round nByte up to the next valid power of two */
for(iFullSz=mem5.szAtom,iLogsize=0; iFullSz<nByte; iFullSz*=2,iLogsize++){}
@@ -391,11 +398,13 @@ static void *memsys5Realloc(void *pPrior, int nBytes){
if( nBytes<=nOld ){
return pPrior;
}
p = memsys5Malloc(nBytes);
memsys5Enter();
p = memsys5MallocUnsafe(nBytes);
if( p ){
memcpy(p, pPrior, nOld);
memsys5Free(pPrior);
memsys5FreeUnsafe(pPrior);
}
memsys5Leave();
return p;
}
-2
View File
@@ -51,8 +51,6 @@ struct sqlite3_mutex {
};
#if SQLITE_MUTEX_NREF
#define SQLITE3_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER,0,0,(pthread_t)0,0}
#elif defined(SQLITE_ENABLE_API_ARMOR)
#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0 }
#else
#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }
#endif
+263 -163
View File
@@ -258,6 +258,8 @@ static pid_t randomnessPid = 0;
#define UNIXFILE_DELETE 0x20 /* Delete on close */
#define UNIXFILE_URI 0x40 /* Filename might have query parameters */
#define UNIXFILE_NOLOCK 0x80 /* Do no file locking */
#define UNIXFILE_WARNED 0x0100 /* verifyDbFile() warnings issued */
#define UNIXFILE_BLOCK 0x0200 /* Next SHM lock might block */
/*
** Include code that is common to all os_*.c files
@@ -322,6 +324,19 @@ static int posixOpen(const char *zFile, int flags, int mode){
return open(zFile, flags, mode);
}
/*
** On some systems, calls to fchown() will trigger a message in a security
** log if they come from non-root processes. So avoid calling fchown() if
** we are not running as root.
*/
static int posixFchown(int fd, uid_t uid, gid_t gid){
#if OS_VXWORKS
return 0;
#else
return geteuid() ? 0 : fchown(fd,uid,gid);
#endif
}
/* Forward reference */
static int openDirectory(const char*, int*);
static int unixGetpagesize(void);
@@ -408,7 +423,7 @@ static struct unix_syscall {
#define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\
aSyscall[13].pCurrent)
{ "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
{ "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
#define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent)
#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
@@ -430,50 +445,32 @@ static struct unix_syscall {
{ "rmdir", (sqlite3_syscall_ptr)rmdir, 0 },
#define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent)
{ "fchown", (sqlite3_syscall_ptr)fchown, 0 },
{ "fchown", (sqlite3_syscall_ptr)posixFchown, 0 },
#define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
{ "geteuid", (sqlite3_syscall_ptr)geteuid, 0 },
#define osGeteuid ((uid_t(*)(void))aSyscall[21].pCurrent)
#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
{ "mmap", (sqlite3_syscall_ptr)mmap, 0 },
#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[22].pCurrent)
#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[21].pCurrent)
{ "munmap", (sqlite3_syscall_ptr)munmap, 0 },
#define osMunmap ((void*(*)(void*,size_t))aSyscall[23].pCurrent)
#define osMunmap ((void*(*)(void*,size_t))aSyscall[22].pCurrent)
#if HAVE_MREMAP
{ "mremap", (sqlite3_syscall_ptr)mremap, 0 },
#else
{ "mremap", (sqlite3_syscall_ptr)0, 0 },
#endif
#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[24].pCurrent)
#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent)
{ "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 },
#define osGetpagesize ((int(*)(void))aSyscall[25].pCurrent)
#define osGetpagesize ((int(*)(void))aSyscall[24].pCurrent)
{ "readlink", (sqlite3_syscall_ptr)readlink, 0 },
#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[26].pCurrent)
#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[25].pCurrent)
#endif
}; /* End of the overrideable system calls */
/*
** On some systems, calls to fchown() will trigger a message in a security
** log if they come from non-root processes. So avoid calling fchown() if
** we are not running as root.
*/
static int robustFchown(int fd, uid_t uid, gid_t gid){
#if OS_VXWORKS
return 0;
#else
return osGeteuid() ? 0 : osFchown(fd,uid,gid);
#endif
}
/*
** This is the xSetSystemCall() method of sqlite3_vfs for all of the
** "unix" VFSes. Return SQLITE_OK opon successfully updating the
@@ -758,12 +755,23 @@ static int robust_ftruncate(int h, sqlite3_int64 sz){
** should handle ENOLCK, ENOTSUP, EOPNOTSUPP separately.
*/
static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {
assert( (sqliteIOErr == SQLITE_IOERR_LOCK) ||
(sqliteIOErr == SQLITE_IOERR_UNLOCK) ||
(sqliteIOErr == SQLITE_IOERR_RDLOCK) ||
(sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) );
switch (posixError) {
case EACCES:
#if 0
/* At one point this code was not commented out. In theory, this branch
** should never be hit, as this function should only be called after
** a locking-related function (i.e. fcntl()) has returned non-zero with
** the value of errno as the first argument. Since a system call has failed,
** errno should be non-zero.
**
** Despite this, if errno really is zero, we still don't want to return
** SQLITE_OK. The system call failed, and *some* SQLite error should be
** propagated back to the caller. Commenting this branch out means errno==0
** will be handled by the "default:" case below.
*/
case 0:
return SQLITE_OK;
#endif
case EAGAIN:
case ETIMEDOUT:
case EBUSY:
@@ -773,9 +781,41 @@ static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {
* introspection, in which it actually means what it says */
return SQLITE_BUSY;
case EACCES:
/* EACCES is like EAGAIN during locking operations, but not any other time*/
if( (sqliteIOErr == SQLITE_IOERR_LOCK) ||
(sqliteIOErr == SQLITE_IOERR_UNLOCK) ||
(sqliteIOErr == SQLITE_IOERR_RDLOCK) ||
(sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ){
return SQLITE_BUSY;
}
/* else fall through */
case EPERM:
return SQLITE_PERM;
#if EOPNOTSUPP!=ENOTSUP
case EOPNOTSUPP:
/* something went terribly awry, unless during file system support
* introspection, in which it actually means what it says */
#endif
#ifdef ENOTSUP
case ENOTSUP:
/* invalid fd, unless during file system support introspection, in which
* it actually means what it says */
#endif
case EIO:
case EBADF:
case EINVAL:
case ENOTCONN:
case ENODEV:
case ENXIO:
case ENOENT:
#ifdef ESTALE /* ESTALE is not defined on Interix systems */
case ESTALE:
#endif
case ENOSYS:
/* these should force the client to close the file and reconnect */
default:
return sqliteIOErr;
}
@@ -1059,7 +1099,7 @@ static unixInodeInfo *inodeList = 0;
/*
**
** This function - unixLogErrorAtLine(), is only ever called via the macro
** This function - unixLogError_x(), is only ever called via the macro
** unixLogError().
**
** It is invoked after an error occurs in an OS function and errno has been
@@ -1228,7 +1268,7 @@ static int findInodeInfo(
rc = osFstat(fd, &statbuf);
if( rc!=0 ){
storeLastErrno(pFile, errno);
#if defined(EOVERFLOW) && defined(SQLITE_DISABLE_LFS)
#ifdef EOVERFLOW
if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS;
#endif
return SQLITE_IOERR;
@@ -1315,21 +1355,30 @@ static int fileHasMoved(unixFile *pFile){
static void verifyDbFile(unixFile *pFile){
struct stat buf;
int rc;
if( pFile->ctrlFlags & UNIXFILE_WARNED ){
/* One or more of the following warnings have already been issued. Do not
** repeat them so as not to clutter the error log */
return;
}
rc = osFstat(pFile->h, &buf);
if( rc!=0 ){
sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath);
pFile->ctrlFlags |= UNIXFILE_WARNED;
return;
}
if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){
sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath);
pFile->ctrlFlags |= UNIXFILE_WARNED;
return;
}
if( buf.st_nlink>1 ){
sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath);
pFile->ctrlFlags |= UNIXFILE_WARNED;
return;
}
if( fileHasMoved(pFile) ){
sqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath);
pFile->ctrlFlags |= UNIXFILE_WARNED;
return;
}
}
@@ -1349,7 +1398,6 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
assert( pFile );
assert( pFile->eFileLock<=SHARED_LOCK );
unixEnterMutex(); /* Because pFile->pInode is shared across threads */
/* Check if a thread in this process holds such a lock */
@@ -1406,7 +1454,9 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){
unixInodeInfo *pInode = pFile->pInode;
assert( unixMutexHeld() );
assert( pInode!=0 );
if( (pFile->ctrlFlags & (UNIXFILE_EXCL|UNIXFILE_RDONLY))==UNIXFILE_EXCL ){
if( ((pFile->ctrlFlags & UNIXFILE_EXCL)!=0 || pInode->bProcessLock)
&& ((pFile->ctrlFlags & UNIXFILE_RDONLY)==0)
){
if( pInode->bProcessLock==0 ){
struct flock lock;
assert( pInode->nLock==0 );
@@ -1758,7 +1808,9 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
if( unixFileLock(pFile, &lock)==(-1) ){
tErrno = errno;
rc = SQLITE_IOERR_UNLOCK;
storeLastErrno(pFile, tErrno);
if( IS_LOCK_ERROR(rc) ){
storeLastErrno(pFile, tErrno);
}
goto end_unlock;
}
lock.l_type = F_RDLCK;
@@ -1780,7 +1832,9 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
if( unixFileLock(pFile, &lock)==(-1) ){
tErrno = errno;
rc = SQLITE_IOERR_UNLOCK;
storeLastErrno(pFile, tErrno);
if( IS_LOCK_ERROR(rc) ){
storeLastErrno(pFile, tErrno);
}
goto end_unlock;
}
}else
@@ -2031,7 +2085,17 @@ static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) {
SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
assert( pFile );
reserved = osAccess((const char*)pFile->lockingContext, 0)==0;
/* Check if a thread in this process holds such a lock */
if( pFile->eFileLock>SHARED_LOCK ){
/* Either this connection or some other connection in the same process
** holds a lock on the file. No need to check further. */
reserved = 1;
}else{
/* The lock is held if and only if the lockfile exists */
const char *zLockFile = (const char*)pFile->lockingContext;
reserved = osAccess(zLockFile, 0)==0;
}
OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved));
*pResOut = reserved;
return rc;
@@ -2093,7 +2157,7 @@ static int dotlockLock(sqlite3_file *id, int eFileLock) {
rc = SQLITE_BUSY;
} else {
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
if( rc!=SQLITE_BUSY ){
if( IS_LOCK_ERROR(rc) ){
storeLastErrno(pFile, tErrno);
}
}
@@ -2140,12 +2204,14 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
/* To fully unlock the database, delete the lock file */
assert( eFileLock==NO_LOCK );
rc = osRmdir(zLockFile);
if( rc<0 && errno==ENOTDIR ) rc = osUnlink(zLockFile);
if( rc<0 ){
int tErrno = errno;
if( tErrno==ENOENT ){
rc = SQLITE_OK;
}else{
rc = 0;
if( ENOENT != tErrno ){
rc = SQLITE_IOERR_UNLOCK;
}
if( IS_LOCK_ERROR(rc) ){
storeLastErrno(pFile, tErrno);
}
return rc;
@@ -2158,11 +2224,14 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
** Close a file. Make sure the lock has been released before closing.
*/
static int dotlockClose(sqlite3_file *id) {
unixFile *pFile = (unixFile*)id;
assert( id!=0 );
dotlockUnlock(id, NO_LOCK);
sqlite3_free(pFile->lockingContext);
return closeUnixFile(id);
int rc = SQLITE_OK;
if( id ){
unixFile *pFile = (unixFile*)id;
dotlockUnlock(id, NO_LOCK);
sqlite3_free(pFile->lockingContext);
rc = closeUnixFile(id);
}
return rc;
}
/****************** End of the dot-file lock implementation *******************
******************************************************************************/
@@ -2228,8 +2297,10 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
int tErrno = errno;
/* unlock failed with an error */
lrc = SQLITE_IOERR_UNLOCK;
storeLastErrno(pFile, tErrno);
rc = lrc;
if( IS_LOCK_ERROR(lrc) ){
storeLastErrno(pFile, tErrno);
rc = lrc;
}
}
} else {
int tErrno = errno;
@@ -2362,9 +2433,12 @@ static int flockUnlock(sqlite3_file *id, int eFileLock) {
** Close a file.
*/
static int flockClose(sqlite3_file *id) {
assert( id!=0 );
flockUnlock(id, NO_LOCK);
return closeUnixFile(id);
int rc = SQLITE_OK;
if( id ){
flockUnlock(id, NO_LOCK);
rc = closeUnixFile(id);
}
return rc;
}
#endif /* SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORK */
@@ -2989,22 +3063,23 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) {
*/
static int afpClose(sqlite3_file *id) {
int rc = SQLITE_OK;
unixFile *pFile = (unixFile*)id;
assert( id!=0 );
afpUnlock(id, NO_LOCK);
unixEnterMutex();
if( pFile->pInode && pFile->pInode->nLock ){
/* If there are outstanding locks, do not actually close the file just
** yet because that would clear those locks. Instead, add the file
** descriptor to pInode->aPending. It will be automatically closed when
** the last lock is cleared.
*/
setPendingFd(pFile);
if( id ){
unixFile *pFile = (unixFile*)id;
afpUnlock(id, NO_LOCK);
unixEnterMutex();
if( pFile->pInode && pFile->pInode->nLock ){
/* If there are outstanding locks, do not actually close the file just
** yet because that would clear those locks. Instead, add the file
** descriptor to pInode->aPending. It will be automatically closed when
** the last lock is cleared.
*/
setPendingFd(pFile);
}
releaseInodeInfo(pFile);
sqlite3_free(pFile->lockingContext);
rc = closeUnixFile(id);
unixLeaveMutex();
}
releaseInodeInfo(pFile);
sqlite3_free(pFile->lockingContext);
rc = closeUnixFile(id);
unixLeaveMutex();
return rc;
}
@@ -3083,9 +3158,13 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
SimulateIOError( got = -1 );
#else
newOffset = lseek(id->h, offset, SEEK_SET);
SimulateIOError( newOffset = -1 );
if( newOffset<0 ){
storeLastErrno((unixFile*)id, errno);
SimulateIOError( newOffset-- );
if( newOffset!=offset ){
if( newOffset == -1 ){
storeLastErrno((unixFile*)id, errno);
}else{
storeLastErrno((unixFile*)id, 0);
}
return -1;
}
got = osRead(id->h, pBuf, cnt);
@@ -3184,7 +3263,6 @@ static int seekAndWriteFd(
assert( nBuf==(nBuf&0x1ffff) );
assert( fd>2 );
assert( piErrno!=0 );
nBuf &= 0x1ffff;
TIMER_START;
@@ -3195,10 +3273,11 @@ static int seekAndWriteFd(
#else
do{
i64 iSeek = lseek(fd, iOff, SEEK_SET);
SimulateIOError( iSeek = -1 );
if( iSeek<0 ){
rc = -1;
break;
SimulateIOError( iSeek-- );
if( iSeek!=iOff ){
if( piErrno ) *piErrno = (iSeek==-1 ? errno : 0);
return -1;
}
rc = osWrite(fd, pBuf, nBuf);
}while( rc<0 && errno==EINTR );
@@ -3207,7 +3286,7 @@ static int seekAndWriteFd(
TIMER_END;
OSTRACE(("WRITE %-3d %5d %7lld %llu\n", fd, rc, iOff, TIMER_ELAPSED));
if( rc<0 ) *piErrno = errno;
if( rc<0 && piErrno ) *piErrno = errno;
return rc;
}
@@ -3391,15 +3470,10 @@ static int full_fsync(int fd, int fullSync, int dataOnly){
#endif
/* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
** no-op. But go ahead and call fstat() to validate the file
** descriptor as we need a method to provoke a failure during
** coverate testing.
** no-op
*/
#ifdef SQLITE_NO_SYNC
{
struct stat buf;
rc = osFstat(fd, &buf);
}
rc = SQLITE_OK;
#elif HAVE_FULLFSYNC
if( fullSync ){
rc = osFcntl(fd, F_FULLFSYNC, 0);
@@ -3465,20 +3539,16 @@ static int openDirectory(const char *zFilename, int *pFd){
char zDirname[MAX_PATHNAME+1];
sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename);
for(ii=(int)strlen(zDirname); ii>0 && zDirname[ii]!='/'; ii--);
for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--);
if( ii>0 ){
zDirname[ii] = '\0';
}else{
if( zDirname[0]!='/' ) zDirname[0] = '.';
zDirname[1] = 0;
}
fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
if( fd>=0 ){
OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
if( fd>=0 ){
OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
}
}
*pFd = fd;
if( fd>=0 ) return SQLITE_OK;
return unixLogError(SQLITE_CANTOPEN_BKPT, "openDirectory", zDirname);
return (fd>=0?SQLITE_OK:unixLogError(SQLITE_CANTOPEN_BKPT, "open", zDirname));
}
/*
@@ -3531,11 +3601,10 @@ static int unixSync(sqlite3_file *id, int flags){
OSTRACE(("DIRSYNC %s (have_fullfsync=%d fullsync=%d)\n", pFile->zPath,
HAVE_FULLFSYNC, isFullsync));
rc = osOpenDirectory(pFile->zPath, &dirfd);
if( rc==SQLITE_OK ){
if( rc==SQLITE_OK && dirfd>=0 ){
full_fsync(dirfd, 0, 0);
robust_close(pFile, dirfd, __LINE__);
}else{
assert( rc==SQLITE_CANTOPEN );
}else if( rc==SQLITE_CANTOPEN ){
rc = SQLITE_OK;
}
pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC;
@@ -3667,14 +3736,18 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
int nWrite = 0; /* Number of bytes written by seekAndWrite */
i64 iWrite; /* Next offset to write to */
iWrite = (buf.st_size/nBlk)*nBlk + nBlk - 1;
iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1;
assert( iWrite>=buf.st_size );
assert( (iWrite/nBlk)==((buf.st_size+nBlk-1)/nBlk) );
assert( ((iWrite+1)%nBlk)==0 );
for(/*no-op*/; iWrite<nSize+nBlk-1; iWrite+=nBlk ){
if( iWrite>=nSize ) iWrite = nSize - 1;
for(/*no-op*/; iWrite<nSize; iWrite+=nBlk ){
nWrite = seekAndWrite(pFile, iWrite, "", 1);
if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
}
if( nWrite==0 || (nSize%nBlk) ){
nWrite = seekAndWrite(pFile, nSize-1, "", 1);
if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
}
#endif
}
}
@@ -3722,6 +3795,10 @@ static int unixGetTempname(int nBuf, char *zBuf);
static int unixFileControl(sqlite3_file *id, int op, void *pArg){
unixFile *pFile = (unixFile*)id;
switch( op ){
case SQLITE_FCNTL_WAL_BLOCK: {
/* pFile->ctrlFlags |= UNIXFILE_BLOCK; // Deferred feature */
return SQLITE_OK;
}
case SQLITE_FCNTL_LOCKSTATE: {
*(int*)pArg = pFile->eFileLock;
return SQLITE_OK;
@@ -4048,9 +4125,10 @@ static int unixShmSystemLock(
assert( n==1 || lockType!=F_RDLCK );
/* Locks are within range */
assert( n>=1 && n<=SQLITE_SHM_NLOCK );
assert( n>=1 && n<SQLITE_SHM_NLOCK );
if( pShmNode->h>=0 ){
int lkType;
/* Initialize the locking parameters */
memset(&f, 0, sizeof(f));
f.l_type = lockType;
@@ -4058,8 +4136,10 @@ static int unixShmSystemLock(
f.l_start = ofst;
f.l_len = n;
rc = osFcntl(pShmNode->h, F_SETLK, &f);
lkType = (pFile->ctrlFlags & UNIXFILE_BLOCK)!=0 ? F_SETLKW : F_SETLK;
rc = osFcntl(pShmNode->h, lkType, &f);
rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
pFile->ctrlFlags &= ~UNIXFILE_BLOCK;
}
/* Update the global lock state and do debug tracing */
@@ -4126,7 +4206,7 @@ static int unixShmRegionPerMap(void){
static void unixShmPurge(unixFile *pFd){
unixShmNode *p = pFd->pInode->pShmNode;
assert( unixMutexHeld() );
if( p && ALWAYS(p->nRef==0) ){
if( p && p->nRef==0 ){
int nShmPerMap = unixShmRegionPerMap();
int i;
assert( p->pInode==pFd->pInode );
@@ -4213,7 +4293,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
** a new *-shm file is created, an attempt will be made to create it
** with the same permissions.
*/
if( osFstat(pDbFd->h, &sStat) ){
if( osFstat(pDbFd->h, &sStat) && pInode->bProcessLock==0 ){
rc = SQLITE_IOERR_FSTAT;
goto shm_open_err;
}
@@ -4263,7 +4343,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
** is owned by the same user that owns the original database. Otherwise,
** the original owner will not be able to connect.
*/
robustFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
osFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
/* Check to see if another process is holding the dead-man switch.
** If not, truncate the file to zero length.
@@ -4400,8 +4480,7 @@ static int unixShmMap(
/* Write to the last byte of each newly allocated or extended page */
assert( (nByte % pgsz)==0 );
for(iPg=(sStat.st_size/pgsz); iPg<(nByte/pgsz); iPg++){
int x = 0;
if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, &x)!=1 ){
if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, 0)!=1 ){
const char *zFile = pShmNode->zFilename;
rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile);
goto shmpage_out;
@@ -4769,14 +4848,17 @@ static void unixRemapfile(
** recreated as a result of outstanding references) or an SQLite error
** code otherwise.
*/
static int unixMapfile(unixFile *pFd, i64 nMap){
static int unixMapfile(unixFile *pFd, i64 nByte){
i64 nMap = nByte;
int rc;
assert( nMap>=0 || pFd->nFetchOut==0 );
assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) );
if( pFd->nFetchOut>0 ) return SQLITE_OK;
if( nMap<0 ){
struct stat statbuf; /* Low-level file information */
if( osFstat(pFd->h, &statbuf) ){
rc = osFstat(pFd->h, &statbuf);
if( rc!=SQLITE_OK ){
return SQLITE_IOERR_FSTAT;
}
nMap = statbuf.st_size;
@@ -4785,9 +4867,12 @@ static int unixMapfile(unixFile *pFd, i64 nMap){
nMap = pFd->mmapSizeMax;
}
assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) );
if( nMap!=pFd->mmapSize ){
unixRemapfile(pFd, nMap);
if( nMap>0 ){
unixRemapfile(pFd, nMap);
}else{
unixUnmapfile(pFd);
}
}
return SQLITE_OK;
@@ -5356,19 +5441,21 @@ static int fillInUnixFile(
*/
static const char *unixTempFileDir(void){
static const char *azDirs[] = {
0,
0,
0,
"/var/tmp",
"/usr/tmp",
"/tmp",
"."
0 /* List terminator */
};
unsigned int i;
struct stat buf;
const char *zDir = sqlite3_temp_directory;
const char *zDir = 0;
if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR");
if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
azDirs[0] = sqlite3_temp_directory;
if( !azDirs[1] ) azDirs[1] = getenv("SQLITE_TMPDIR");
if( !azDirs[2] ) azDirs[2] = getenv("TMPDIR");
for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
if( zDir==0 ) continue;
if( osStat(zDir, &buf) ) continue;
@@ -5385,8 +5472,12 @@ static const char *unixTempFileDir(void){
** pVfs->mxPathname bytes.
*/
static int unixGetTempname(int nBuf, char *zBuf){
static const unsigned char zChars[] =
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789";
unsigned int i, j;
const char *zDir;
int iLimit = 0;
/* It's odd to simulate an io-error here, but really this is just
** using the io-error infrastructure to test that SQLite handles this
@@ -5395,14 +5486,24 @@ static int unixGetTempname(int nBuf, char *zBuf){
SimulateIOError( return SQLITE_IOERR );
zDir = unixTempFileDir();
if( zDir==0 ) zDir = ".";
/* Check that the output buffer is large enough for the temporary file
** name. If it is not, return SQLITE_ERROR.
*/
if( (strlen(zDir) + strlen(SQLITE_TEMP_FILE_PREFIX) + 18) >= (size_t)nBuf ){
return SQLITE_ERROR;
}
do{
u64 r;
sqlite3_randomness(sizeof(r), &r);
assert( nBuf>2 );
zBuf[nBuf-2] = 0;
sqlite3_snprintf(nBuf, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX"%llx%c",
zDir, r, 0);
if( zBuf[nBuf-2]!=0 || (iLimit++)>10 ) return SQLITE_ERROR;
sqlite3_snprintf(nBuf-18, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir);
j = (int)strlen(zBuf);
sqlite3_randomness(15, &zBuf[j]);
for(i=0; i<15; i++, j++){
zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
}
zBuf[j] = 0;
zBuf[j+1] = 0;
}while( osAccess(zBuf,0)==0 );
return SQLITE_OK;
}
@@ -5524,19 +5625,16 @@ static int findCreateFileMode(
** used by the test_multiplex.c module.
*/
nDb = sqlite3Strlen30(zPath) - 1;
while( zPath[nDb]!='-' ){
#ifndef SQLITE_ENABLE_8_3_NAMES
/* In the normal case (8+3 filenames disabled) the journal filename
** is guaranteed to contain a '-' character. */
assert( nDb>0 );
assert( sqlite3Isalnum(zPath[nDb]) );
#ifdef SQLITE_ENABLE_8_3_NAMES
while( nDb>0 && sqlite3Isalnum(zPath[nDb]) ) nDb--;
if( nDb==0 || zPath[nDb]!='-' ) return SQLITE_OK;
#else
/* If 8+3 names are possible, then the journal file might not contain
** a '-' character. So check for that case and return early. */
if( nDb==0 || zPath[nDb]=='.' ) return SQLITE_OK;
#endif
while( zPath[nDb]!='-' ){
assert( nDb>0 );
assert( zPath[nDb]!='\n' );
nDb--;
}
#endif
memcpy(zDb, zPath, nDb);
zDb[nDb] = '\0';
@@ -5677,7 +5775,7 @@ static int unixOpen(
}else if( !zName ){
/* If zName is NULL, the upper layer is requesting a temp file. */
assert(isDelete && !syncDir);
rc = unixGetTempname(pVfs->mxPathname, zTmpname);
rc = unixGetTempname(MAX_PATHNAME+2, zTmpname);
if( rc!=SQLITE_OK ){
return rc;
}
@@ -5710,8 +5808,7 @@ static int unixOpen(
}
fd = robust_open(zName, openFlags, openMode);
OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags));
assert( !isExclusive || (openFlags & O_CREAT)!=0 );
if( fd<0 && errno!=EISDIR && isReadWrite ){
if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){
/* Failed to open the file for read/write access. Try read-only. */
flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
openFlags &= ~(O_RDWR|O_CREAT);
@@ -5730,7 +5827,7 @@ static int unixOpen(
** the same as the original database.
*/
if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
robustFchown(fd, uid, gid);
osFchown(fd, uid, gid);
}
}
assert( fd>=0 );
@@ -5867,8 +5964,7 @@ static int unixDelete(
rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath);
}
robust_close(0, fd, __LINE__);
}else{
assert( rc==SQLITE_CANTOPEN );
}else if( rc==SQLITE_CANTOPEN ){
rc = SQLITE_OK;
}
}
@@ -5892,19 +5988,29 @@ static int unixAccess(
int flags, /* What do we want to learn about the zPath file? */
int *pResOut /* Write result boolean here */
){
int amode = 0;
UNUSED_PARAMETER(NotUsed);
SimulateIOError( return SQLITE_IOERR_ACCESS; );
assert( pResOut!=0 );
switch( flags ){
case SQLITE_ACCESS_EXISTS:
amode = F_OK;
break;
case SQLITE_ACCESS_READWRITE:
amode = W_OK|R_OK;
break;
case SQLITE_ACCESS_READ:
amode = R_OK;
break;
/* The spec says there are three possible values for flags. But only
** two of them are actually used */
assert( flags==SQLITE_ACCESS_EXISTS || flags==SQLITE_ACCESS_READWRITE );
if( flags==SQLITE_ACCESS_EXISTS ){
default:
assert(!"Invalid flags argument");
}
*pResOut = (osAccess(zPath, amode)==0);
if( flags==SQLITE_ACCESS_EXISTS && *pResOut ){
struct stat buf;
*pResOut = (0==osStat(zPath, &buf) && buf.st_size>0);
}else{
*pResOut = osAccess(zPath, W_OK|R_OK)==0;
if( 0==osStat(zPath, &buf) && buf.st_size==0 ){
*pResOut = 0;
}
}
return SQLITE_OK;
}
@@ -5947,7 +6053,8 @@ static int unixFullPathname(
if( errno!=EINVAL && errno!=ENOENT ){
return unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zPath);
}
sqlite3_snprintf(nOut, zOut, "%s", zPath);
zOut[nOut-1] = '\0';
sqlite3_snprintf(nOut-1, zOut, "%s", zPath);
nByte = sqlite3Strlen30(zOut);
}else{
zOut[nByte] = '\0';
@@ -5969,9 +6076,7 @@ static int unixFullPathname(
** truncated to make it fit. This is Ok, as SQLite refuses to open any
** file for which this function returns a full path larger than (nOut-8)
** bytes in size. */
testcase( nByte==nOut-5 );
testcase( nByte==nOut-4 );
if( zOut[0]!='/' && nByte<nOut-4 ){
if( zOut[0]!='/' ){
int nCwd;
int nRem = nOut-nByte-1;
memmove(&zOut[nRem], zOut, nByte+1);
@@ -6154,8 +6259,11 @@ static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){
*piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_nsec/1000000;
#else
struct timeval sNow;
(void)gettimeofday(&sNow, 0); /* Cannot fail given valid arguments */
*piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000;
if( gettimeofday(&sNow, 0)==0 ){
*piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000;
}else{
rc = SQLITE_ERROR;
}
#endif
#ifdef SQLITE_TEST
@@ -6167,7 +6275,6 @@ static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){
return rc;
}
#if 0 /* Not used */
/*
** Find the current time (in Universal Coordinated Time). Write the
** current time and date as a Julian Day number into *prNow and
@@ -6181,11 +6288,7 @@ static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){
*prNow = i/86400000.0;
return rc;
}
#else
# define unixCurrentTime 0
#endif
#if 0 /* Not used */
/*
** We added the xGetLastError() method with the intention of providing
** better low-level error messages when operating-system problems come up
@@ -6199,9 +6302,6 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
UNUSED_PARAMETER(NotUsed3);
return 0;
}
#else
# define unixGetLastError 0
#endif
/*
@@ -7340,7 +7440,7 @@ static int proxyUnlock(sqlite3_file *id, int eFileLock) {
** Close a file that uses proxy locks.
*/
static int proxyClose(sqlite3_file *id) {
if( ALWAYS(id) ){
if( id ){
unixFile *pFile = (unixFile*)id;
proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
unixFile *lockProxy = pCtx->lockProxy;
@@ -7484,7 +7584,7 @@ int sqlite3_os_init(void){
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
assert( ArraySize(aSyscall)==27 );
assert( ArraySize(aSyscall)==26 );
/* Register all VFSes defined in the aVfs[] array */
for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
+1 -29
View File
@@ -6679,7 +6679,7 @@ const char *sqlite3PagerFilename(Pager *pPager, int nullIfMemDb){
/*
** Return the VFS structure for the pager.
*/
sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){
const sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){
return pPager->pVfs;
}
@@ -7301,34 +7301,6 @@ int sqlite3PagerCloseWal(Pager *pPager){
return rc;
}
#ifdef SQLITE_ENABLE_SNAPSHOT
/*
** If this is a WAL database, obtain a snapshot handle for the snapshot
** currently open. Otherwise, return an error.
*/
int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot){
int rc = SQLITE_ERROR;
if( pPager->pWal ){
rc = sqlite3WalSnapshotGet(pPager->pWal, ppSnapshot);
}
return rc;
}
/*
** If this is a WAL database, store a pointer to pSnapshot. Next time a
** read transaction is opened, attempt to read from the snapshot it
** identifies. If this is not a WAL database, return an error.
*/
int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot){
int rc = SQLITE_OK;
if( pPager->pWal ){
sqlite3WalSnapshotOpen(pPager->pWal, pSnapshot);
}else{
rc = SQLITE_ERROR;
}
return rc;
}
#endif /* SQLITE_ENABLE_SNAPSHOT */
#endif /* !SQLITE_OMIT_WAL */
#ifdef SQLITE_ENABLE_ZIPVFS
+1 -5
View File
@@ -168,10 +168,6 @@ int sqlite3PagerSharedLock(Pager *pPager);
int sqlite3PagerWalCallback(Pager *pPager);
int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
int sqlite3PagerCloseWal(Pager *pPager);
# ifdef SQLITE_ENABLE_SNAPSHOT
int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
# endif
#endif
#ifdef SQLITE_ENABLE_ZIPVFS
@@ -186,7 +182,7 @@ u32 sqlite3PagerDataVersion(Pager*);
#endif
int sqlite3PagerMemUsed(Pager*);
const char *sqlite3PagerFilename(Pager*, int);
sqlite3_vfs *sqlite3PagerVfs(Pager*);
const sqlite3_vfs *sqlite3PagerVfs(Pager*);
sqlite3_file *sqlite3PagerFile(Pager*);
const char *sqlite3PagerJournalname(Pager*);
int sqlite3PagerNosync(Pager*);
+2 -2
View File
@@ -65,7 +65,7 @@
** that is allocated when the page cache is created. The size of the local
** bulk allocation can be adjusted using
**
** sqlite3_config(SQLITE_CONFIG_PAGECACHE, (void*)0, 0, N).
** sqlite3_config(SQLITE_CONFIG_PAGECACHE, 0, 0, N).
**
** If N is positive, then N pages worth of memory are allocated using a single
** sqlite3Malloc() call and that memory is used for the first N pages allocated.
@@ -350,7 +350,7 @@ static void *pcache1Alloc(int nByte){
static void pcache1Free(void *p){
int nFreed = 0;
if( p==0 ) return;
if( SQLITE_WITHIN(p, pcache1.pStart, pcache1.pEnd) ){
if( p>=pcache1.pStart && p<pcache1.pEnd ){
PgFreeslot *pSlot;
sqlite3_mutex_enter(pcache1.mutex);
sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_USED, 1);
+1 -1
View File
@@ -308,7 +308,7 @@ static const struct sPragmaNames {
/* ePragFlag: */ 0,
/* iArg: */ 0 },
#endif
#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_PARSER_TRACE)
#if defined(SQLITE_DEBUG)
{ /* zName: */ "parser_trace",
/* ePragTyp: */ PragTyp_PARSER_TRACE,
/* ePragFlag: */ 0,
+4 -27
View File
@@ -270,12 +270,6 @@ void sqlite3VXPrintf(
testcase( wx>0x7fffffff );
width = wx & 0x7fffffff;
}
assert( width>=0 );
#ifdef SQLITE_PRINTF_PRECISION_LIMIT
if( width>SQLITE_PRINTF_PRECISION_LIMIT ){
width = SQLITE_PRINTF_PRECISION_LIMIT;
}
#endif
/* Get the precision */
if( c=='.' ){
@@ -302,14 +296,6 @@ void sqlite3VXPrintf(
}else{
precision = -1;
}
assert( precision>=(-1) );
#ifdef SQLITE_PRINTF_PRECISION_LIMIT
if( precision>SQLITE_PRINTF_PRECISION_LIMIT ){
precision = SQLITE_PRINTF_PRECISION_LIMIT;
}
#endif
/* Get the conversion type modifier */
if( c=='l' ){
flag_long = 1;
@@ -766,9 +752,8 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
setStrAccumError(p, STRACCUM_TOOBIG);
return N;
}else{
char *zOld = p->bMalloced ? p->zText : 0;
char *zOld = (p->zText==p->zBase ? 0 : p->zText);
i64 szNew = p->nChar;
assert( (p->zText==0 || p->zText==p->zBase)==(p->bMalloced==0) );
szNew += N + 1;
if( szNew+p->nChar<=p->mxAlloc ){
/* Force exponential buffer size growth as long as it does not overflow,
@@ -789,10 +774,9 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
}
if( zNew ){
assert( p->zText!=0 || p->nChar==0 );
if( !p->bMalloced && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
p->zText = zNew;
p->nAlloc = sqlite3DbMallocSize(p->db, zNew);
p->bMalloced = 1;
}else{
sqlite3StrAccumReset(p);
setStrAccumError(p, STRACCUM_NOMEM);
@@ -810,7 +794,6 @@ void sqlite3AppendChar(StrAccum *p, int N, char c){
if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){
return;
}
assert( (p->zText==p->zBase)==(p->bMalloced==0) );
while( (N--)>0 ) p->zText[p->nChar++] = c;
}
@@ -828,7 +811,6 @@ static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){
memcpy(&p->zText[p->nChar], z, N);
p->nChar += N;
}
assert( (p->zText==0 || p->zText==p->zBase)==(p->bMalloced==0) );
}
/*
@@ -864,13 +846,11 @@ void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){
*/
char *sqlite3StrAccumFinish(StrAccum *p){
if( p->zText ){
assert( (p->zText==p->zBase)==(p->bMalloced==0) );
p->zText[p->nChar] = 0;
if( p->mxAlloc>0 && p->bMalloced==0 ){
if( p->mxAlloc>0 && p->zText==p->zBase ){
p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
if( p->zText ){
memcpy(p->zText, p->zBase, p->nChar+1);
p->bMalloced = 1;
}else{
setStrAccumError(p, STRACCUM_NOMEM);
}
@@ -883,10 +863,8 @@ char *sqlite3StrAccumFinish(StrAccum *p){
** Reset an StrAccum string. Reclaim all malloced memory.
*/
void sqlite3StrAccumReset(StrAccum *p){
assert( (p->zText==0 || p->zText==p->zBase)==(p->bMalloced==0) );
if( p->bMalloced ){
if( p->zText!=p->zBase ){
sqlite3DbFree(p->db, p->zText);
p->bMalloced = 0;
}
p->zText = 0;
}
@@ -912,7 +890,6 @@ void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){
p->nAlloc = n;
p->mxAlloc = mx;
p->accError = 0;
p->bMalloced = 0;
}
/*
+2 -1
View File
@@ -328,6 +328,7 @@ static int lookupName(
}
if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && VisibleRowid(pTab) ){
/* IMP: R-51414-32910 */
/* IMP: R-44911-55124 */
iCol = -1;
}
if( iCol<pTab->nCol ){
@@ -362,7 +363,7 @@ static int lookupName(
&& VisibleRowid(pMatch->pTab)
){
cnt = 1;
pExpr->iColumn = -1;
pExpr->iColumn = -1; /* IMP: R-44911-55124 */
pExpr->affinity = SQLITE_AFF_INTEGER;
}
+6 -11
View File
@@ -1340,8 +1340,7 @@ static const char *columnTypeImpl(
char const *zOrigCol = 0;
#endif
assert( pExpr!=0 );
assert( pNC->pSrcList!=0 );
if( NEVER(pExpr==0) || pNC->pSrcList==0 ) return 0;
switch( pExpr->op ){
case TK_AGG_COLUMN:
case TK_COLUMN: {
@@ -1529,9 +1528,7 @@ static void generateColumnNames(
}
#endif
if( pParse->colNamesSet || db->mallocFailed ) return;
assert( v!=0 );
assert( pTabList!=0 );
if( pParse->colNamesSet || NEVER(v==0) || db->mallocFailed ) return;
pParse->colNamesSet = 1;
fullNames = (db->flags & SQLITE_FullColNames)!=0;
shortNames = (db->flags & SQLITE_ShortColNames)!=0;
@@ -1543,7 +1540,7 @@ static void generateColumnNames(
if( pEList->a[i].zName ){
char *zName = pEList->a[i].zName;
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
}else if( p->op==TK_COLUMN || p->op==TK_AGG_COLUMN ){
}else if( (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN) && pTabList ){
Table *pTab;
char *zCol;
int iCol = p->iColumn;
@@ -1616,7 +1613,6 @@ int sqlite3ColumnsFromExprList(
nCol = 0;
aCol = 0;
}
assert( nCol==(i16)nCol );
*pnCol = nCol;
*paCol = aCol;
@@ -2372,7 +2368,7 @@ static int multiSelect(
if( dest.eDest==SRT_Output ){
Select *pFirst = p;
while( pFirst->pPrior ) pFirst = pFirst->pPrior;
generateColumnNames(pParse, pFirst->pSrc, pFirst->pEList);
generateColumnNames(pParse, 0, pFirst->pEList);
}
iBreak = sqlite3VdbeMakeLabel(v);
iCont = sqlite3VdbeMakeLabel(v);
@@ -2447,7 +2443,7 @@ static int multiSelect(
if( dest.eDest==SRT_Output ){
Select *pFirst = p;
while( pFirst->pPrior ) pFirst = pFirst->pPrior;
generateColumnNames(pParse, pFirst->pSrc, pFirst->pEList);
generateColumnNames(pParse, 0, pFirst->pEList);
}
iBreak = sqlite3VdbeMakeLabel(v);
iCont = sqlite3VdbeMakeLabel(v);
@@ -3062,7 +3058,7 @@ static int multiSelectOrderBy(
if( pDest->eDest==SRT_Output ){
Select *pFirst = pPrior;
while( pFirst->pPrior ) pFirst = pFirst->pPrior;
generateColumnNames(pParse, pFirst->pSrc, pFirst->pEList);
generateColumnNames(pParse, 0, pFirst->pEList);
}
/* Reassembly the compound query so that it will be freed correctly
@@ -4459,7 +4455,6 @@ static int selectExpander(Walker *pWalker, Select *p){
#if SQLITE_MAX_COLUMN
if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
sqlite3ErrorMsg(pParse, "too many columns in result set");
return WRC_Abort;
}
#endif
return WRC_Continue;
+59 -143
View File
@@ -329,13 +329,6 @@ static int bail_on_error = 0;
*/
static int stdin_is_interactive = 1;
/*
** On Windows systems we have to know if standard output is a console
** in order to translate UTF-8 into MBCS. The following variable is
** true if translation is required.
*/
static int stdout_is_console = 1;
/*
** The following is the open SQLite database. We make a pointer
** to this database a static variable so that it can be accessed
@@ -437,16 +430,6 @@ static void shellstaticFunc(
}
/*
** Compute a string length that is limited to what can be stored in
** lower 30 bits of a 32-bit signed integer.
*/
static int strlen30(const char *z){
const char *z2 = z;
while( *z2 ){ z2++; }
return 0x3fffffff & (int)(z2 - z);
}
/*
** This routine reads a line of text from FILE in, stores
** the text in memory obtained from malloc() and returns a pointer
@@ -482,26 +465,6 @@ static char *local_getline(char *zLine, FILE *in){
break;
}
}
#if defined(_WIN32) || defined(WIN32)
/* For interactive input on Windows systems, translate the
** multi-byte characterset characters into UTF-8. */
if( stdin_is_interactive ){
extern char *sqlite3_win32_mbcs_to_utf8(const char*);
char *zTrans = sqlite3_win32_mbcs_to_utf8(zLine);
if( zTrans ){
int nTrans = strlen30(zTrans)+1;
if( nTrans>nLine ){
zLine = realloc(zLine, nTrans);
if( zLine==0 ){
sqlite3_free(zTrans);
return 0;
}
}
memcpy(zLine, zTrans, nTrans);
sqlite3_free(zTrans);
}
}
#endif /* defined(_WIN32) || defined(WIN32) */
return zLine;
}
@@ -539,31 +502,6 @@ static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
return zResult;
}
/*
** Render output like fprintf(). Except, if the output is going to the
** console and if this is running on a Windows machine, translate the
** output from UTF-8 into MBCS.
*/
#if defined(_WIN32) || defined(WIN32)
void utf8_printf(FILE *out, const char *zFormat, ...){
va_list ap;
va_start(ap, zFormat);
if( stdout_is_console && out==stdout ){
extern char *sqlite3_win32_utf8_to_mbcs(const char*);
char *z1 = sqlite3_vmprintf(zFormat, ap);
char *z2 = sqlite3_win32_utf8_to_mbcs(z1);
sqlite3_free(z1);
fputs(z2, out);
sqlite3_free(z2);
}else{
vfprintf(out, zFormat, ap);
}
va_end(ap);
}
#else
# define utf8_printf fprintf
#endif
/*
** Shell output mode information from before ".explain on",
** saved so that it can be restored by ".explain off"
@@ -587,7 +525,6 @@ struct ShellState {
int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
int statsOn; /* True to display memory stats before each finalize */
int scanstatsOn; /* True to display scan stats before each finalize */
int countChanges; /* True to display change counts */
int backslashOn; /* Resolve C-style \x escapes in SQL input text */
int outCount; /* Revert to stdout when reaching zero */
int cnt; /* Number of records displayed so far */
@@ -669,6 +606,16 @@ static const char *modeDescr[] = {
*/
#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
/*
** Compute a string length that is limited to what can be stored in
** lower 30 bits of a 32-bit signed integer.
*/
static int strlen30(const char *z){
const char *z2 = z;
while( *z2 ){ z2++; }
return 0x3fffffff & (int)(z2 - z);
}
/*
** A callback for the sqlite3_log() interface.
*/
@@ -701,7 +648,7 @@ static void output_quoted_string(FILE *out, const char *z){
if( z[i]=='\'' ) nSingle++;
}
if( nSingle==0 ){
utf8_printf(out,"'%s'",z);
fprintf(out,"'%s'",z);
}else{
fprintf(out,"'");
while( *z ){
@@ -710,10 +657,10 @@ static void output_quoted_string(FILE *out, const char *z){
fprintf(out,"''");
z++;
}else if( z[i]=='\'' ){
utf8_printf(out,"%.*s''",i,z);
fprintf(out,"%.*s''",i,z);
z += i+1;
}else{
utf8_printf(out,"%s",z);
fprintf(out,"%s",z);
break;
}
}
@@ -769,7 +716,7 @@ static void output_html_string(FILE *out, const char *z){
&& z[i]!='\'';
i++){}
if( i>0 ){
utf8_printf(out,"%.*s",i,z);
fprintf(out,"%.*s",i,z);
}
if( z[i]=='<' ){
fprintf(out,"&lt;");
@@ -820,7 +767,7 @@ static const char needCsvQuote[] = {
static void output_csv(ShellState *p, const char *z, int bSep){
FILE *out = p->out;
if( z==0 ){
utf8_printf(out,"%s",p->nullValue);
fprintf(out,"%s",p->nullValue);
}else{
int i;
int nSep = strlen30(p->colSeparator);
@@ -840,11 +787,11 @@ static void output_csv(ShellState *p, const char *z, int bSep){
}
putc('"', out);
}else{
utf8_printf(out, "%s", z);
fprintf(out, "%s", z);
}
}
if( bSep ){
utf8_printf(p->out, "%s", p->colSeparator);
fprintf(p->out, "%s", p->colSeparator);
}
}
@@ -882,9 +829,9 @@ static int shell_callback(
int len = strlen30(azCol[i] ? azCol[i] : "");
if( len>w ) w = len;
}
if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator);
if( p->cnt++>0 ) fprintf(p->out, "%s", p->rowSeparator);
for(i=0; i<nArg; i++){
utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
fprintf(p->out,"%*s = %s%s", w, azCol[i],
azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
}
break;
@@ -910,10 +857,10 @@ static int shell_callback(
}
if( p->showHeader ){
if( w<0 ){
utf8_printf(p->out,"%*.*s%s",-w,-w,azCol[i],
fprintf(p->out,"%*.*s%s",-w,-w,azCol[i],
i==nArg-1 ? p->rowSeparator : " ");
}else{
utf8_printf(p->out,"%-*.*s%s",w,w,azCol[i],
fprintf(p->out,"%-*.*s%s",w,w,azCol[i],
i==nArg-1 ? p->rowSeparator : " ");
}
}
@@ -927,8 +874,7 @@ static int shell_callback(
}else{
w = 10;
}
fprintf(p->out,"%-*.*s%s",w,w,
"----------------------------------------------------------"
fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
"----------------------------------------------------------",
i==nArg-1 ? p->rowSeparator : " ");
}
@@ -952,11 +898,11 @@ static int shell_callback(
p->iIndent++;
}
if( w<0 ){
utf8_printf(p->out,"%*.*s%s",-w,-w,
fprintf(p->out,"%*.*s%s",-w,-w,
azArg[i] ? azArg[i] : p->nullValue,
i==nArg-1 ? p->rowSeparator : " ");
}else{
utf8_printf(p->out,"%-*.*s%s",w,w,
fprintf(p->out,"%-*.*s%s",w,w,
azArg[i] ? azArg[i] : p->nullValue,
i==nArg-1 ? p->rowSeparator : " ");
}
@@ -967,7 +913,7 @@ static int shell_callback(
case MODE_List: {
if( p->cnt++==0 && p->showHeader ){
for(i=0; i<nArg; i++){
utf8_printf(p->out,"%s%s",azCol[i],
fprintf(p->out,"%s%s",azCol[i],
i==nArg-1 ? p->rowSeparator : p->colSeparator);
}
}
@@ -975,13 +921,13 @@ static int shell_callback(
for(i=0; i<nArg; i++){
char *z = azArg[i];
if( z==0 ) z = p->nullValue;
utf8_printf(p->out, "%s", z);
fprintf(p->out, "%s", z);
if( i<nArg-1 ){
utf8_printf(p->out, "%s", p->colSeparator);
fprintf(p->out, "%s", p->colSeparator);
}else if( p->mode==MODE_Semi ){
utf8_printf(p->out, ";%s", p->rowSeparator);
fprintf(p->out, ";%s", p->rowSeparator);
}else{
utf8_printf(p->out, "%s", p->rowSeparator);
fprintf(p->out, "%s", p->rowSeparator);
}
}
break;
@@ -1010,16 +956,16 @@ static int shell_callback(
if( p->cnt++==0 && p->showHeader ){
for(i=0; i<nArg; i++){
output_c_string(p->out,azCol[i] ? azCol[i] : "");
if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
}
utf8_printf(p->out, "%s", p->rowSeparator);
fprintf(p->out, "%s", p->rowSeparator);
}
if( azArg==0 ) break;
for(i=0; i<nArg; i++){
output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
}
utf8_printf(p->out, "%s", p->rowSeparator);
fprintf(p->out, "%s", p->rowSeparator);
break;
}
case MODE_Csv: {
@@ -1028,13 +974,13 @@ static int shell_callback(
for(i=0; i<nArg; i++){
output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
}
utf8_printf(p->out, "%s", p->rowSeparator);
fprintf(p->out, "%s", p->rowSeparator);
}
if( nArg>0 ){
for(i=0; i<nArg; i++){
output_csv(p, azArg[i], i<nArg-1);
}
utf8_printf(p->out, "%s", p->rowSeparator);
fprintf(p->out, "%s", p->rowSeparator);
}
setTextMode(p->out);
break;
@@ -1042,12 +988,12 @@ static int shell_callback(
case MODE_Insert: {
p->cnt++;
if( azArg==0 ) break;
utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
fprintf(p->out,"INSERT INTO %s",p->zDestTable);
if( p->showHeader ){
fprintf(p->out,"(");
for(i=0; i<nArg; i++){
char *zSep = i>0 ? ",": "";
utf8_printf(p->out, "%s%s", zSep, azCol[i]);
fprintf(p->out, "%s%s", zSep, azCol[i]);
}
fprintf(p->out,")");
}
@@ -1061,14 +1007,14 @@ static int shell_callback(
output_quoted_string(p->out, azArg[i]);
}else if( aiType && (aiType[i]==SQLITE_INTEGER
|| aiType[i]==SQLITE_FLOAT) ){
utf8_printf(p->out,"%s%s",zSep, azArg[i]);
fprintf(p->out,"%s%s",zSep, azArg[i]);
}else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
const void *pBlob = sqlite3_column_blob(p->pStmt, i);
int nBlob = sqlite3_column_bytes(p->pStmt, i);
if( zSep[0] ) fprintf(p->out,"%s",zSep);
output_hex_blob(p->out, pBlob, nBlob);
}else if( isNumber(azArg[i], 0) ){
utf8_printf(p->out,"%s%s",zSep, azArg[i]);
fprintf(p->out,"%s%s",zSep, azArg[i]);
}else{
if( zSep[0] ) fprintf(p->out,"%s",zSep);
output_quoted_string(p->out, azArg[i]);
@@ -1080,17 +1026,17 @@ static int shell_callback(
case MODE_Ascii: {
if( p->cnt++==0 && p->showHeader ){
for(i=0; i<nArg; i++){
if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : "");
if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
fprintf(p->out,"%s",azCol[i] ? azCol[i] : "");
}
utf8_printf(p->out, "%s", p->rowSeparator);
fprintf(p->out, "%s", p->rowSeparator);
}
if( azArg==0 ) break;
for(i=0; i<nArg; i++){
if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
fprintf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
}
utf8_printf(p->out, "%s", p->rowSeparator);
fprintf(p->out, "%s", p->rowSeparator);
break;
}
}
@@ -1220,13 +1166,13 @@ static int run_table_dump_query(
nResult = sqlite3_column_count(pSelect);
while( rc==SQLITE_ROW ){
if( zFirstRow ){
utf8_printf(p->out, "%s", zFirstRow);
fprintf(p->out, "%s", zFirstRow);
zFirstRow = 0;
}
z = (const char*)sqlite3_column_text(pSelect, 0);
utf8_printf(p->out, "%s", z);
fprintf(p->out, "%s", z);
for(i=1; i<nResult; i++){
utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
}
if( z==0 ) z = "";
while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
@@ -1414,7 +1360,7 @@ static void display_scanstats(
sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain);
fprintf(pArg->out, "Loop %2d: %s\n", n, zExplain);
rEstLoop *= rEst;
fprintf(pArg->out,
" nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
@@ -1575,7 +1521,7 @@ static int shell_exec(
/* echo the sql statement if echo on */
if( pArg && pArg->echoOn ){
const char *zStmtSql = sqlite3_sql(pStmt);
utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
}
/* Show the EXPLAIN QUERY PLAN if .eqp is on */
@@ -1589,7 +1535,7 @@ static int shell_exec(
fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0));
fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
}
}
sqlite3_finalize(pExplain);
@@ -1730,11 +1676,11 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
"INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
"VALUES('table','%q','%q',0,'%q');",
zTable, zTable, zSql);
utf8_printf(p->out, "%s\n", zIns);
fprintf(p->out, "%s\n", zIns);
sqlite3_free(zIns);
return 0;
}else{
utf8_printf(p->out, "%s;\n", zSql);
fprintf(p->out, "%s;\n", zSql);
}
if( strcmp(zType, "table")==0 ){
@@ -1839,7 +1785,6 @@ static char zHelp[] =
".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
".bail on|off Stop after hitting an error. Default OFF\n"
".binary on|off Turn binary output on or off. Default OFF\n"
".changes on|off Show number of rows changed by SQL\n"
".clone NEWDB Clone data into NEWDB from the existing database\n"
".databases List names and files of attached databases\n"
".dbinfo ?DB? Show status information about the database\n"
@@ -1902,7 +1847,6 @@ static char zHelp[] =
".timeout MS Try opening locked tables for MS milliseconds\n"
".timer on|off Turn SQL timer on or off\n"
".trace FILE|off Output each SQL statement as it is run\n"
".vfsinfo ?AUX? Information about the top-level VFS\n"
".vfsname ?AUX? Print the name of the VFS stack\n"
".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
" Negative values right-justify\n"
@@ -2179,7 +2123,7 @@ static void sql_trace_callback(void *pArg, const char *z){
if( f ){
int i = (int)strlen(z);
while( i>0 && z[i-1]==';' ){ i--; }
utf8_printf(f, "%.*s;\n", i, z);
fprintf(f, "%.*s;\n", i, z);
}
}
@@ -2662,7 +2606,7 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
int val = db_int(p, zSql);
sqlite3_free(zSql);
utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val);
}
sqlite3_free(zSchemaTab);
return 0;
@@ -2812,15 +2756,6 @@ static int do_meta_command(char *zLine, ShellState *p){
test_breakpoint();
}else
if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){
if( nArg==2 ){
p->countChanges = booleanValue(azArg[1]);
}else{
fprintf(stderr, "Usage: .changes on|off\n");
rc = 1;
}
}else
if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
if( nArg==2 ){
tryToClone(p, azArg[1]);
@@ -3502,7 +3437,7 @@ static int do_meta_command(char *zLine, ShellState *p){
int i;
for(i=1; i<nArg; i++){
if( i>1 ) fprintf(p->out, " ");
utf8_printf(p->out, "%s", azArg[i]);
fprintf(p->out, "%s", azArg[i]);
}
fprintf(p->out, "\n");
}else
@@ -3696,7 +3631,7 @@ static int do_meta_command(char *zLine, ShellState *p){
int i, v;
for(i=1; i<nArg; i++){
v = booleanValue(azArg[i]);
utf8_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
}
}
if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
@@ -3705,7 +3640,7 @@ static int do_meta_command(char *zLine, ShellState *p){
char zBuf[200];
v = integerValue(azArg[i]);
sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
utf8_printf(p->out, "%s", zBuf);
fprintf(p->out, "%s", zBuf);
}
}
}else
@@ -3879,8 +3814,7 @@ static int do_meta_command(char *zLine, ShellState *p){
for(i=0; i<nPrintRow; i++){
for(j=i; j<nRow; j+=nPrintRow){
char *zSp = j<nPrintRow ? "" : " ";
utf8_printf(p->out, "%s%-*s", zSp, maxlen,
azResult[j] ? azResult[j]:"");
fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:"");
}
fprintf(p->out, "\n");
}
@@ -4133,20 +4067,6 @@ static int do_meta_command(char *zLine, ShellState *p){
sqlite3_libversion(), sqlite3_sourceid());
}else
if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){
const char *zDbName = nArg==2 ? azArg[1] : "main";
sqlite3_vfs *pVfs;
if( p->db ){
sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
if( pVfs ){
fprintf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName);
fprintf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
fprintf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
fprintf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
}
}
}else
if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
const char *zDbName = nArg==2 ? azArg[1] : "main";
char *zVfsName = 0;
@@ -4351,9 +4271,6 @@ static int process_input(ShellState *p, FILE *in){
fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
}
errCnt++;
}else if( p->countChanges ){
fprintf(p->out, "changes: %3d total_changes: %d\n",
sqlite3_changes(p->db), sqlite3_total_changes(p->db));
}
nSql = 0;
if( p->outCount ){
@@ -4601,7 +4518,6 @@ int SQLITE_CDECL main(int argc, char **argv){
Argv0 = argv[0];
main_init(&data);
stdin_is_interactive = isatty(0);
stdout_is_console = isatty(1);
/* Make sure we have a valid signal handler early, before anything
** else is done.
+25 -170
View File
@@ -882,15 +882,6 @@ struct sqlite3_io_methods {
** pointer in case this file-control is not implemented. This file-control
** is intended for diagnostic use only.
**
** <li>[[SQLITE_FCNTL_VFS_POINTER]]
** ^The [SQLITE_FCNTL_VFS_POINTER] opcode finds a pointer to the top-level
** [VFSes] currently in use. ^(The argument X in
** sqlite3_file_control(db,SQLITE_FCNTL_VFS_POINTER,X) must be
** of type "[sqlite3_vfs] **". This opcodes will set *X
** to a pointer to the top-level VFS.)^
** ^When there are multiple VFS shims in the stack, this opcode finds the
** upper-most shim only.
**
** <li>[[SQLITE_FCNTL_PRAGMA]]
** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA]
** file control is sent to the open [sqlite3_file] object corresponding
@@ -1009,7 +1000,6 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_WAL_BLOCK 24
#define SQLITE_FCNTL_ZIPVFS 25
#define SQLITE_FCNTL_RBU 26
#define SQLITE_FCNTL_VFS_POINTER 27
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
@@ -4405,8 +4395,8 @@ unsigned int sqlite3_value_subtype(sqlite3_value*);
** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer
** then sqlite3_value_free(V) is a harmless no-op.
*/
sqlite3_value *sqlite3_value_dup(const sqlite3_value*);
void sqlite3_value_free(sqlite3_value*);
SQLITE_EXPERIMENTAL sqlite3_value *sqlite3_value_dup(const sqlite3_value*);
SQLITE_EXPERIMENTAL void sqlite3_value_free(sqlite3_value*);
/*
** CAPI3REF: Obtain Aggregate Function Context
@@ -5625,17 +5615,6 @@ struct sqlite3_module {
** ^Information about the ORDER BY clause is stored in aOrderBy[].
** ^Each term of aOrderBy records a column of the ORDER BY clause.
**
** The colUsed field indicates which columns of the virtual table may be
** required by the current scan. Virtual table columns are numbered from
** zero in the order in which they appear within the CREATE TABLE statement
** passed to sqlite3_declare_vtab(). For the first 63 columns (columns 0-62),
** the corresponding bit is set within the colUsed mask if the column may be
** required by SQLite. If the table has at least 64 columns and any column
** to the right of the first 63 is required, then bit 63 of colUsed is also
** set. In other words, column iCol may be required if the expression
** (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) evaluates to
** non-zero.
**
** The [xBestIndex] method must fill aConstraintUsage[] with information
** about what parameters to pass to xFilter. ^If argvIndex>0 then
** the right-hand side of the corresponding aConstraint[] is evaluated
@@ -5715,8 +5694,6 @@ struct sqlite3_index_info {
sqlite3_int64 estimatedRows; /* Estimated number of rows returned */
/* Fields below are only available in SQLite 3.9.0 and later */
int idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */
/* Fields below are only available in SQLite 3.10.0 and later */
sqlite3_uint64 colUsed; /* Input: Mask of columns used by statement */
};
/*
@@ -5732,15 +5709,12 @@ struct sqlite3_index_info {
** an operator that is part of a constraint term in the wHERE clause of
** a query that uses a [virtual table].
*/
#define SQLITE_INDEX_CONSTRAINT_EQ 2
#define SQLITE_INDEX_CONSTRAINT_GT 4
#define SQLITE_INDEX_CONSTRAINT_LE 8
#define SQLITE_INDEX_CONSTRAINT_LT 16
#define SQLITE_INDEX_CONSTRAINT_GE 32
#define SQLITE_INDEX_CONSTRAINT_MATCH 64
#define SQLITE_INDEX_CONSTRAINT_LIKE 65
#define SQLITE_INDEX_CONSTRAINT_GLOB 66
#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
#define SQLITE_INDEX_CONSTRAINT_EQ 2
#define SQLITE_INDEX_CONSTRAINT_GT 4
#define SQLITE_INDEX_CONSTRAINT_LE 8
#define SQLITE_INDEX_CONSTRAINT_LT 16
#define SQLITE_INDEX_CONSTRAINT_GE 32
#define SQLITE_INDEX_CONSTRAINT_MATCH 64
/*
** CAPI3REF: Register A Virtual Table Implementation
@@ -7391,43 +7365,18 @@ int sqlite3_strnicmp(const char *, const char *, int);
/*
** CAPI3REF: String Globbing
*
** ^The [sqlite3_strglob(P,X)] interface returns zero if and only if
** string X matches the [GLOB] pattern P.
** ^The definition of [GLOB] pattern matching used in
** ^The [sqlite3_strglob(P,X)] interface returns zero if string X matches
** the glob pattern P, and it returns non-zero if string X does not match
** the glob pattern P. ^The definition of glob pattern matching used in
** [sqlite3_strglob(P,X)] is the same as for the "X GLOB P" operator in the
** SQL dialect understood by SQLite. ^The [sqlite3_strglob(P,X)] function
** is case sensitive.
** SQL dialect used by SQLite. ^The sqlite3_strglob(P,X) function is case
** sensitive.
**
** Note that this routine returns zero on a match and non-zero if the strings
** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
**
** See also: [sqlite3_strlike()].
*/
int sqlite3_strglob(const char *zGlob, const char *zStr);
/*
** CAPI3REF: String LIKE Matching
*
** ^The [sqlite3_strlike(P,X,E)] interface returns zero if and only if
** string X matches the [LIKE] pattern P with escape character E.
** ^The definition of [LIKE] pattern matching used in
** [sqlite3_strlike(P,X,E)] is the same as for the "X LIKE P ESCAPE E"
** operator in the SQL dialect understood by SQLite. ^For "X LIKE P" without
** the ESCAPE clause, set the E parameter of [sqlite3_strlike(P,X,E)] to 0.
** ^As with the LIKE operator, the [sqlite3_strlike(P,X,E)] function is case
** insensitive - equivalent upper and lower case ASCII characters match
** one another.
**
** ^The [sqlite3_strlike(P,X,E)] function matches Unicode characters, though
** only ASCII characters are case folded.
**
** Note that this routine returns zero on a match and non-zero if the strings
** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
**
** See also: [sqlite3_strglob()].
*/
int sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc);
/*
** CAPI3REF: Error Logging Interface
**
@@ -7851,127 +7800,33 @@ void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
/*
** CAPI3REF: Flush caches to disk mid-transaction
**
** ^If a write-transaction is open on [database connection] D when the
** [sqlite3_db_cacheflush(D)] interface invoked, any dirty
** If a write-transaction is open when this function is called, any dirty
** pages in the pager-cache that are not currently in use are written out
** to disk. A dirty page may be in use if a database cursor created by an
** active SQL statement is reading from it, or if it is page 1 of a database
** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)]
** interface flushes caches for all schemas - "main", "temp", and
** any [attached] databases.
** file (page 1 is always "in use"). Dirty pages are flushed for all
** databases - "main", "temp" and any attached databases.
**
** ^If this function needs to obtain extra database locks before dirty pages
** can be flushed to disk, it does so. ^If those locks cannot be obtained
** If this function needs to obtain extra database locks before dirty pages
** can be flushed to disk, it does so. If said locks cannot be obtained
** immediately and there is a busy-handler callback configured, it is invoked
** in the usual manner. ^If the required lock still cannot be obtained, then
** in the usual manner. If the required lock still cannot be obtained, then
** the database is skipped and an attempt made to flush any dirty pages
** belonging to the next (if any) database. ^If any databases are skipped
** belonging to the next (if any) database. If any databases are skipped
** because locks cannot be obtained, but no other error occurs, this
** function returns SQLITE_BUSY.
**
** ^If any other error occurs while flushing dirty pages to disk (for
** If any other error occurs while flushing dirty pages to disk (for
** example an IO error or out-of-memory condition), then processing is
** abandoned and an SQLite [error code] is returned to the caller immediately.
** abandoned and an SQLite error code returned to the caller immediately.
**
** ^Otherwise, if no error occurs, [sqlite3_db_cacheflush()] returns SQLITE_OK.
** Otherwise, if no error occurs, SQLITE_OK is returned.
**
** ^This function does not set the database handle error code or message
** returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions.
** This function does not set the database handle error code or message
** returned by the sqlite3_errcode() and sqlite3_errmsg() functions.
*/
int sqlite3_db_cacheflush(sqlite3*);
/*
** CAPI3REF: Database Snapshot
** KEYWORDS: {snapshot}
** EXPERIMENTAL
**
** An instance of the snapshot object records the state of a [WAL mode]
** database for some specific point in history.
**
** In [WAL mode], multiple [database connections] that are open on the
** same database file can each be reading a different historical version
** of the database file. When a [database connection] begins a read
** transaction, that connection sees an unchanging copy of the database
** as it existed for the point in time when the transaction first started.
** Subsequent changes to the database from other connections are not seen
** by the reader until a new read transaction is started.
**
** The sqlite3_snapshot object records state information about an historical
** version of the database file so that it is possible to later open a new read
** transaction that sees that historical version of the database rather than
** the most recent version.
**
** The constructor for this object is [sqlite3_snapshot_get()]. The
** [sqlite3_snapshot_open()] method causes a fresh read transaction to refer
** to an historical snapshot (if possible). The destructor for
** sqlite3_snapshot objects is [sqlite3_snapshot_free()].
*/
typedef struct sqlite3_snapshot sqlite3_snapshot;
/*
** CAPI3REF: Record A Database Snapshot
** EXPERIMENTAL
**
** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a
** new [sqlite3_snapshot] object that records the current state of
** schema S in database connection D. ^On success, the
** [sqlite3_snapshot_get(D,S,P)] interface writes a pointer to the newly
** created [sqlite3_snapshot] object into *P and returns SQLITE_OK.
** ^If schema S of [database connection] D is not a [WAL mode] database
** that is in a read transaction, then [sqlite3_snapshot_get(D,S,P)]
** leaves the *P value unchanged and returns an appropriate [error code].
**
** The [sqlite3_snapshot] object returned from a successful call to
** [sqlite3_snapshot_get()] must be freed using [sqlite3_snapshot_free()]
** to avoid a memory leak.
**
** The [sqlite3_snapshot_get()] interface is only available when the
** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
*/
SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
sqlite3 *db,
const char *zSchema,
sqlite3_snapshot **ppSnapshot
);
/*
** CAPI3REF: Start a read transaction on an historical snapshot
** EXPERIMENTAL
**
** ^The [sqlite3_snapshot_open(D,S,P)] interface attempts to move the
** read transaction that is currently open on schema S of
** [database connection] D so that it refers to historical [snapshot] P.
** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success
** or an appropriate [error code] if it fails.
**
** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be
** the first operation, apart from other sqlite3_snapshot_open() calls,
** following the [BEGIN] that starts a new read transaction.
** ^A [snapshot] will fail to open if it has been overwritten by a
** [checkpoint].
**
** The [sqlite3_snapshot_open()] interface is only available when the
** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
*/
SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
sqlite3 *db,
const char *zSchema,
sqlite3_snapshot *pSnapshot
);
/*
** CAPI3REF: Destroy a snapshot
** EXPERIMENTAL
**
** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P.
** The application must eventually free every [sqlite3_snapshot] object
** using this routine to avoid a memory leak.
**
** The [sqlite3_snapshot_free()] interface is only available when the
** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
*/
SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
-8
View File
@@ -275,10 +275,6 @@ struct sqlite3_api_routines {
/* Version 3.9.0 and later */
unsigned int (*value_subtype)(sqlite3_value*);
void (*result_subtype)(sqlite3_context*,unsigned int);
/* Version 3.10.0 and later */
int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
int (*strlike)(const char*,const char*,unsigned int);
int (*db_cacheflush)(sqlite3*);
};
/*
@@ -518,10 +514,6 @@ struct sqlite3_api_routines {
/* Version 3.9.0 and later */
#define sqlite3_value_subtype sqlite3_api->value_subtype
#define sqlite3_result_subtype sqlite3_api->result_subtype
/* Version 3.10.0 and later */
#define sqlite3_status64 sqlite3_api->status64
#define sqlite3_strlike sqlite3_api->strlike
#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
+6 -24
View File
@@ -173,21 +173,6 @@
# define SQLITE_PTR_TO_INT(X) ((int)(X))
#endif
/*
** The SQLITE_WITHIN(P,S,E) macro checks to see if pointer P points to
** something between S (inclusive) and E (exclusive).
**
** In other words, S is a buffer and E is a pointer to the first byte after
** the end of buffer S. This macro returns true if P points to something
** contained within the buffer S.
*/
#if defined(HAVE_STDINT_H)
# define SQLITE_WITHIN(P,S,E) \
((uintptr_t)(P)>=(uintptr_t)(S) && (uintptr_t)(P)<(uintptr_t)(E))
#else
# define SQLITE_WITHIN(P,S,E) ((P)>=(S) && (P)<(E))
#endif
/*
** A macro to hint to the compiler that a function should not be
** inlined.
@@ -692,6 +677,11 @@ typedef INT16_TYPE LogEst;
** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined
** at run-time.
*/
#ifdef SQLITE_AMALGAMATION
const int sqlite3one = 1;
#else
extern const int sqlite3one;
#endif
#if (defined(i386) || defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
@@ -709,11 +699,6 @@ typedef INT16_TYPE LogEst;
# define SQLITE_UTF16NATIVE SQLITE_UTF16BE
#endif
#if !defined(SQLITE_BYTEORDER)
# ifdef SQLITE_AMALGAMATION
const int sqlite3one = 1;
# else
extern const int sqlite3one;
# endif
# define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */
# define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0)
# define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1)
@@ -1932,7 +1917,7 @@ struct Index {
Index *pNext; /* The next index associated with the same table */
Schema *pSchema; /* Schema containing this index */
u8 *aSortOrder; /* for each column: True==DESC, False==ASC */
const char **azColl; /* Array of collation sequence names for index */
char **azColl; /* Array of collation sequence names for index */
Expr *pPartIdxWhere; /* WHERE clause for partial indices */
ExprList *aColExpr; /* Column expressions */
int tnum; /* DB Page containing root of this index */
@@ -2967,7 +2952,6 @@ struct StrAccum {
int nAlloc; /* Amount of space allocated in zText */
int mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */
u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */
u8 bMalloced; /* zText points to allocated space */
};
#define STRACCUM_NOMEM 1
#define STRACCUM_TOOBIG 2
@@ -3461,7 +3445,6 @@ void sqlite3ExprCacheRemove(Parse*, int, int);
void sqlite3ExprCacheClear(Parse*);
void sqlite3ExprCacheAffinityChange(Parse*, int, int);
void sqlite3ExprCode(Parse*, Expr*, int);
void sqlite3ExprCodeCopy(Parse*, Expr*, int);
void sqlite3ExprCodeFactorable(Parse*, Expr*, int);
void sqlite3ExprCodeAtInit(Parse*, Expr*, int, u8);
int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
@@ -3699,7 +3682,6 @@ int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **);
void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
#ifndef SQLITE_AMALGAMATION
extern const unsigned char sqlite3OpcodeProperty[];
extern const char sqlite3StrBINARY[];
extern const unsigned char sqlite3UpperToLower[];
extern const unsigned char sqlite3CtypeMap[];
extern const Token sqlite3IntTokens[];
+2 -95
View File
@@ -2269,94 +2269,6 @@ static int vfsCurrentTimeInt64(
return TCL_OK;
}
#ifdef SQLITE_ENABLE_SNAPSHOT
/*
** Usage: sqlite3_snapshot_get DB DBNAME
*/
static int test_snapshot_get(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int rc;
sqlite3 *db;
char *zName;
sqlite3_snapshot *pSnapshot = 0;
if( objc!=3 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME");
return TCL_ERROR;
}
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
zName = Tcl_GetString(objv[2]);
rc = sqlite3_snapshot_get(db, zName, &pSnapshot);
if( rc!=SQLITE_OK ){
Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
return TCL_ERROR;
}else{
char zBuf[100];
if( sqlite3TestMakePointerStr(interp, zBuf, pSnapshot) ) return TCL_ERROR;
Tcl_SetObjResult(interp, Tcl_NewStringObj(zBuf, -1));
}
return TCL_OK;
}
#endif /* SQLITE_ENABLE_SNAPSHOT */
#ifdef SQLITE_ENABLE_SNAPSHOT
/*
** Usage: sqlite3_snapshot_open DB DBNAME SNAPSHOT
*/
static int test_snapshot_open(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int rc;
sqlite3 *db;
char *zName;
sqlite3_snapshot *pSnapshot;
if( objc!=4 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME SNAPSHOT");
return TCL_ERROR;
}
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
zName = Tcl_GetString(objv[2]);
pSnapshot = (sqlite3_snapshot*)sqlite3TestTextToPtr(Tcl_GetString(objv[3]));
rc = sqlite3_snapshot_open(db, zName, pSnapshot);
if( rc!=SQLITE_OK ){
Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
return TCL_ERROR;
}
return TCL_OK;
}
#endif /* SQLITE_ENABLE_SNAPSHOT */
#ifdef SQLITE_ENABLE_SNAPSHOT
/*
** Usage: sqlite3_snapshot_free SNAPSHOT
*/
static int test_snapshot_free(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
sqlite3_snapshot *pSnapshot;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "SNAPSHOT");
return TCL_ERROR;
}
pSnapshot = (sqlite3_snapshot*)sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
sqlite3_snapshot_free(pSnapshot);
return TCL_OK;
}
#endif /* SQLITE_ENABLE_SNAPSHOT */
/*
** Usage: sqlite3_next_stmt DB STMT
**
@@ -5994,13 +5906,13 @@ static int test_sqlite3_log(
Tcl_DecrRefCount(logcallback.pObj);
logcallback.pObj = 0;
logcallback.pInterp = 0;
sqlite3_config(SQLITE_CONFIG_LOG, (void*)0, (void*)0);
sqlite3_config(SQLITE_CONFIG_LOG, 0, 0);
}
if( objc>1 ){
logcallback.pObj = objv[1];
Tcl_IncrRefCount(logcallback.pObj);
logcallback.pInterp = interp;
sqlite3_config(SQLITE_CONFIG_LOG, xLogcallback, (void*)0);
sqlite3_config(SQLITE_CONFIG_LOG, xLogcallback, 0);
}
return TCL_OK;
}
@@ -7171,11 +7083,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite3_config_sqllog", test_config_sqllog, 0 },
#endif
{ "vfs_current_time_int64", vfsCurrentTimeInt64, 0 },
#ifdef SQLITE_ENABLE_SNAPSHOT
{ "sqlite3_snapshot_get", test_snapshot_get, 0 },
{ "sqlite3_snapshot_open", test_snapshot_open, 0 },
{ "sqlite3_snapshot_free", test_snapshot_free, 0 },
#endif
};
static int bitmask_size = sizeof(Bitmask)*8;
static int longdouble_size = sizeof(LONGDOUBLE_TYPE);
+9 -52
View File
@@ -745,34 +745,6 @@ static void string_concat(char **pzStr, char *zAppend, int doFree, int *pRc){
}
}
/*
** This function returns a pointer to an sqlite3_malloc()ed buffer
** containing the select-list (the thing between keywords SELECT and FROM)
** to query the underlying real table with for the scan described by
** argument pIdxInfo.
**
** If the current SQLite version is earlier than 3.10.0, this is just "*"
** (select all columns). Or, for version 3.10.0 and greater, the list of
** columns identified by the pIdxInfo->colUsed mask.
*/
static char *echoSelectList(echo_vtab *pTab, sqlite3_index_info *pIdxInfo){
char *zRet = 0;
if( sqlite3_libversion_number()<3010000 ){
zRet = sqlite3_mprintf(", *");
}else{
int i;
for(i=0; i<pTab->nCol; i++){
if( pIdxInfo->colUsed & ((sqlite3_uint64)1 << (i>=63 ? 63 : i)) ){
zRet = sqlite3_mprintf("%z, %s", zRet, pTab->aCol[i]);
}else{
zRet = sqlite3_mprintf("%z, NULL", zRet);
}
if( !zRet ) break;
}
}
return zRet;
}
/*
** The echo module implements the subset of query constraints and sort
** orders that may take advantage of SQLite indices on the underlying
@@ -798,7 +770,6 @@ static char *echoSelectList(echo_vtab *pTab, sqlite3_index_info *pIdxInfo){
static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
int ii;
char *zQuery = 0;
char *zCol = 0;
char *zNew;
int nArg = 0;
const char *zSep = "WHERE";
@@ -846,11 +817,10 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
}
}
zCol = echoSelectList(pVtab, pIdxInfo);
if( !zCol ) return SQLITE_NOMEM;
zQuery = sqlite3_mprintf("SELECT rowid%z FROM %Q", zCol, pVtab->zTableName);
if( !zQuery ) return SQLITE_NOMEM;
zQuery = sqlite3_mprintf("SELECT rowid, * FROM %Q", pVtab->zTableName);
if( !zQuery ){
return SQLITE_NOMEM;
}
for(ii=0; ii<pIdxInfo->nConstraint; ii++){
const struct sqlite3_index_constraint *pConstraint;
struct sqlite3_index_constraint_usage *pUsage;
@@ -863,7 +833,7 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
iCol = pConstraint->iColumn;
if( iCol<0 || pVtab->aIndex[iCol] ){
char *zNewCol = iCol>=0 ? pVtab->aCol[iCol] : "rowid";
char *zCol = iCol>=0 ? pVtab->aCol[iCol] : "rowid";
char *zOp = 0;
useIdx = 1;
switch( pConstraint->op ){
@@ -878,26 +848,13 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
case SQLITE_INDEX_CONSTRAINT_GE:
zOp = ">="; break;
case SQLITE_INDEX_CONSTRAINT_MATCH:
/* Purposely translate the MATCH operator into a LIKE, which
** will be used by the next block of code to construct a new
** query. It should also be noted here that the next block
** of code requires the first letter of this operator to be
** in upper-case to trigger the special MATCH handling (i.e.
** wrapping the bound parameter with literal '%'s).
*/
zOp = "LIKE"; break;
case SQLITE_INDEX_CONSTRAINT_LIKE:
zOp = "like"; break;
case SQLITE_INDEX_CONSTRAINT_GLOB:
zOp = "glob"; break;
case SQLITE_INDEX_CONSTRAINT_REGEXP:
zOp = "regexp"; break;
}
if( zOp[0]=='L' ){
zNew = sqlite3_mprintf(" %s %s LIKE (SELECT '%%'||?||'%%')",
zSep, zNewCol);
zSep, zCol);
} else {
zNew = sqlite3_mprintf(" %s %s %s ?", zSep, zNewCol, zOp);
zNew = sqlite3_mprintf(" %s %s %s ?", zSep, zCol, zOp);
}
string_concat(&zQuery, zNew, 1, &rc);
@@ -915,9 +872,9 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
pIdxInfo->aOrderBy->iColumn<0 ||
pVtab->aIndex[pIdxInfo->aOrderBy->iColumn]) ){
int iCol = pIdxInfo->aOrderBy->iColumn;
char *zNewCol = iCol>=0 ? pVtab->aCol[iCol] : "rowid";
char *zCol = iCol>=0 ? pVtab->aCol[iCol] : "rowid";
char *zDir = pIdxInfo->aOrderBy->desc?"DESC":"ASC";
zNew = sqlite3_mprintf(" ORDER BY %s %s", zNewCol, zDir);
zNew = sqlite3_mprintf(" ORDER BY %s %s", zCol, zDir);
string_concat(&zQuery, zNew, 1, &rc);
pIdxInfo->orderByConsumed = 1;
}
-12
View File
@@ -143,12 +143,6 @@ static void set_options(Tcl_Interp *interp){
Tcl_SetVar2(interp, "sqlite_options", "mem5", "0", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_ENABLE_SNAPSHOT
Tcl_SetVar2(interp, "sqlite_options", "snapshot", "1", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "snapshot", "0", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_MUTEX_OMIT
Tcl_SetVar2(interp, "sqlite_options", "mutex", "0", TCL_GLOBAL_ONLY);
#else
@@ -191,12 +185,6 @@ static void set_options(Tcl_Interp *interp){
Tcl_SetVar2(interp, "sqlite_options", "json1", "0", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
Tcl_SetVar2(interp, "sqlite_options", "like_match_blobs", "0", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "like_match_blobs", "1", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_OMIT_ATTACH
Tcl_SetVar2(interp, "sqlite_options", "attach", "0", TCL_GLOBAL_ONLY);
#else
+3 -575
View File
@@ -29,37 +29,6 @@
** Adding the row to the idx table automatically creates a row in the
** virtual table with rowid=4, path=/etc/passwd and a text field that
** contains data read from file /etc/passwd on disk.
**
*************************************************************************
** Virtual table module "fsdir"
**
** This module is designed to be used as a read-only eponymous virtual table.
** Its schema is as follows:
**
** CREATE TABLE fsdir(dir TEXT, name TEXT);
**
** When queried, a WHERE term of the form "dir = $dir" must be provided. The
** virtual table then appears to have one row for each entry in file-system
** directory $dir. Column dir contains a copy of $dir, and column "name"
** contains the name of the directory entry.
**
** If the specified $dir cannot be opened or is not a directory, it is not
** an error. The virtual table appears to be empty in this case.
**
*************************************************************************
** Virtual table module "fstree"
**
** This module is also a read-only eponymous virtual table with the
** following schema:
**
** CREATE TABLE fstree(path TEXT, size INT, data BLOB);
**
** Running a "SELECT * FROM fstree" query on this table returns the entire
** contents of the file-system, starting at "/". To restrict the search
** space, the virtual table supports LIKE and GLOB constraints on the
** 'path' column. For example:
**
** SELECT * FROM fstree WHERE path LIKE '/home/dan/sqlite/%'
*/
#include "sqliteInt.h"
#include "tcl.h"
@@ -72,17 +41,9 @@
#if SQLITE_OS_UNIX
# include <unistd.h>
# include <dirent.h>
# ifndef DIRENT
# define DIRENT dirent
# endif
#endif
#if SQLITE_OS_WIN
# include <io.h>
# include "test_windirent.h"
# ifndef S_ISREG
# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
# endif
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -109,491 +70,6 @@ struct fs_cursor {
int nAlloc;
};
/*************************************************************************
** Start of fsdir implementation.
*/
typedef struct FsdirVtab FsdirVtab;
typedef struct FsdirCsr FsdirCsr;
struct FsdirVtab {
sqlite3_vtab base;
};
struct FsdirCsr {
sqlite3_vtab_cursor base;
char *zDir; /* Buffer containing directory scanned */
DIR *pDir; /* Open directory */
sqlite3_int64 iRowid;
struct DIRENT entry; /* Current entry */
};
/*
** This function is the implementation of both the xConnect and xCreate
** methods of the fsdir virtual table.
**
** The argv[] array contains the following:
**
** argv[0] -> module name ("fs")
** argv[1] -> database name
** argv[2] -> table name
** argv[...] -> other module argument fields.
*/
static int fsdirConnect(
sqlite3 *db,
void *pAux,
int argc, const char *const*argv,
sqlite3_vtab **ppVtab,
char **pzErr
){
FsdirVtab *pTab;
if( argc!=3 ){
*pzErr = sqlite3_mprintf("wrong number of arguments");
return SQLITE_ERROR;
}
pTab = (FsdirVtab *)sqlite3_malloc(sizeof(FsdirVtab));
if( !pTab ) return SQLITE_NOMEM;
memset(pTab, 0, sizeof(FsdirVtab));
*ppVtab = &pTab->base;
sqlite3_declare_vtab(db, "CREATE TABLE xyz(dir, name);");
return SQLITE_OK;
}
/*
** xDestroy/xDisconnect implementation.
*/
static int fsdirDisconnect(sqlite3_vtab *pVtab){
sqlite3_free(pVtab);
return SQLITE_OK;
}
/*
** xBestIndex implementation. The only constraint supported is:
**
** (dir = ?)
*/
static int fsdirBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
int ii;
pIdxInfo->estimatedCost = 1000000000.0;
for(ii=0; ii<pIdxInfo->nConstraint; ii++){
struct sqlite3_index_constraint const *p = &pIdxInfo->aConstraint[ii];
if( p->iColumn==0 && p->usable && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
struct sqlite3_index_constraint_usage *pUsage;
pUsage = &pIdxInfo->aConstraintUsage[ii];
pUsage->omit = 1;
pUsage->argvIndex = 1;
pIdxInfo->idxNum = 1;
pIdxInfo->estimatedCost = 1.0;
break;
}
}
return SQLITE_OK;
}
/*
** xOpen implementation.
**
** Open a new fsdir cursor.
*/
static int fsdirOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
FsdirCsr *pCur;
/* Allocate an extra 256 bytes because it is undefined how big dirent.d_name
** is and we need enough space. Linux provides plenty already, but
** Solaris only provides one byte. */
pCur = (FsdirCsr*)sqlite3_malloc(sizeof(FsdirCsr)+256);
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(FsdirCsr));
*ppCursor = &pCur->base;
return SQLITE_OK;
}
/*
** Close a fsdir cursor.
*/
static int fsdirClose(sqlite3_vtab_cursor *cur){
FsdirCsr *pCur = (FsdirCsr*)cur;
if( pCur->pDir ) closedir(pCur->pDir);
sqlite3_free(pCur->zDir);
sqlite3_free(pCur);
return SQLITE_OK;
}
/*
** Skip the cursor to the next entry.
*/
static int fsdirNext(sqlite3_vtab_cursor *cur){
FsdirCsr *pCsr = (FsdirCsr*)cur;
if( pCsr->pDir ){
struct DIRENT *pRes = 0;
readdir_r(pCsr->pDir, &pCsr->entry, &pRes);
if( pRes==0 ){
closedir(pCsr->pDir);
pCsr->pDir = 0;
}
pCsr->iRowid++;
}
return SQLITE_OK;
}
/*
** xFilter method implementation.
*/
static int fsdirFilter(
sqlite3_vtab_cursor *pVtabCursor,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv
){
FsdirCsr *pCsr = (FsdirCsr*)pVtabCursor;
const char *zDir;
int nDir;
if( idxNum!=1 || argc!=1 ){
return SQLITE_ERROR;
}
pCsr->iRowid = 0;
sqlite3_free(pCsr->zDir);
if( pCsr->pDir ){
closedir(pCsr->pDir);
pCsr->pDir = 0;
}
zDir = (const char*)sqlite3_value_text(argv[0]);
nDir = sqlite3_value_bytes(argv[0]);
pCsr->zDir = sqlite3_malloc(nDir+1);
if( pCsr->zDir==0 ) return SQLITE_NOMEM;
memcpy(pCsr->zDir, zDir, nDir+1);
pCsr->pDir = opendir(pCsr->zDir);
return fsdirNext(pVtabCursor);
}
/*
** xEof method implementation.
*/
static int fsdirEof(sqlite3_vtab_cursor *cur){
FsdirCsr *pCsr = (FsdirCsr*)cur;
return pCsr->pDir==0;
}
/*
** xColumn method implementation.
*/
static int fsdirColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
FsdirCsr *pCsr = (FsdirCsr*)cur;
switch( i ){
case 0: /* dir */
sqlite3_result_text(ctx, pCsr->zDir, -1, SQLITE_STATIC);
break;
case 1: /* name */
sqlite3_result_text(ctx, pCsr->entry.d_name, -1, SQLITE_TRANSIENT);
break;
default:
assert( 0 );
}
return SQLITE_OK;
}
/*
** xRowid method implementation.
*/
static int fsdirRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
FsdirCsr *pCsr = (FsdirCsr*)cur;
*pRowid = pCsr->iRowid;
return SQLITE_OK;
}
/*
** End of fsdir implementation.
*************************************************************************/
/*************************************************************************
** Start of fstree implementation.
*/
typedef struct FstreeVtab FstreeVtab;
typedef struct FstreeCsr FstreeCsr;
struct FstreeVtab {
sqlite3_vtab base;
sqlite3 *db;
};
struct FstreeCsr {
sqlite3_vtab_cursor base;
sqlite3_stmt *pStmt; /* Statement to list paths */
int fd; /* File descriptor open on current path */
};
/*
** This function is the implementation of both the xConnect and xCreate
** methods of the fstree virtual table.
**
** The argv[] array contains the following:
**
** argv[0] -> module name ("fs")
** argv[1] -> database name
** argv[2] -> table name
** argv[...] -> other module argument fields.
*/
static int fstreeConnect(
sqlite3 *db,
void *pAux,
int argc, const char *const*argv,
sqlite3_vtab **ppVtab,
char **pzErr
){
FstreeVtab *pTab;
if( argc!=3 ){
*pzErr = sqlite3_mprintf("wrong number of arguments");
return SQLITE_ERROR;
}
pTab = (FstreeVtab *)sqlite3_malloc(sizeof(FstreeVtab));
if( !pTab ) return SQLITE_NOMEM;
memset(pTab, 0, sizeof(FstreeVtab));
pTab->db = db;
*ppVtab = &pTab->base;
sqlite3_declare_vtab(db, "CREATE TABLE xyz(path, size, data);");
return SQLITE_OK;
}
/*
** xDestroy/xDisconnect implementation.
*/
static int fstreeDisconnect(sqlite3_vtab *pVtab){
sqlite3_free(pVtab);
return SQLITE_OK;
}
/*
** xBestIndex implementation. The only constraint supported is:
**
** (dir = ?)
*/
static int fstreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
int ii;
for(ii=0; ii<pIdxInfo->nConstraint; ii++){
struct sqlite3_index_constraint const *p = &pIdxInfo->aConstraint[ii];
if( p->iColumn==0 && p->usable && (
p->op==SQLITE_INDEX_CONSTRAINT_GLOB
|| p->op==SQLITE_INDEX_CONSTRAINT_LIKE
|| p->op==SQLITE_INDEX_CONSTRAINT_EQ
)){
struct sqlite3_index_constraint_usage *pUsage;
pUsage = &pIdxInfo->aConstraintUsage[ii];
pIdxInfo->idxNum = p->op;
pUsage->argvIndex = 1;
pIdxInfo->estimatedCost = 100000.0;
return SQLITE_OK;
}
}
pIdxInfo->estimatedCost = 1000000000.0;
return SQLITE_OK;
}
/*
** xOpen implementation.
**
** Open a new fstree cursor.
*/
static int fstreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
FstreeCsr *pCur;
pCur = (FstreeCsr*)sqlite3_malloc(sizeof(FstreeCsr));
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(FstreeCsr));
pCur->fd = -1;
*ppCursor = &pCur->base;
return SQLITE_OK;
}
static void fstreeCloseFd(FstreeCsr *pCsr){
if( pCsr->fd>=0 ){
close(pCsr->fd);
pCsr->fd = -1;
}
}
/*
** Close a fstree cursor.
*/
static int fstreeClose(sqlite3_vtab_cursor *cur){
FstreeCsr *pCsr = (FstreeCsr*)cur;
sqlite3_finalize(pCsr->pStmt);
fstreeCloseFd(pCsr);
sqlite3_free(pCsr);
return SQLITE_OK;
}
/*
** Skip the cursor to the next entry.
*/
static int fstreeNext(sqlite3_vtab_cursor *cur){
FstreeCsr *pCsr = (FstreeCsr*)cur;
int rc;
fstreeCloseFd(pCsr);
rc = sqlite3_step(pCsr->pStmt);
if( rc!=SQLITE_ROW ){
rc = sqlite3_finalize(pCsr->pStmt);
pCsr->pStmt = 0;
}else{
rc = SQLITE_OK;
pCsr->fd = open((const char*)sqlite3_column_text(pCsr->pStmt, 0), O_RDONLY);
}
return rc;
}
/*
** xFilter method implementation.
*/
static int fstreeFilter(
sqlite3_vtab_cursor *pVtabCursor,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv
){
FstreeCsr *pCsr = (FstreeCsr*)pVtabCursor;
FstreeVtab *pTab = (FstreeVtab*)(pCsr->base.pVtab);
int rc;
const char *zSql =
"WITH r(d) AS ("
" SELECT CASE WHEN dir=?2 THEN ?3 ELSE dir END || '/' || name "
" FROM fsdir WHERE dir=?1 AND name NOT LIKE '.%'"
" UNION ALL"
" SELECT dir || '/' || name FROM r, fsdir WHERE dir=d AND name NOT LIKE '.%'"
") SELECT d FROM r;";
char *zRoot;
int nRoot;
char *zPrefix;
int nPrefix;
const char *zDir;
int nDir;
char aWild[2] = { '\0', '\0' };
#if SQLITE_OS_WIN
zRoot = sqlite3_mprintf("%s%c", getenv("SystemDrive"), '/');
nRoot = strlen(zRoot);
zPrefix = sqlite3_mprintf("%s", getenv("SystemDrive"));
nPrefix = strlen(zPrefix);
#else
zRoot = "/";
nRoot = 1;
zPrefix = "";
nPrefix = 0;
#endif
zDir = zRoot;
nDir = nRoot;
fstreeCloseFd(pCsr);
sqlite3_finalize(pCsr->pStmt);
pCsr->pStmt = 0;
rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
if( rc!=SQLITE_OK ) return rc;
if( idxNum ){
const char *zQuery = (const char*)sqlite3_value_text(argv[0]);
switch( idxNum ){
case SQLITE_INDEX_CONSTRAINT_GLOB:
aWild[0] = '*';
aWild[1] = '?';
break;
case SQLITE_INDEX_CONSTRAINT_LIKE:
aWild[0] = '_';
aWild[1] = '%';
break;
}
if( sqlite3_strnicmp(zQuery, zPrefix, nPrefix)==0 ){
int i;
for(i=nPrefix; zQuery[i]; i++){
if( zQuery[i]==aWild[0] || zQuery[i]==aWild[1] ) break;
if( zQuery[i]=='/' ) nDir = i;
}
zDir = zQuery;
}
}
sqlite3_bind_text(pCsr->pStmt, 1, zDir, nDir, SQLITE_TRANSIENT);
sqlite3_bind_text(pCsr->pStmt, 2, zRoot, nRoot, SQLITE_TRANSIENT);
sqlite3_bind_text(pCsr->pStmt, 3, zPrefix, nPrefix, SQLITE_TRANSIENT);
#if SQLITE_OS_WIN
sqlite3_free(zPrefix);
sqlite3_free(zRoot);
#endif
return fstreeNext(pVtabCursor);
}
/*
** xEof method implementation.
*/
static int fstreeEof(sqlite3_vtab_cursor *cur){
FstreeCsr *pCsr = (FstreeCsr*)cur;
return pCsr->pStmt==0;
}
/*
** xColumn method implementation.
*/
static int fstreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
FstreeCsr *pCsr = (FstreeCsr*)cur;
if( i==0 ){ /* path */
sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pStmt, 0));
}else{
struct stat sBuf;
fstat(pCsr->fd, &sBuf);
if( S_ISREG(sBuf.st_mode) ){
if( i==1 ){
sqlite3_result_int64(ctx, sBuf.st_size);
}else{
int nRead;
char *aBuf = sqlite3_malloc(sBuf.st_mode+1);
if( !aBuf ) return SQLITE_NOMEM;
nRead = read(pCsr->fd, aBuf, sBuf.st_mode);
if( nRead!=sBuf.st_mode ){
return SQLITE_IOERR;
}
sqlite3_result_blob(ctx, aBuf, nRead, SQLITE_TRANSIENT);
sqlite3_free(aBuf);
}
}
}
return SQLITE_OK;
}
/*
** xRowid method implementation.
*/
static int fstreeRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
*pRowid = 0;
return SQLITE_OK;
}
/*
** End of fstree implementation.
*************************************************************************/
/*
** This function is the implementation of both the xConnect and xCreate
** methods of the fs virtual table.
@@ -633,7 +109,7 @@ static int fsConnect(
memcpy(pVtab->zTbl, zTbl, strlen(zTbl));
memcpy(pVtab->zDb, zDb, strlen(zDb));
*ppVtab = &pVtab->base;
sqlite3_declare_vtab(db, "CREATE TABLE x(path TEXT, data TEXT)");
sqlite3_declare_vtab(db, "CREATE TABLE xyz(path TEXT, data TEXT)");
return SQLITE_OK;
}
@@ -712,15 +188,15 @@ static int fsFilter(
static int fsColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
fs_cursor *pCur = (fs_cursor*)cur;
assert( i==0 || i==1 || i==2 );
assert( i==0 || i==1 );
if( i==0 ){
sqlite3_result_value(ctx, sqlite3_column_value(pCur->pStmt, 0));
}else{
const char *zFile = (const char *)sqlite3_column_text(pCur->pStmt, 1);
struct stat sbuf;
int fd;
int n;
fd = open(zFile, O_RDONLY);
if( fd<0 ) return SQLITE_IOERR;
fstat(fd, &sbuf);
@@ -808,52 +284,6 @@ static sqlite3_module fsModule = {
0, /* xRename */
};
static sqlite3_module fsdirModule = {
0, /* iVersion */
fsdirConnect, /* xCreate */
fsdirConnect, /* xConnect */
fsdirBestIndex, /* xBestIndex */
fsdirDisconnect, /* xDisconnect */
fsdirDisconnect, /* xDestroy */
fsdirOpen, /* xOpen - open a cursor */
fsdirClose, /* xClose - close a cursor */
fsdirFilter, /* xFilter - configure scan constraints */
fsdirNext, /* xNext - advance a cursor */
fsdirEof, /* xEof - check for end of scan */
fsdirColumn, /* xColumn - read data */
fsdirRowid, /* xRowid - read data */
0, /* xUpdate */
0, /* xBegin */
0, /* xSync */
0, /* xCommit */
0, /* xRollback */
0, /* xFindMethod */
0, /* xRename */
};
static sqlite3_module fstreeModule = {
0, /* iVersion */
fstreeConnect, /* xCreate */
fstreeConnect, /* xConnect */
fstreeBestIndex, /* xBestIndex */
fstreeDisconnect, /* xDisconnect */
fstreeDisconnect, /* xDestroy */
fstreeOpen, /* xOpen - open a cursor */
fstreeClose, /* xClose - close a cursor */
fstreeFilter, /* xFilter - configure scan constraints */
fstreeNext, /* xNext - advance a cursor */
fstreeEof, /* xEof - check for end of scan */
fstreeColumn, /* xColumn - read data */
fstreeRowid, /* xRowid - read data */
0, /* xUpdate */
0, /* xBegin */
0, /* xSync */
0, /* xCommit */
0, /* xRollback */
0, /* xFindMethod */
0, /* xRename */
};
/*
** Decode a pointer to an sqlite3 object.
*/
@@ -876,8 +306,6 @@ static int register_fs_module(
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite3_create_module(db, "fs", &fsModule, (void *)interp);
sqlite3_create_module(db, "fsdir", &fsdirModule, 0);
sqlite3_create_module(db, "fstree", &fstreeModule, 0);
#endif
return TCL_OK;
}
+1 -1
View File
@@ -34,7 +34,7 @@ static void statusFunc(
int argc,
sqlite3_value **argv
){
int op = 0, mx, cur, resetFlag, rc;
int op, mx, cur, resetFlag, rc;
if( sqlite3_value_type(argv[0])==SQLITE_INTEGER ){
op = sqlite3_value_int(argv[0]);
}else if( sqlite3_value_type(argv[0])==SQLITE_TEXT ){
+3 -4
View File
@@ -222,8 +222,7 @@ static int faultsimInstall(int install){
assert( memcmp(&m2, &memfault.m, sizeof(m2))==0 );
rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memfault.m);
sqlite3_test_control(SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS,
(void*)0, (void*)0);
sqlite3_test_control(SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, 0, 0);
}
if( rc==SQLITE_OK ){
@@ -911,7 +910,7 @@ static int test_config_scratch(
free(buf);
if( sz<0 ){
buf = 0;
rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, (void*)0, 0, 0);
rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, 0, 0, 0);
}else{
buf = malloc( sz*N + 1 );
rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, buf, sz, N);
@@ -958,7 +957,7 @@ static int test_config_pagecache(
Tcl_SetObjResult(interp, pRes);
if( sz<0 ){
sqlite3_config(SQLITE_CONFIG_PAGECACHE, (void*)0, 0, 0);
sqlite3_config(SQLITE_CONFIG_PAGECACHE, 0, 0, 0);
}else{
buf = malloc( sz*N );
sqlite3_config(SQLITE_CONFIG_PAGECACHE, buf, sz, N);
+11 -6
View File
@@ -189,11 +189,8 @@ static struct {
int isInitialized;
/* For run-time access any of the other global data structures in this
** shim, the following mutex must be held. In practice, all this mutex
** protects is add/remove operations to/from the linked list of group objects
** starting at pGroups below. More specifically, it protects the value of
** pGroups itself, and the pNext/pPrev fields of each multiplexGroup
** structure. */
** shim, the following mutex must be held.
*/
sqlite3_mutex *pMutex;
/* List of multiplexGroup objects.
@@ -761,8 +758,11 @@ static int multiplexRead(
multiplexConn *p = (multiplexConn*)pConn;
multiplexGroup *pGroup = p->pGroup;
int rc = SQLITE_OK;
int nMutex = 0;
multiplexEnter(); nMutex++;
if( !pGroup->bEnabled ){
sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0);
multiplexLeave(); nMutex--;
if( pSubOpen==0 ){
rc = SQLITE_IOERR_READ;
}else{
@@ -772,7 +772,9 @@ static int multiplexRead(
while( iAmt > 0 ){
int i = (int)(iOfst / pGroup->szChunk);
sqlite3_file *pSubOpen;
if( nMutex==0 ){ multiplexEnter(); nMutex++; }
pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL, 1);
multiplexLeave(); nMutex--;
if( pSubOpen ){
int extra = ((int)(iOfst % pGroup->szChunk) + iAmt) - pGroup->szChunk;
if( extra<0 ) extra = 0;
@@ -789,7 +791,8 @@ static int multiplexRead(
}
}
}
assert( nMutex==0 || nMutex==1 );
if( nMutex ) multiplexLeave();
return rc;
}
@@ -806,6 +809,7 @@ static int multiplexWrite(
multiplexConn *p = (multiplexConn*)pConn;
multiplexGroup *pGroup = p->pGroup;
int rc = SQLITE_OK;
multiplexEnter();
if( !pGroup->bEnabled ){
sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0);
if( pSubOpen==0 ){
@@ -830,6 +834,7 @@ static int multiplexWrite(
}
}
}
multiplexLeave();
return rc;
}
+28 -168
View File
@@ -23,15 +23,6 @@
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Characters that make up the idxStr created by xBestIndex for xFilter.
*/
#define TCLVAR_NAME_EQ 'e'
#define TCLVAR_NAME_MATCH 'm'
#define TCLVAR_VALUE_GLOB 'g'
#define TCLVAR_VALUE_REGEXP 'r'
#define TCLVAR_VALUE_LIKE 'l'
typedef struct tclvar_vtab tclvar_vtab;
typedef struct tclvar_cursor tclvar_cursor;
@@ -164,44 +155,15 @@ static int tclvarFilter(
){
tclvar_cursor *pCur = (tclvar_cursor *)pVtabCursor;
Tcl_Interp *interp = ((tclvar_vtab *)(pVtabCursor->pVtab))->interp;
Tcl_Obj *p = Tcl_NewStringObj("tclvar_filter_cmd", -1);
const char *zEq = "";
const char *zMatch = "";
const char *zGlob = "";
const char *zRegexp = "";
const char *zLike = "";
int i;
for(i=0; idxStr[i]; i++){
switch( idxStr[i] ){
case TCLVAR_NAME_EQ:
zEq = (const char*)sqlite3_value_text(argv[i]);
break;
case TCLVAR_NAME_MATCH:
zMatch = (const char*)sqlite3_value_text(argv[i]);
break;
case TCLVAR_VALUE_GLOB:
zGlob = (const char*)sqlite3_value_text(argv[i]);
break;
case TCLVAR_VALUE_REGEXP:
zRegexp = (const char*)sqlite3_value_text(argv[i]);
break;
case TCLVAR_VALUE_LIKE:
zLike = (const char*)sqlite3_value_text(argv[i]);
break;
default:
assert( 0 );
}
}
Tcl_Obj *p = Tcl_NewStringObj("info vars", -1);
Tcl_IncrRefCount(p);
Tcl_ListObjAppendElement(0, p, Tcl_NewStringObj(zEq, -1));
Tcl_ListObjAppendElement(0, p, Tcl_NewStringObj(zMatch, -1));
Tcl_ListObjAppendElement(0, p, Tcl_NewStringObj(zGlob, -1));
Tcl_ListObjAppendElement(0, p, Tcl_NewStringObj(zRegexp, -1));
Tcl_ListObjAppendElement(0, p, Tcl_NewStringObj(zLike, -1));
assert( argc==0 || argc==1 );
if( argc==1 ){
Tcl_Obj *pArg = Tcl_NewStringObj((char*)sqlite3_value_text(argv[0]), -1);
Tcl_ListObjAppendElement(0, p, pArg);
}
Tcl_EvalObjEx(interp, p, TCL_EVAL_GLOBAL);
if( pCur->pList1 ){
Tcl_DecrRefCount(pCur->pList1);
@@ -214,6 +176,7 @@ static int tclvarFilter(
pCur->i2 = 0;
pCur->pList1 = Tcl_GetObjResult(interp);
Tcl_IncrRefCount(pCur->pList1);
assert( pCur->i1==0 && pCur->i2==0 && pCur->pList2==0 );
Tcl_DecrRefCount(p);
return tclvarNext(pVtabCursor);
@@ -261,113 +224,32 @@ static int tclvarEof(sqlite3_vtab_cursor *cur){
return (pCur->pList2?0:1);
}
/*
** If nul-terminated string zStr does not already contain the character
** passed as the second argument, append it and return 0. Or, if there is
** already an instance of x in zStr, do nothing return 1;
**
** There is guaranteed to be enough room in the buffer pointed to by zStr
** for the new character and nul-terminator.
*/
static int tclvarAddToIdxstr(char *zStr, char x){
int i;
for(i=0; zStr[i]; i++){
if( zStr[i]==x ) return 1;
}
zStr[i] = x;
zStr[i+1] = '\0';
return 0;
}
/*
** Return true if variable $::tclvar_set_omit exists and is set to true.
** False otherwise.
*/
static int tclvarSetOmit(Tcl_Interp *interp){
int rc;
int res = 0;
Tcl_Obj *pRes;
rc = Tcl_Eval(interp,
"expr {[info exists ::tclvar_set_omit] && $::tclvar_set_omit}"
);
if( rc==TCL_OK ){
pRes = Tcl_GetObjResult(interp);
rc = Tcl_GetBooleanFromObj(0, pRes, &res);
}
return (rc==TCL_OK && res);
}
/*
** The xBestIndex() method. This virtual table supports the following
** operators:
**
** name = ? (omit flag clear)
** name MATCH ? (omit flag set)
** value GLOB ? (omit flag set iff $::tclvar_set_omit)
** value REGEXP ? (omit flag set iff $::tclvar_set_omit)
** value LIKE ? (omit flag set iff $::tclvar_set_omit)
**
** For each constraint present, the corresponding TCLVAR_XXX character is
** appended to the idxStr value.
*/
static int tclvarBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
tclvar_vtab *pTab = (tclvar_vtab*)tab;
int ii;
char *zStr = sqlite3_malloc(32);
int iStr = 0;
if( zStr==0 ) return SQLITE_NOMEM;
zStr[0] = '\0';
for(ii=0; ii<pIdxInfo->nConstraint; ii++){
struct sqlite3_index_constraint const *pCons = &pIdxInfo->aConstraint[ii];
struct sqlite3_index_constraint_usage *pUsage;
pUsage = &pIdxInfo->aConstraintUsage[ii];
if( pCons->usable ){
/* name = ? */
if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ && pCons->iColumn==0 ){
if( 0==tclvarAddToIdxstr(zStr, TCLVAR_NAME_EQ) ){
pUsage->argvIndex = ++iStr;
pUsage->omit = 0;
}
}
/* name MATCH ? */
if( pCons->op==SQLITE_INDEX_CONSTRAINT_MATCH && pCons->iColumn==0 ){
if( 0==tclvarAddToIdxstr(zStr, TCLVAR_NAME_MATCH) ){
pUsage->argvIndex = ++iStr;
pUsage->omit = 1;
}
}
/* value GLOB ? */
if( pCons->op==SQLITE_INDEX_CONSTRAINT_GLOB && pCons->iColumn==2 ){
if( 0==tclvarAddToIdxstr(zStr, TCLVAR_VALUE_GLOB) ){
pUsage->argvIndex = ++iStr;
pUsage->omit = tclvarSetOmit(pTab->interp);
}
}
/* value REGEXP ? */
if( pCons->op==SQLITE_INDEX_CONSTRAINT_REGEXP && pCons->iColumn==2 ){
if( 0==tclvarAddToIdxstr(zStr, TCLVAR_VALUE_REGEXP) ){
pUsage->argvIndex = ++iStr;
pUsage->omit = tclvarSetOmit(pTab->interp);
}
}
/* value LIKE ? */
if( pCons->op==SQLITE_INDEX_CONSTRAINT_LIKE && pCons->iColumn==2 ){
if( 0==tclvarAddToIdxstr(zStr, TCLVAR_VALUE_LIKE) ){
pUsage->argvIndex = ++iStr;
pUsage->omit = tclvarSetOmit(pTab->interp);
}
}
if( pCons->iColumn==0 && pCons->usable
&& pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){
struct sqlite3_index_constraint_usage *pUsage;
pUsage = &pIdxInfo->aConstraintUsage[ii];
pUsage->omit = 0;
pUsage->argvIndex = 1;
return SQLITE_OK;
}
}
for(ii=0; ii<pIdxInfo->nConstraint; ii++){
struct sqlite3_index_constraint const *pCons = &pIdxInfo->aConstraint[ii];
if( pCons->iColumn==0 && pCons->usable
&& pCons->op==SQLITE_INDEX_CONSTRAINT_MATCH ){
struct sqlite3_index_constraint_usage *pUsage;
pUsage = &pIdxInfo->aConstraintUsage[ii];
pUsage->omit = 1;
pUsage->argvIndex = 1;
return SQLITE_OK;
}
}
pIdxInfo->idxStr = zStr;
pIdxInfo->needToFreeIdxStr = 1;
return SQLITE_OK;
}
@@ -413,7 +295,6 @@ static int register_tclvar_module(
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
int rc = TCL_OK;
sqlite3 *db;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB");
@@ -421,30 +302,9 @@ static int register_tclvar_module(
}
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite3_create_module(db, "tclvar", &tclvarModule, (void*)interp);
rc = Tcl_Eval(interp,
"proc like {pattern str} {\n"
" set p [string map {% * _ ?} $pattern]\n"
" string match $p $str\n"
"}\n"
"proc tclvar_filter_cmd {eq match glob regexp like} {\n"
" set res {}\n"
" set pattern $eq\n"
" if {$pattern=={}} { set pattern $match }\n"
" if {$pattern=={}} { set pattern * }\n"
" foreach v [uplevel #0 info vars $pattern] {\n"
" if {($glob=={} || [string match $glob [uplevel #0 set $v]])\n"
" && ($like=={} || [like $like [uplevel #0 set $v]])\n"
" && ($regexp=={} || [regexp $regexp [uplevel #0 set $v]])\n"
" } {\n"
" lappend res $v\n"
" }\n"
" }\n"
" set res\n"
"}\n"
);
sqlite3_create_module(db, "tclvar", &tclvarModule, (void *)interp);
#endif
return rc;
return TCL_OK;
}
#endif
-157
View File
@@ -1,157 +0,0 @@
/*
** 2015 November 30
**
** 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 code to implement most of the opendir() family of
** POSIX functions on Win32 using the MSVCRT.
*/
#if defined(_WIN32) && defined(_MSC_VER)
#include "test_windirent.h"
/*
** Implementation of the POSIX opendir() function using the MSVCRT.
*/
LPDIR opendir(
const char *dirname
){
struct _finddata_t data;
LPDIR dirp = (LPDIR)sqlite3_malloc(sizeof(DIR));
SIZE_T namesize = sizeof(data.name) / sizeof(data.name[0]);
if( dirp==NULL ) return NULL;
memset(dirp, 0, sizeof(DIR));
/* TODO: Remove this if Unix-style root paths are not used. */
if( sqlite3_stricmp(dirname, "/")==0 ){
dirname = getenv("SystemDrive");
}
_snprintf(data.name, namesize, "%s\\*", dirname);
dirp->d_handle = _findfirst(data.name, &data);
if( dirp->d_handle==BAD_INTPTR_T ){
closedir(dirp);
return NULL;
}
/* TODO: Remove this block to allow hidden and system files. */
if( data.attrib&_A_HIDDEN || data.attrib&_A_SYSTEM ){
if( _findnext(dirp->d_handle, &data)==-1 ){
closedir(dirp);
return NULL;
}
}
dirp->d_first.d_attributes = data.attrib;
strncpy(dirp->d_first.d_name, data.name, NAME_MAX);
dirp->d_first.d_name[NAME_MAX] = '\0';
return dirp;
}
/*
** Implementation of the POSIX readdir() function using the MSVCRT.
*/
LPDIRENT readdir(
LPDIR dirp
){
struct _finddata_t data;
if( dirp==NULL ) return NULL;
if( dirp->d_first.d_ino==0 ){
dirp->d_first.d_ino++;
dirp->d_next.d_ino++;
return &dirp->d_first;
}
next:
if( _findnext(dirp->d_handle, &data)==-1 ) return NULL;
/* TODO: Remove this block to allow hidden and system files. */
if( data.attrib&_A_HIDDEN ) goto next;
if( data.attrib&_A_SYSTEM ) goto next;
dirp->d_next.d_ino++;
dirp->d_next.d_attributes = data.attrib;
strncpy(dirp->d_next.d_name, data.name, NAME_MAX);
dirp->d_next.d_name[NAME_MAX] = '\0';
return &dirp->d_next;
}
/*
** Implementation of the POSIX readdir_r() function using the MSVCRT.
*/
INT readdir_r(
LPDIR dirp,
LPDIRENT entry,
LPDIRENT *result
){
struct _finddata_t data;
if( dirp==NULL ) return EBADF;
if( dirp->d_first.d_ino==0 ){
dirp->d_first.d_ino++;
dirp->d_next.d_ino++;
entry->d_ino = dirp->d_first.d_ino;
entry->d_attributes = dirp->d_first.d_attributes;
strncpy(entry->d_name, dirp->d_first.d_name, NAME_MAX);
entry->d_name[NAME_MAX] = '\0';
*result = entry;
return 0;
}
next:
if( _findnext(dirp->d_handle, &data)==-1 ){
*result = NULL;
return ENOENT;
}
/* TODO: Remove this block to allow hidden and system files. */
if( data.attrib&_A_HIDDEN ) goto next;
if( data.attrib&_A_SYSTEM ) goto next;
entry->d_ino = (ino_t)-1; /* not available */
entry->d_attributes = data.attrib;
strncpy(entry->d_name, data.name, NAME_MAX);
entry->d_name[NAME_MAX] = '\0';
*result = entry;
return 0;
}
/*
** Implementation of the POSIX closedir() function using the MSVCRT.
*/
INT closedir(
LPDIR dirp
){
INT result = 0;
if( dirp==NULL ) return EINVAL;
if( dirp->d_handle!=NULL_INTPTR_T && dirp->d_handle!=BAD_INTPTR_T ){
result = _findclose(dirp->d_handle);
}
sqlite3_free(dirp);
return result;
}
#endif /* defined(WIN32) && defined(_MSC_VER) */
-105
View File
@@ -1,105 +0,0 @@
/*
** 2015 November 30
**
** 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 declarations for most of the opendir() family of
** POSIX functions on Win32 using the MSVCRT.
*/
#if defined(_WIN32) && defined(_MSC_VER)
/*
** We need several data types from the Windows SDK header.
*/
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
/*
** We need several support functions from the SQLite core.
*/
#include "sqlite3.h"
/*
** We need several things from the ANSI and MSVCRT headers.
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <io.h>
#include <limits.h>
/*
** We may need to provide the "ino_t" type.
*/
#ifndef INO_T_DEFINED
#define INO_T_DEFINED
typedef unsigned short ino_t;
#endif
/*
** We need to define "NAME_MAX" if it was not present in "limits.h".
*/
#ifndef NAME_MAX
# ifdef FILENAME_MAX
# define NAME_MAX (FILENAME_MAX)
# else
# define NAME_MAX (260)
# endif
#endif
/*
** We need to define "NULL_INTPTR_T" and "BAD_INTPTR_T".
*/
#ifndef NULL_INTPTR_T
# define NULL_INTPTR_T ((intptr_t)(0))
#endif
#ifndef BAD_INTPTR_T
# define BAD_INTPTR_T ((intptr_t)(-1))
#endif
/*
** We need to provide the necessary structures and related types.
*/
typedef struct DIRENT DIRENT;
typedef struct DIR DIR;
typedef DIRENT *LPDIRENT;
typedef DIR *LPDIR;
struct DIRENT {
ino_t d_ino; /* Sequence number, do not use. */
unsigned d_attributes; /* Win32 file attributes. */
char d_name[NAME_MAX + 1]; /* Name within the directory. */
};
struct DIR {
intptr_t d_handle; /* Value returned by "_findfirst". */
DIRENT d_first; /* DIRENT constructed based on "_findfirst". */
DIRENT d_next; /* DIRENT constructed based on "_findnext". */
};
/*
** Finally, we can provide the function prototypes for the opendir(),
** readdir(), readdir_r(), and closedir() POSIX functions.
*/
extern LPDIR opendir(const char *dirname);
extern LPDIRENT readdir(LPDIR dirp);
extern INT readdir_r(LPDIR dirp, LPDIRENT entry, LPDIRENT *result);
extern INT closedir(LPDIR dirp);
#endif /* defined(WIN32) && defined(_MSC_VER) */
+23 -4
View File
@@ -559,12 +559,31 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
*/
assert( pTable!=0 );
if( (v = sqlite3GetVdbe(pParse))!=0 ){
sqlite3NestedParse(pParse,
"DELETE FROM %Q.%s WHERE name=%Q AND type='trigger'",
db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pTrigger->zName
);
int base;
static const int iLn = VDBE_OFFSET_LINENO(2);
static const VdbeOpList dropTrigger[] = {
{ OP_Rewind, 0, ADDR(9), 0},
{ OP_String8, 0, 1, 0}, /* 1 */
{ OP_Column, 0, 1, 2},
{ OP_Ne, 2, ADDR(8), 1},
{ OP_String8, 0, 1, 0}, /* 4: "trigger" */
{ OP_Column, 0, 0, 2},
{ OP_Ne, 2, ADDR(8), 1},
{ OP_Delete, 0, 0, 0},
{ OP_Next, 0, ADDR(1), 0}, /* 8 */
};
sqlite3BeginWriteOperation(pParse, 0, iDb);
sqlite3OpenMasterTable(pParse, iDb);
base = sqlite3VdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger, iLn);
sqlite3VdbeChangeP4(v, base+1, pTrigger->zName, P4_TRANSIENT);
sqlite3VdbeChangeP4(v, base+4, "trigger", P4_STATIC);
sqlite3ChangeCookie(pParse, iDb);
sqlite3VdbeAddOp2(v, OP_Close, 0, 0);
sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0);
if( pParse->nMem<3 ){
pParse->nMem = 3;
}
}
}
+3 -5
View File
@@ -263,12 +263,10 @@ void sqlite3Update(
assert( chngPk==0 || chngPk==1 );
chngKey = chngRowid + chngPk;
/* The SET expressions are not actually used inside the WHERE loop.
** So reset the colUsed mask. Unless this is a virtual table. In that
** case, set all bits of the colUsed mask (to ensure that the virtual
** table implementation makes all columns available).
/* The SET expressions are not actually used inside the WHERE loop.
** So reset the colUsed mask
*/
pTabList->a[0].colUsed = IsVirtual(pTab) ? (Bitmask)-1 : 0;
pTabList->a[0].colUsed = 0;
hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey);
+2 -2
View File
@@ -37,13 +37,13 @@
#include <assert.h>
#include "vdbeInt.h"
#if !defined(SQLITE_AMALGAMATION) && SQLITE_BYTEORDER==0
#ifndef SQLITE_AMALGAMATION
/*
** The following constant value is used by the SQLITE_BIGENDIAN and
** SQLITE_LITTLEENDIAN macros.
*/
const int sqlite3one = 1;
#endif /* SQLITE_AMALGAMATION && SQLITE_BYTEORDER==0 */
#endif /* SQLITE_AMALGAMATION */
/*
** This lookup table is used to help decode the first byte of
+9 -8
View File
@@ -1088,7 +1088,6 @@ case OP_String: { /* out2 */
pOut->n = pOp->p1;
pOut->enc = encoding;
UPDATE_MAX_BLOBSIZE(pOut);
#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
if( pOp->p5 ){
assert( pOp->p3>0 );
assert( pOp->p3<=(p->nMem-p->nCursor) );
@@ -1096,7 +1095,6 @@ case OP_String: { /* out2 */
assert( pIn3->flags & MEM_Int );
if( pIn3->u.i ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term;
}
#endif
break;
}
@@ -1981,7 +1979,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
*/
if( pOp->p5 & SQLITE_STOREP2 ){
pOut = &aMem[pOp->p2];
memAboutToChange(p, pOut);
MemSetTypeFlag(pOut, MEM_Null);
REGISTER_TRACE(pOp->p2, pOut);
}else{
@@ -2378,12 +2375,20 @@ case OP_Column: {
u16 fx; /* pDest->flags value */
Mem *pReg; /* PseudoTable input register */
pC = p->apCsr[pOp->p1];
if( pC->eCurType==CURTYPE_PSEUDO ) goto skip_moveto;
pOp->opcode = OP_BColumn;
case OP_BColumn:
pC = p->apCsr[pOp->p1];
rc = sqlite3VdbeCursorMoveto(pC);
if( rc ) goto abort_due_to_error;
skip_moveto:
p2 = pOp->p2;
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
pDest = &aMem[pOp->p3];
memAboutToChange(p, pDest);
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
assert( p2<pC->nField );
aOffset = pC->aOffset;
@@ -2393,8 +2398,6 @@ case OP_Column: {
pCrsr = pC->uc.pCursor;
/* If the cursor cache is stale, bring it up-to-date */
rc = sqlite3VdbeCursorMoveto(pC);
if( rc ) goto abort_due_to_error;
if( pC->cacheStatus!=p->cacheCtr ){
if( pC->nullRow ){
if( pC->eCurType==CURTYPE_PSEUDO ){
@@ -2524,8 +2527,6 @@ case OP_Column: {
rc = SQLITE_CORRUPT_BKPT;
goto op_column_error;
}
}else{
VVA_ONLY( t = 0; ) /* Only needed by assert() statements */
}
/* If after trying to extract new entries from the header, nHdrParsed is
+49 -45
View File
@@ -349,7 +349,7 @@ int sqlite3VdbeMakeLabel(Vdbe *v){
if( p->aLabel ){
p->aLabel[i] = -1;
}
return ADDR(i);
return -1-i;
}
/*
@@ -359,7 +359,7 @@ int sqlite3VdbeMakeLabel(Vdbe *v){
*/
void sqlite3VdbeResolveLabel(Vdbe *v, int x){
Parse *p = v->pParse;
int j = ADDR(x);
int j = -1-x;
assert( v->magic==VDBE_MAGIC_INIT );
assert( j<p->nLabel );
assert( j>=0 );
@@ -586,8 +586,8 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
pOp->opflags = sqlite3OpcodeProperty[opcode];
if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
assert( ADDR(pOp->p2)<pParse->nLabel );
pOp->p2 = aLabel[ADDR(pOp->p2)];
assert( -1-pOp->p2<pParse->nLabel );
pOp->p2 = aLabel[-1-pOp->p2];
}
}
sqlite3DbFree(p->db, pParse->aLabel);
@@ -644,10 +644,15 @@ int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp, int iLineno){
addr = p->nOp;
pOut = &p->aOp[addr];
for(i=0; i<nOp; i++, aOp++, pOut++){
int p2 = aOp->p2;
pOut->opcode = aOp->opcode;
pOut->p1 = aOp->p1;
pOut->p2 = aOp->p2;
assert( aOp->p2>=0 );
if( p2<0 ){
assert( sqlite3OpcodeProperty[pOut->opcode] & OPFLG_JUMP );
pOut->p2 = addr + ADDR(p2);
}else{
pOut->p2 = p2;
}
pOut->p3 = aOp->p3;
pOut->p4type = P4_NOTUSED;
pOut->p4.p = 0;
@@ -832,6 +837,7 @@ void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
freeP4(db, pOp->p4type, pOp->p4.p);
memset(pOp, 0, sizeof(pOp[0]));
pOp->opcode = OP_Noop;
if( addr==p->nOp-1 ) p->nOp--;
}
}
@@ -1720,31 +1726,30 @@ void sqlite3VdbeIOTraceSql(Vdbe *p){
**
** nByte is the number of bytes of space needed.
**
** pFrom points to *pnFrom bytes of available space. New space is allocated
** from the end of the pFrom buffer and *pnFrom is decremented.
** *ppFrom points to available space and pEnd points to the end of the
** available space. When space is allocated, *ppFrom is advanced past
** the end of the allocated space.
**
** *pnNeeded is a counter of the number of bytes of space that have failed
** to allocate. If there is insufficient space in pFrom to satisfy the
** request, then increment *pnNeeded by the amount of the request.
** *pnByte is a counter of the number of bytes of space that have failed
** to allocate. If there is insufficient space in *ppFrom to satisfy the
** request, then increment *pnByte by the amount of the request.
*/
static void *allocSpace(
void *pBuf, /* Where return pointer will be stored */
int nByte, /* Number of bytes to allocate */
u8 *pFrom, /* Memory available for allocation */
int *pnFrom, /* IN/OUT: Space available at pFrom */
int *pnNeeded /* If allocation cannot be made, increment *pnByte */
u8 **ppFrom, /* IN/OUT: Allocate from *ppFrom */
u8 *pEnd, /* Pointer to 1 byte past the end of *ppFrom buffer */
int *pnByte /* If allocation cannot be made, increment *pnByte */
){
assert( EIGHT_BYTE_ALIGNMENT(pFrom) );
if( pBuf==0 ){
nByte = ROUND8(nByte);
if( nByte <= *pnFrom ){
*pnFrom -= nByte;
pBuf = &pFrom[*pnFrom];
}else{
*pnNeeded += nByte;
}
assert( EIGHT_BYTE_ALIGNMENT(*ppFrom) );
if( pBuf ) return pBuf;
nByte = ROUND8(nByte);
if( &(*ppFrom)[nByte] <= pEnd ){
pBuf = (void*)*ppFrom;
*ppFrom += nByte;
}else{
*pnByte += nByte;
}
assert( EIGHT_BYTE_ALIGNMENT(pBuf) );
return pBuf;
}
@@ -1817,8 +1822,8 @@ void sqlite3VdbeMakeReady(
int nArg; /* Number of arguments in subprograms */
int nOnce; /* Number of OP_Once instructions */
int n; /* Loop counter */
int nFree; /* Available free space */
u8 *zCsr; /* Memory available for allocation */
u8 *zEnd; /* First byte past allocated memory */
int nByte; /* How much extra memory is needed */
assert( p!=0 );
@@ -1850,16 +1855,16 @@ void sqlite3VdbeMakeReady(
** an array to marshal SQL function arguments in.
*/
zCsr = (u8*)&p->aOp[p->nOp]; /* Memory avaliable for allocation */
assert( pParse->nOpAlloc*sizeof(Op) <= 0x7fffff00 );
nFree = (pParse->nOpAlloc - p->nOp)*sizeof(p->aOp[0]); /* Available space */
zEnd = (u8*)&p->aOp[pParse->nOpAlloc]; /* First byte past end of zCsr[] */
resolveP2Values(p, &nArg);
p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort);
if( pParse->explain && nMem<10 ){
nMem = 10;
}
memset(zCsr, 0, nFree);
assert( EIGHT_BYTE_ALIGNMENT(&zCsr[nFree]) );
memset(zCsr, 0, zEnd-zCsr);
zCsr += (zCsr - (u8*)0)&7;
assert( EIGHT_BYTE_ALIGNMENT(zCsr) );
p->expired = 0;
/* Memory for registers, parameters, cursor, etc, is allocated in two
@@ -1874,21 +1879,21 @@ void sqlite3VdbeMakeReady(
*/
do {
nByte = 0;
p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), zCsr, &nFree, &nByte);
p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), zCsr, &nFree, &nByte);
p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), zCsr, &nFree, &nByte);
p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), zCsr, &nFree, &nByte);
p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte);
p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte);
p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte);
p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte);
p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*),
zCsr, &nFree, &nByte);
p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, zCsr, &nFree, &nByte);
&zCsr, zEnd, &nByte);
p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, &zCsr, zEnd, &nByte);
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
p->anExec = allocSpace(p->anExec, p->nOp*sizeof(i64), zCsr, &nFree, &nByte);
p->anExec = allocSpace(p->anExec, p->nOp*sizeof(i64), &zCsr, zEnd, &nByte);
#endif
if( nByte ){
p->pFree = sqlite3DbMallocZero(db, nByte);
}
zCsr = p->pFree;
nFree = nByte;
zEnd = &zCsr[nByte];
}while( nByte && !db->mallocFailed );
p->nCursor = nCursor;
@@ -2995,13 +3000,12 @@ int sqlite3VdbeCursorRestore(VdbeCursor *p){
** not been deleted out from under the cursor, then this routine is a no-op.
*/
int sqlite3VdbeCursorMoveto(VdbeCursor *p){
if( p->eCurType==CURTYPE_BTREE ){
if( p->deferredMoveto ){
return handleDeferredMoveto(p);
}
if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
return handleMovedCursor(p);
}
assert( p->eCurType==CURTYPE_BTREE );
if( p->deferredMoveto ){
return handleDeferredMoveto(p);
}
if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
return handleMovedCursor(p);
}
return SQLITE_OK;
}
@@ -3231,7 +3235,7 @@ u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){
assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.nZero:0)
== (int)sqlite3VdbeSerialTypeLen(serial_type) );
len = pMem->n;
if( len>0 ) memcpy(buf, pMem->z, len);
memcpy(buf, pMem->z, len);
return len;
}
+83 -215
View File
@@ -272,8 +272,7 @@ int sqlite3WalTrace = 0;
/*
** Indices of various locking bytes. WAL_NREADER is the number
** of available reader locks and should be at least 3. The default
** is SQLITE_SHM_NLOCK==8 and WAL_NREADER==5.
** of available reader locks and should be at least 3.
*/
#define WAL_WRITE_LOCK 0
#define WAL_ALL_BUT_WRITE 1
@@ -293,10 +292,7 @@ typedef struct WalCkptInfo WalCkptInfo;
** The following object holds a copy of the wal-index header content.
**
** The actual header in the wal-index consists of two copies of this
** object followed by one instance of the WalCkptInfo object.
** For all versions of SQLite through 3.10.0 and probably beyond,
** the locking bytes (WalCkptInfo.aLock) start at offset 120 and
** the total header size is 136 bytes.
** object.
**
** The szPage value can be any power of 2 between 512 and 32768, inclusive.
** Or it can be 1 to represent a 65536-byte page. The latter case was
@@ -329,16 +325,6 @@ struct WalIndexHdr {
** However, a WAL_WRITE_LOCK thread can move the value of nBackfill from
** mxFrame back to zero when the WAL is reset.
**
** nBackfillAttempted is the largest value of nBackfill that a checkpoint
** has attempted to achieve. Normally nBackfill==nBackfillAtempted, however
** the nBackfillAttempted is set before any backfilling is done and the
** nBackfill is only set after all backfilling completes. So if a checkpoint
** crashes, nBackfillAttempted might be larger than nBackfill. The
** WalIndexHdr.mxFrame must never be less than nBackfillAttempted.
**
** The aLock[] field is a set of bytes used for locking. These bytes should
** never be read or written.
**
** There is one entry in aReadMark[] for each reader lock. If a reader
** holds read-lock K, then the value in aReadMark[K] is no greater than
** the mxFrame for that reader. The value READMARK_NOT_USED (0xffffffff)
@@ -378,9 +364,6 @@ struct WalIndexHdr {
struct WalCkptInfo {
u32 nBackfill; /* Number of WAL frames backfilled into DB */
u32 aReadMark[WAL_NREADER]; /* Reader marks */
u8 aLock[SQLITE_SHM_NLOCK]; /* Reserved space for locks */
u32 nBackfillAttempted; /* WAL frames perhaps written, or maybe not */
u32 notUsed0; /* Available for future enhancements */
};
#define READMARK_NOT_USED 0xffffffff
@@ -390,8 +373,9 @@ struct WalCkptInfo {
** only support mandatory file-locks, we do not read or write data
** from the region of the file on which locks are applied.
*/
#define WALINDEX_LOCK_OFFSET (sizeof(WalIndexHdr)*2+offsetof(WalCkptInfo,aLock))
#define WALINDEX_HDR_SIZE (sizeof(WalIndexHdr)*2+sizeof(WalCkptInfo))
#define WALINDEX_LOCK_OFFSET (sizeof(WalIndexHdr)*2 + sizeof(WalCkptInfo))
#define WALINDEX_LOCK_RESERVED 16
#define WALINDEX_HDR_SIZE (WALINDEX_LOCK_OFFSET+WALINDEX_LOCK_RESERVED)
/* Size of header before each frame in wal */
#define WAL_FRAME_HDRSIZE 24
@@ -450,9 +434,6 @@ struct Wal {
#ifdef SQLITE_DEBUG
u8 lockError; /* True if a locking error has occurred */
#endif
#ifdef SQLITE_ENABLE_SNAPSHOT
WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */
#endif
};
/*
@@ -808,9 +789,10 @@ static void walUnlockShared(Wal *pWal, int lockIdx){
SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED);
WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx)));
}
static int walLockExclusive(Wal *pWal, int lockIdx, int n){
static int walLockExclusive(Wal *pWal, int lockIdx, int n, int fBlock){
int rc;
if( pWal->exclusiveMode ) return SQLITE_OK;
if( fBlock ) sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_WAL_BLOCK, 0);
rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE);
WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal,
@@ -1096,7 +1078,7 @@ static int walIndexRecover(Wal *pWal){
assert( pWal->writeLock );
iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock;
nLock = SQLITE_SHM_NLOCK - iLock;
rc = walLockExclusive(pWal, iLock, nLock);
rc = walLockExclusive(pWal, iLock, nLock, 0);
if( rc ){
return rc;
}
@@ -1217,7 +1199,6 @@ finished:
*/
pInfo = walCkptInfo(pWal);
pInfo->nBackfill = 0;
pInfo->nBackfillAttempted = pWal->hdr.mxFrame;
pInfo->aReadMark[0] = 0;
for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
if( pWal->hdr.mxFrame ) pInfo->aReadMark[1] = pWal->hdr.mxFrame;
@@ -1289,11 +1270,7 @@ int sqlite3WalOpen(
/* In the amalgamation, the os_unix.c and os_win.c source files come before
** this source file. Verify that the #defines of the locking byte offsets
** in os_unix.c and os_win.c agree with the WALINDEX_LOCK_OFFSET value.
** For that matter, if the lock offset ever changes from its initial design
** value of 120, we need to know that so there is an assert() to check it.
*/
assert( 120==WALINDEX_LOCK_OFFSET );
assert( 136==WALINDEX_HDR_SIZE );
#ifdef WIN_SHM_BASE
assert( WIN_SHM_BASE==WALINDEX_LOCK_OFFSET );
#endif
@@ -1639,7 +1616,7 @@ static int walBusyLock(
){
int rc;
do {
rc = walLockExclusive(pWal, lockIdx, n);
rc = walLockExclusive(pWal, lockIdx, n, 0);
}while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) );
return rc;
}
@@ -1679,7 +1656,6 @@ static void walRestartHdr(Wal *pWal, u32 salt1){
memcpy(&pWal->hdr.aSalt[1], &salt1, 4);
walIndexWriteHdr(pWal);
pInfo->nBackfill = 0;
pInfo->nBackfillAttempted = 0;
pInfo->aReadMark[1] = 0;
for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
assert( pInfo->aReadMark[0]==0 );
@@ -1789,8 +1765,6 @@ static int walCheckpoint(
i64 nSize; /* Current size of database file */
u32 nBackfill = pInfo->nBackfill;
pInfo->nBackfillAttempted = mxSafeFrame;
/* Sync the WAL to disk */
if( sync_flags ){
rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
@@ -2083,7 +2057,7 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
walUnlockShared(pWal, WAL_WRITE_LOCK);
rc = SQLITE_READONLY_RECOVERY;
}
}else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){
}else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 1)) ){
pWal->writeLock = 1;
if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
badHdr = walIndexTryHdr(pWal, pChanged);
@@ -2174,7 +2148,6 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
int mxI; /* Index of largest aReadMark[] value */
int i; /* Loop counter */
int rc = SQLITE_OK; /* Return code */
u32 mxFrame; /* Wal frame to lock to */
assert( pWal->readLock<0 ); /* Not currently locked */
@@ -2238,12 +2211,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
}
pInfo = walCkptInfo(pWal);
if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame
#ifdef SQLITE_ENABLE_SNAPSHOT
&& (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0
|| 0==memcmp(&pWal->hdr, pWal->pSnapshot, sizeof(WalIndexHdr)))
#endif
){
if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame ){
/* The WAL has been completely backfilled (or it is empty).
** and can be safely ignored.
*/
@@ -2281,88 +2249,85 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
*/
mxReadMark = 0;
mxI = 0;
mxFrame = pWal->hdr.mxFrame;
#ifdef SQLITE_ENABLE_SNAPSHOT
if( pWal->pSnapshot && pWal->pSnapshot->mxFrame<mxFrame ){
mxFrame = pWal->pSnapshot->mxFrame;
}
#endif
for(i=1; i<WAL_NREADER; i++){
u32 thisMark = pInfo->aReadMark[i];
if( mxReadMark<=thisMark && thisMark<=mxFrame ){
if( mxReadMark<=thisMark && thisMark<=pWal->hdr.mxFrame ){
assert( thisMark!=READMARK_NOT_USED );
mxReadMark = thisMark;
mxI = i;
}
}
if( (pWal->readOnly & WAL_SHM_RDONLY)==0
&& (mxReadMark<mxFrame || mxI==0)
){
for(i=1; i<WAL_NREADER; i++){
rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1);
if( rc==SQLITE_OK ){
mxReadMark = pInfo->aReadMark[i] = mxFrame;
mxI = i;
walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
break;
}else if( rc!=SQLITE_BUSY ){
return rc;
/* There was once an "if" here. The extra "{" is to preserve indentation. */
{
if( (pWal->readOnly & WAL_SHM_RDONLY)==0
&& (mxReadMark<pWal->hdr.mxFrame || mxI==0)
){
for(i=1; i<WAL_NREADER; i++){
rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1, 0);
if( rc==SQLITE_OK ){
mxReadMark = pInfo->aReadMark[i] = pWal->hdr.mxFrame;
mxI = i;
walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
break;
}else if( rc!=SQLITE_BUSY ){
return rc;
}
}
}
}
if( mxI==0 ){
assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 );
return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK;
}
if( mxI==0 ){
assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 );
return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK;
}
rc = walLockShared(pWal, WAL_READ_LOCK(mxI));
if( rc ){
return rc==SQLITE_BUSY ? WAL_RETRY : rc;
}
/* Now that the read-lock has been obtained, check that neither the
** value in the aReadMark[] array or the contents of the wal-index
** header have changed.
**
** It is necessary to check that the wal-index header did not change
** between the time it was read and when the shared-lock was obtained
** on WAL_READ_LOCK(mxI) was obtained to account for the possibility
** that the log file may have been wrapped by a writer, or that frames
** that occur later in the log than pWal->hdr.mxFrame may have been
** copied into the database by a checkpointer. If either of these things
** happened, then reading the database with the current value of
** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry
** instead.
**
** Before checking that the live wal-index header has not changed
** since it was read, set Wal.minFrame to the first frame in the wal
** file that has not yet been checkpointed. This client will not need
** to read any frames earlier than minFrame from the wal file - they
** can be safely read directly from the database file.
**
** Because a ShmBarrier() call is made between taking the copy of
** nBackfill and checking that the wal-header in shared-memory still
** matches the one cached in pWal->hdr, it is guaranteed that the
** checkpointer that set nBackfill was not working with a wal-index
** header newer than that cached in pWal->hdr. If it were, that could
** cause a problem. The checkpointer could omit to checkpoint
** a version of page X that lies before pWal->minFrame (call that version
** A) on the basis that there is a newer version (version B) of the same
** page later in the wal file. But if version B happens to like past
** frame pWal->hdr.mxFrame - then the client would incorrectly assume
** that it can read version A from the database file. However, since
** we can guarantee that the checkpointer that set nBackfill could not
** see any pages past pWal->hdr.mxFrame, this problem does not come up.
*/
pWal->minFrame = pInfo->nBackfill+1;
walShmBarrier(pWal);
if( pInfo->aReadMark[mxI]!=mxReadMark
|| memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr))
){
walUnlockShared(pWal, WAL_READ_LOCK(mxI));
return WAL_RETRY;
}else{
assert( mxReadMark<=pWal->hdr.mxFrame );
pWal->readLock = (i16)mxI;
rc = walLockShared(pWal, WAL_READ_LOCK(mxI));
if( rc ){
return rc==SQLITE_BUSY ? WAL_RETRY : rc;
}
/* Now that the read-lock has been obtained, check that neither the
** value in the aReadMark[] array or the contents of the wal-index
** header have changed.
**
** It is necessary to check that the wal-index header did not change
** between the time it was read and when the shared-lock was obtained
** on WAL_READ_LOCK(mxI) was obtained to account for the possibility
** that the log file may have been wrapped by a writer, or that frames
** that occur later in the log than pWal->hdr.mxFrame may have been
** copied into the database by a checkpointer. If either of these things
** happened, then reading the database with the current value of
** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry
** instead.
**
** Before checking that the live wal-index header has not changed
** since it was read, set Wal.minFrame to the first frame in the wal
** file that has not yet been checkpointed. This client will not need
** to read any frames earlier than minFrame from the wal file - they
** can be safely read directly from the database file.
**
** Because a ShmBarrier() call is made between taking the copy of
** nBackfill and checking that the wal-header in shared-memory still
** matches the one cached in pWal->hdr, it is guaranteed that the
** checkpointer that set nBackfill was not working with a wal-index
** header newer than that cached in pWal->hdr. If it were, that could
** cause a problem. The checkpointer could omit to checkpoint
** a version of page X that lies before pWal->minFrame (call that version
** A) on the basis that there is a newer version (version B) of the same
** page later in the wal file. But if version B happens to like past
** frame pWal->hdr.mxFrame - then the client would incorrectly assume
** that it can read version A from the database file. However, since
** we can guarantee that the checkpointer that set nBackfill could not
** see any pages past pWal->hdr.mxFrame, this problem does not come up.
*/
pWal->minFrame = pInfo->nBackfill+1;
walShmBarrier(pWal);
if( pInfo->aReadMark[mxI]!=mxReadMark
|| memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr))
){
walUnlockShared(pWal, WAL_READ_LOCK(mxI));
return WAL_RETRY;
}else{
assert( mxReadMark<=pWal->hdr.mxFrame );
pWal->readLock = (i16)mxI;
}
}
return rc;
}
@@ -2385,14 +2350,6 @@ int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
int rc; /* Return code */
int cnt = 0; /* Number of TryBeginRead attempts */
#ifdef SQLITE_ENABLE_SNAPSHOT
int bChanged = 0;
WalIndexHdr *pSnapshot = pWal->pSnapshot;
if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
bChanged = 1;
}
#endif
do{
rc = walTryBeginRead(pWal, pChanged, 0, ++cnt);
}while( rc==WAL_RETRY );
@@ -2400,66 +2357,6 @@ int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
testcase( (rc&0xff)==SQLITE_IOERR );
testcase( rc==SQLITE_PROTOCOL );
testcase( rc==SQLITE_OK );
#ifdef SQLITE_ENABLE_SNAPSHOT
if( rc==SQLITE_OK ){
if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
/* At this point the client has a lock on an aReadMark[] slot holding
** a value equal to or smaller than pSnapshot->mxFrame, but pWal->hdr
** is populated with the wal-index header corresponding to the head
** of the wal file. Verify that pSnapshot is still valid before
** continuing. Reasons why pSnapshot might no longer be valid:
**
** (1) The WAL file has been reset since the snapshot was taken.
** In this case, the salt will have changed.
**
** (2) A checkpoint as been attempted that wrote frames past
** pSnapshot->mxFrame into the database file. Note that the
** checkpoint need not have completed for this to cause problems.
*/
volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
assert( pWal->readLock>0 || pWal->hdr.mxFrame==0 );
assert( pInfo->aReadMark[pWal->readLock]<=pSnapshot->mxFrame );
/* It is possible that there is a checkpointer thread running
** concurrent with this code. If this is the case, it may be that the
** checkpointer has already determined that it will checkpoint
** snapshot X, where X is later in the wal file than pSnapshot, but
** has not yet set the pInfo->nBackfillAttempted variable to indicate
** its intent. To avoid the race condition this leads to, ensure that
** there is no checkpointer process by taking a shared CKPT lock
** before checking pInfo->nBackfillAttempted. */
rc = walLockShared(pWal, WAL_CKPT_LOCK);
if( rc==SQLITE_OK ){
/* Check that the wal file has not been wrapped. Assuming that it has
** not, also check that no checkpointer has attempted to checkpoint any
** frames beyond pSnapshot->mxFrame. If either of these conditions are
** true, return SQLITE_BUSY_SNAPSHOT. Otherwise, overwrite pWal->hdr
** with *pSnapshot and set *pChanged as appropriate for opening the
** snapshot. */
if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt))
&& pSnapshot->mxFrame>=pInfo->nBackfillAttempted
){
assert( pWal->readLock>0 );
memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr));
*pChanged = bChanged;
}else{
rc = SQLITE_BUSY_SNAPSHOT;
}
/* Release the shared CKPT lock obtained above. */
walUnlockShared(pWal, WAL_CKPT_LOCK);
}
if( rc!=SQLITE_OK ){
sqlite3WalEndReadTransaction(pWal);
}
}
}
#endif
return rc;
}
@@ -2640,7 +2537,7 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){
/* Only one writer allowed at a time. Get the write lock. Return
** SQLITE_BUSY if unable.
*/
rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 0);
if( rc ){
return rc;
}
@@ -2785,7 +2682,7 @@ static int walRestartLog(Wal *pWal){
if( pInfo->nBackfill>0 ){
u32 salt1;
sqlite3_randomness(4, &salt1);
rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1, 0);
if( rc==SQLITE_OK ){
/* If all readers are using WAL_READ_LOCK(0) (in other words if no
** readers are currently using the WAL), then the transactions
@@ -3110,7 +3007,7 @@ int sqlite3WalCheckpoint(
/* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive
** "checkpoint" lock on the database file. */
rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1, 0);
if( rc ){
/* EVIDENCE-OF: R-10421-19736 If any other process is running a
** checkpoint operation at the same time, the lock cannot be obtained and
@@ -3269,35 +3166,6 @@ int sqlite3WalHeapMemory(Wal *pWal){
return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE );
}
#ifdef SQLITE_ENABLE_SNAPSHOT
/* Create a snapshot object. The content of a snapshot is opaque to
** every other subsystem, so the WAL module can put whatever it needs
** in the object.
*/
int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot){
int rc = SQLITE_OK;
WalIndexHdr *pRet;
assert( pWal->readLock>=0 && pWal->writeLock==0 );
pRet = (WalIndexHdr*)sqlite3_malloc(sizeof(WalIndexHdr));
if( pRet==0 ){
rc = SQLITE_NOMEM;
}else{
memcpy(pRet, &pWal->hdr, sizeof(WalIndexHdr));
*ppSnapshot = (sqlite3_snapshot*)pRet;
}
return rc;
}
/* Try to open on pSnapshot when the next read-transaction starts
*/
void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot){
pWal->pSnapshot = (WalIndexHdr*)pSnapshot;
}
#endif /* SQLITE_ENABLE_SNAPSHOT */
#ifdef SQLITE_ENABLE_ZIPVFS
/*
** If the argument is not NULL, it points to a Wal object that holds a
-5
View File
@@ -126,11 +126,6 @@ int sqlite3WalExclusiveMode(Wal *pWal, int op);
*/
int sqlite3WalHeapMemory(Wal *pWal);
#ifdef SQLITE_ENABLE_SNAPSHOT
int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot);
void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot);
#endif
#ifdef SQLITE_ENABLE_ZIPVFS
/* If the WAL file is not empty, return the number of bytes of content
** stored in each frame (i.e. the db page-size when the WAL was created).
+4 -10
View File
@@ -718,7 +718,7 @@ static void constructAutomaticIndex(
idxCols |= cMask;
pIdx->aiColumn[n] = pTerm->u.leftColumn;
pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
pIdx->azColl[n] = pColl ? pColl->zName : sqlite3StrBINARY;
pIdx->azColl[n] = pColl ? pColl->zName : "BINARY";
n++;
}
}
@@ -730,20 +730,20 @@ static void constructAutomaticIndex(
for(i=0; i<mxBitCol; i++){
if( extraCols & MASKBIT(i) ){
pIdx->aiColumn[n] = i;
pIdx->azColl[n] = sqlite3StrBINARY;
pIdx->azColl[n] = "BINARY";
n++;
}
}
if( pSrc->colUsed & MASKBIT(BMS-1) ){
for(i=BMS-1; i<pTable->nCol; i++){
pIdx->aiColumn[n] = i;
pIdx->azColl[n] = sqlite3StrBINARY;
pIdx->azColl[n] = "BINARY";
n++;
}
}
assert( n==nKeyCol );
pIdx->aiColumn[n] = XN_ROWID;
pIdx->azColl[n] = sqlite3StrBINARY;
pIdx->azColl[n] = "BINARY";
/* Create the automatic index */
assert( pLevel->iIdxCur>=0 );
@@ -893,9 +893,6 @@ static sqlite3_index_info *allocateIndexInfo(
pIdxCons[j].iTermOffset = i;
op = (u8)pTerm->eOperator & WO_ALL;
if( op==WO_IN ) op = WO_EQ;
if( op==WO_MATCH ){
op = pTerm->eMatchOp;
}
pIdxCons[j].op = op;
/* The direct assignment in the previous line is possible only because
** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The
@@ -2864,7 +2861,6 @@ static int whereLoopAddVirtual(
pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
pIdxInfo->estimatedRows = 25;
pIdxInfo->idxFlags = 0;
pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
rc = vtabBestIndex(pParse, pTab, pIdxInfo);
if( rc ) goto whereLoopAddVtab_exit;
pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
@@ -4492,7 +4488,6 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
sqlite3VdbeJumpHere(v, pLevel->addrSkip);
sqlite3VdbeJumpHere(v, pLevel->addrSkip-2);
}
#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
if( pLevel->addrLikeRep ){
int op;
if( sqlite3VdbeGetOp(v, pLevel->addrLikeRep-1)->p1 ){
@@ -4503,7 +4498,6 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
sqlite3VdbeAddOp2(v, op, pLevel->iLikeRepCntr, pLevel->addrLikeRep);
VdbeCoverage(v);
}
#endif
if( pLevel->iLeftJoin ){
addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v);
assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
+1 -4
View File
@@ -69,10 +69,8 @@ struct WhereLevel {
int addrCont; /* Jump here to continue with the next loop cycle */
int addrFirst; /* First instruction of interior of the loop */
int addrBody; /* Beginning of the body of this loop */
#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
int iLikeRepCntr; /* LIKE range processing counter register */
int addrLikeRep; /* LIKE range processing address */
#endif
u8 iFrom; /* Which entry in the FROM clause */
u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */
int p1, p2; /* Operands of the opcode used to ends the loop */
@@ -255,7 +253,6 @@ struct WhereTerm {
u16 eOperator; /* A WO_xx value describing <op> */
u16 wtFlags; /* TERM_xxx bit flags. See below */
u8 nChild; /* Number of children that must disable us */
u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */
WhereClause *pWC; /* The clause this term is part of */
Bitmask prereqRight; /* Bitmask of tables used by pExpr->pRight */
Bitmask prereqAll; /* Bitmask of tables referenced by pExpr */
@@ -288,7 +285,7 @@ struct WhereTerm {
struct WhereScan {
WhereClause *pOrigWC; /* Original, innermost WhereClause */
WhereClause *pWC; /* WhereClause currently being scanned */
const char *zCollName; /* Required collating sequence, if not NULL */
char *zCollName; /* Required collating sequence, if not NULL */
Expr *pIdxExpr; /* Search for this index expression */
char idxaff; /* Must match this affinity, if zCollName!=NULL */
unsigned char nEquiv; /* Number of entries in aEquiv[] */
-14
View File
@@ -561,7 +561,6 @@ static int codeAllEqualityTerms(
return regBase;
}
#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
/*
** If the most recently coded instruction is a constant range contraint
** that originated from the LIKE optimization, then change the P3 to be
@@ -573,10 +572,6 @@ static int codeAllEqualityTerms(
** The OP_String opcodes on the second pass convert the upper and lower
** bound string contants to blobs. This routine makes the necessary changes
** to the OP_String opcodes for that to happen.
**
** Except, of course, if SQLITE_LIKE_DOESNT_MATCH_BLOBS is defined, then
** only the one pass through the string space is required, so this routine
** becomes a no-op.
*/
static void whereLikeOptimizationStringFixup(
Vdbe *v, /* prepared statement under construction */
@@ -594,9 +589,6 @@ static void whereLikeOptimizationStringFixup(
pOp->p5 = 1;
}
}
#else
# define whereLikeOptimizationStringFixup(A,B,C)
#endif
#ifdef SQLITE_ENABLE_CURSOR_HINTS
/*
@@ -1083,7 +1075,6 @@ Bitmask sqlite3WhereCodeOneLoopStart(
if( pLoop->wsFlags & WHERE_TOP_LIMIT ){
pRangeEnd = pLoop->aLTerm[j++];
nExtraReg = 1;
#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
if( (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 ){
assert( pRangeStart!=0 ); /* LIKE opt constraints */
assert( pRangeStart->wtFlags & TERM_LIKEOPT ); /* occur in pairs */
@@ -1096,7 +1087,6 @@ Bitmask sqlite3WhereCodeOneLoopStart(
VdbeComment((v, "LIKE loop counter"));
pLevel->addrLikeRep = sqlite3VdbeCurrentAddr(v);
}
#endif
if( pRangeStart==0
&& (j = pIdx->aiColumn[nEq])>=0
&& pIdx->pTable->aCol[j].notNull==0
@@ -1600,13 +1590,9 @@ Bitmask sqlite3WhereCodeOneLoopStart(
continue;
}
if( pTerm->wtFlags & TERM_LIKECOND ){
#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
continue;
#else
assert( pLevel->iLikeRepCntr>0 );
skipLikeAddr = sqlite3VdbeAddOp1(v, OP_IfNot, pLevel->iLikeRepCntr);
VdbeCoverage(v);
#endif
}
sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr);
+9 -30
View File
@@ -277,48 +277,29 @@ static int isLikeOrGlob(
/*
** Check to see if the given expression is of the form
**
** column OP expr
**
** where OP is one of MATCH, GLOB, LIKE or REGEXP and "column" is a
** column of a virtual table.
** column MATCH expr
**
** If it is then return TRUE. If not, return FALSE.
*/
static int isMatchOfColumn(
Expr *pExpr, /* Test this expression */
unsigned char *peOp2 /* OUT: 0 for MATCH, or else an op2 value */
Expr *pExpr /* Test this expression */
){
struct Op2 {
const char *zOp;
unsigned char eOp2;
} aOp[] = {
{ "match", SQLITE_INDEX_CONSTRAINT_MATCH },
{ "glob", SQLITE_INDEX_CONSTRAINT_GLOB },
{ "like", SQLITE_INDEX_CONSTRAINT_LIKE },
{ "regexp", SQLITE_INDEX_CONSTRAINT_REGEXP }
};
ExprList *pList;
Expr *pCol; /* Column reference */
int i;
if( pExpr->op!=TK_FUNCTION ){
return 0;
}
if( sqlite3StrICmp(pExpr->u.zToken,"match")!=0 ){
return 0;
}
pList = pExpr->x.pList;
if( pList==0 || pList->nExpr!=2 ){
if( pList->nExpr!=2 ){
return 0;
}
pCol = pList->a[1].pExpr;
if( pCol->op!=TK_COLUMN || !IsVirtual(pCol->pTab) ){
if( pList->a[1].pExpr->op != TK_COLUMN ){
return 0;
}
for(i=0; i<ArraySize(aOp); i++){
if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
*peOp2 = aOp[i].eOp2;
return 1;
}
}
return 0;
return 1;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -895,7 +876,6 @@ static void exprAnalyze(
int op; /* Top-level operator. pExpr->op */
Parse *pParse = pWInfo->pParse; /* Parsing context */
sqlite3 *db = pParse->db; /* Database connection */
unsigned char eOp2; /* op2 value for LIKE/REGEXP/GLOB */
if( db->mallocFailed ){
return;
@@ -1119,7 +1099,7 @@ static void exprAnalyze(
** virtual tables. The native query optimizer does not attempt
** to do anything with MATCH functions.
*/
if( isMatchOfColumn(pExpr, &eOp2) ){
if( isMatchOfColumn(pExpr) ){
int idxNew;
Expr *pRight, *pLeft;
WhereTerm *pNewTerm;
@@ -1140,7 +1120,6 @@ static void exprAnalyze(
pNewTerm->leftCursor = pLeft->iTable;
pNewTerm->u.leftColumn = pLeft->iColumn;
pNewTerm->eOperator = WO_MATCH;
pNewTerm->eMatchOp = eOp2;
markTermAsChild(pWC, idxNew, idxTerm);
pTerm = &pWC->a[idxTerm];
pTerm->wtFlags |= TERM_COPIED;
+6 -14
View File
@@ -283,17 +283,9 @@ do_eqp_test analyze3-2.3 {
SELECT count(a) FROM t1 WHERE b LIKE '%a'
} {0 0 0 {SCAN TABLE t1}}
# Return the first argument if like_match_blobs is true (the default)
# or the second argument if not
#
proc ilmb {a b} {
ifcapable like_match_blobs {return $a}
return $b
}
do_test analyze3-2.4 {
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE 'a%' }
} [list [ilmb 102 101] 0 100]
} {102 0 100}
do_test analyze3-2.5 {
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE '%a' }
} {999 999 100}
@@ -301,7 +293,7 @@ do_test analyze3-2.5 {
do_test analyze3-2.6 {
set like "a%"
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
} [list [ilmb 102 101] 0 100]
} {102 0 100}
do_test analyze3-2.7 {
set like "%a"
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
@@ -309,19 +301,19 @@ do_test analyze3-2.7 {
do_test analyze3-2.8 {
set like "a"
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
} [list [ilmb 102 101] 0 0]
} {102 0 0}
do_test analyze3-2.9 {
set like "ab"
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
} [list [ilmb 12 11] 0 0]
} {12 0 0}
do_test analyze3-2.10 {
set like "abc"
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
} [list [ilmb 3 2] 0 1]
} {3 0 1}
do_test analyze3-2.11 {
set like "a_c"
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
} [list [ilmb 102 101] 0 10]
} {102 0 10}
#-------------------------------------------------------------------------
-23
View File
@@ -18,7 +18,6 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix capi3c
# Do not use a codec for tests in this file, as the database file is
# manipulated directly using tcl scripts (using the [hexio_write] command).
@@ -1376,26 +1375,4 @@ do_test capi3c-24.3 {
decltype {SELECT (SELECT x FROM (SELECT t5.a AS x)) FROM t5}
} {INTEGER}
# Further tests of sqlite3_column_decltype():
#
do_execsql_test 25.0 {
CREATE TABLE t11(a VARCHAR(10), b INTEGER);
CREATE TABLE t12(a VARCHAR(15), b FLOAT);
}
foreach {tn sql} {
1 "SELECT * FROM t11 UNION ALL SELECT * FROM t12"
2 "SELECT * FROM t11 UNION SELECT * FROM t12"
3 "SELECT * FROM t11 EXCEPT SELECT * FROM t12"
4 "SELECT * FROM t11 INTERSECT SELECT * FROM t12"
5 "SELECT * FROM t11 UNION ALL SELECT * FROM t12 ORDER BY 1"
6 "SELECT * FROM t11 UNION SELECT * FROM t12 ORDER BY 1"
7 "SELECT * FROM t11 EXCEPT SELECT * FROM t12 ORDER BY 1"
8 "SELECT * FROM t11 INTERSECT SELECT * FROM t12 ORDER BY 1"
} {
do_test 25.$tn { decltype $sql } {VARCHAR(10) INTEGER}
}
finish_test
-9
View File
@@ -336,15 +336,6 @@ if {$tzoffset_new==4} {
datetest 6.8.1 {datetime('2006-04-02 02:00:00','utc')} {2006-04-02 06:00:00}
datetest 6.8.2 {datetime('2007-03-11 02:00:00','utc')} {2007-03-11 06:00:00}
# The 'utc' modifier is a no-op if the LHS is known to already be in UTC
datetest 6.9.1 {datetime('2015-12-23 12:00:00','utc')} {2015-12-23 17:00:00}
datetest 6.9.2 {datetime('2015-12-23 12:00:00z','utc')} {2015-12-23 12:00:00}
datetest 6.9.3 {datetime('2015-12-23 12:00:00-03:00','utc')} \
{2015-12-23 15:00:00}
datetest 6.9.4 {datetime('2015-12-23 12:00:00','utc','utc','utc')} \
{2015-12-23 17:00:00}
datetest 6.10 {datetime('2000-01-01 12:00:00','localtime')} \
{2000-01-01 07:00:00}
datetest 6.11 {datetime('1969-01-01 12:00:00','localtime')} \
-17
View File
@@ -252,21 +252,4 @@ do_execsql_test 5.6 {
SELECT DISTINCT x FROM t1 ORDER BY x;
} {1 2 3 4 5 6}
#-------------------------------------------------------------------------
# 2015-11-23. Problem discovered by Kostya Serebryany using libFuzzer
#
db close
sqlite3 db :memory:
do_execsql_test 6.1 {
CREATE TABLE jjj(x);
SELECT (SELECT 'mmm' UNION SELECT DISTINCT max(name) ORDER BY 1)
FROM sqlite_master;
} {jjj}
do_execsql_test 6.2 {
CREATE TABLE nnn(x);
SELECT (SELECT 'mmm' UNION SELECT DISTINCT max(name) ORDER BY 1)
FROM sqlite_master;
} {mmm}
finish_test
+2 -3
View File
@@ -62,7 +62,7 @@ ifcapable {bloblit && utf16} {
execsql {
CREATE TABLE t2(a);
INSERT INTO t2 VALUES(x'61006200630064006500');
SELECT CAST(a AS text) FROM t2 WHERE CAST(a AS text) LIKE 'abc%';
SELECT CAST(a AS text) FROM t2 WHERE a LIKE 'abc%';
}
} {abcde}
do_test enc3-2.3 {
@@ -72,8 +72,7 @@ ifcapable {bloblit && utf16} {
} {abcde}
do_test enc3-2.4 {
execsql {
SELECT rowid FROM t2
WHERE CAST(a AS text) LIKE CAST(x'610062002500' AS text);
SELECT rowid FROM t2 WHERE a LIKE x'610062002500';
}
} {1}
}
+2 -2
View File
@@ -587,7 +587,7 @@ do_execsql_test 10.1 {
INSERT INTO idx VALUES (3, 't3.txt');
CREATE VIRTUAL TABLE vt USING fs(idx);
SELECT path, data FROM vt;
SELECT * FROM vt;
} {
1 {a b c d e f g h i j k l m n o p q r s t u v w x y z}
2 {a b c d e f g h i j k l m a b c d e f g h i j k l m}
@@ -595,7 +595,7 @@ do_execsql_test 10.1 {
}
do_execsql_test 10.2 {
SELECT path, data FROM vt WHERE rowid = 2;
SELECT * FROM vt WHERE rowid = 2;
} {
2 {a b c d e f g h i j k l m a b c d e f g h i j k l m}
}
+8 -2
View File
@@ -588,13 +588,18 @@ static int inmemFullPathname(
return SQLITE_OK;
}
/* GetLastError() is never used */
static int inmemGetLastError(sqlite3_vfs *pVfs, int n, char *z){
return SQLITE_OK;
}
/*
** Register the VFS that reads from the g.aFile[] set of files.
*/
static void inmemVfsRegister(void){
static sqlite3_vfs inmemVfs;
sqlite3_vfs *pDefault = sqlite3_vfs_find(0);
inmemVfs.iVersion = 3;
inmemVfs.iVersion = 1;
inmemVfs.szOsFile = sizeof(VHandle);
inmemVfs.mxPathname = 200;
inmemVfs.zName = "inmem";
@@ -604,7 +609,8 @@ static void inmemVfsRegister(void){
inmemVfs.xFullPathname = inmemFullPathname;
inmemVfs.xRandomness = pDefault->xRandomness;
inmemVfs.xSleep = pDefault->xSleep;
inmemVfs.xCurrentTimeInt64 = pDefault->xCurrentTimeInt64;
inmemVfs.xCurrentTime = pDefault->xCurrentTime;
inmemVfs.xGetLastError = inmemGetLastError;
sqlite3_vfs_register(&inmemVfs, 0);
};
-3
View File
@@ -109,9 +109,6 @@ do_execsql_test hexlit-301 {
do_catchsql_test hexlist-400 {
SELECT 0x10000000000000000;
} {1 {hex literal too big: 0x10000000000000000}}
do_catchsql_test hexlist-401 {
SELECT DISTINCT 0x10000000000000000;
} {1 {hex literal too big: 0x10000000000000000}}
do_catchsql_test hexlist-410 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(x);
-16
View File
@@ -307,21 +307,5 @@ do_catchsql_test indexexpr1-910 {
INSERT INTO t9(a,b,c,d) VALUES(5,6,7,-8);
} {1 {UNIQUE constraint failed: index 't9x1'}}
# Test cases derived from a NEVER() maro failure discovered by
# Jonathan Metzman using AFL
#
do_execsql_test indexexpr1-1000 {
DROP TABLE IF EXISTS t0;
CREATE TABLE t0(a,b,t);
CREATE INDEX i ON t0(a in(0,1));
INSERT INTO t0 VALUES(0,1,2),(2,3,4),(5,6,7);
UPDATE t0 SET b=99 WHERE (a in(0,1))=0;
SELECT *, '|' FROM t0 ORDER BY +a;
} {0 1 2 | 2 99 4 | 5 99 7 |}
do_execsql_test indexexpr1-1010 {
UPDATE t0 SET b=88 WHERE (a in(0,1))=1;
SELECT *, '|' FROM t0 ORDER BY +a;
} {0 88 2 | 2 99 4 | 5 99 7 |}
finish_test
-65
View File
@@ -1,65 +0,0 @@
# 2015-12-30
#
# 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 for JSON aggregate SQL functions
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !json1 {
finish_test
return
}
do_execsql_test json103-100 {
CREATE TABLE t1(a,b,c);
WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<100)
INSERT INTO t1(a,b,c) SELECT x, x%3, printf('n%d',x) FROM c;
UPDATE t1 SET a='orange' WHERE rowid=39;
UPDATE t1 SET a=32.5 WHERE rowid=31;
UPDATE t1 SET a=x'303132' WHERE rowid=29;
UPDATE t1 SET a=NULL WHERE rowid=37;
SELECT json_group_array(a) FROM t1 WHERE a<0 AND typeof(a)!='blob';
} {{[]}}
do_catchsql_test json103-101 {
SELECT json_group_array(a) FROM t1;
} {1 {JSON cannot hold BLOB values}}
do_execsql_test json103-110 {
SELECT json_group_array(a) FROM t1
WHERE rowid BETWEEN 31 AND 39;
} {{[32.5,32,33,34,35,36,null,38,"orange"]}}
do_execsql_test json103-111 {
SELECT json_array_length(json_group_array(a)) FROM t1
WHERE rowid BETWEEN 31 AND 39;
} {9}
do_execsql_test json103-120 {
SELECT b, json_group_array(a) FROM t1 WHERE rowid<10 GROUP BY b ORDER BY b;
} {0 {[3,6,9]} 1 {[1,4,7]} 2 {[2,5,8]}}
do_execsql_test json103-200 {
SELECT json_group_object(c,a) FROM t1 WHERE a<0 AND typeof(a)!='blob';
} {{{}}}
do_catchsql_test json103-201 {
SELECT json_group_object(c,a) FROM t1;
} {1 {JSON cannot hold BLOB values}}
do_execsql_test json103-210 {
SELECT json_group_object(c,a) FROM t1
WHERE rowid BETWEEN 31 AND 39 AND rowid%2==1;
} {{{"n31":32.5,"n33":33,"n35":35,"n37":null,"n39":"orange"}}}
do_execsql_test json103-220 {
SELECT b, json_group_object(c,a) FROM t1
WHERE rowid<7 GROUP BY b ORDER BY b;
} {0 {{"n3":3,"n6":6}} 1 {{"n1":1,"n4":4}} 2 {{"n2":2,"n5":5}}}
finish_test
+10 -26
View File
@@ -745,19 +745,11 @@ ifcapable like_opt&&!icu {
SELECT a FROM t10 WHERE e LIKE '12%' ORDER BY +a;
}
} {12 123 scan 5 like 6}
ifcapable like_match_blobs {
do_test like-10.5a {
count {
SELECT a FROM t10 WHERE f LIKE '12%' ORDER BY +a;
}
} {12 123 scan 4 like 0}
} else {
do_test like-10.5b {
count {
SELECT a FROM t10 WHERE f LIKE '12%' ORDER BY +a;
}
} {12 123 scan 3 like 0}
}
do_test like-10.5 {
count {
SELECT a FROM t10 WHERE f LIKE '12%' ORDER BY +a;
}
} {12 123 scan 4 like 0}
do_test like-10.6 {
count {
SELECT a FROM t10 WHERE a LIKE '12%' ORDER BY +a;
@@ -794,19 +786,11 @@ ifcapable like_opt&&!icu {
SELECT a FROM t10b WHERE e GLOB '12*' ORDER BY +a;
}
} {12 123 scan 5 like 6}
ifcapable like_match_blobs {
do_test like-10.14 {
count {
SELECT a FROM t10b WHERE f GLOB '12*' ORDER BY +a;
}
} {12 123 scan 4 like 0}
} else {
do_test like-10.14 {
count {
SELECT a FROM t10b WHERE f GLOB '12*' ORDER BY +a;
}
} {12 123 scan 3 like 0}
}
do_test like-10.14 {
count {
SELECT a FROM t10b WHERE f GLOB '12*' ORDER BY +a;
}
} {12 123 scan 4 like 0}
do_test like-10.15 {
count {
SELECT a FROM t10b WHERE a GLOB '12*' ORDER BY +a;
+2 -5
View File
@@ -29,11 +29,6 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !like_match_blobs {
finish_test
return
}
do_execsql_test like3-1.1 {
PRAGMA encoding=UTF8;
CREATE TABLE t1(a,b TEXT COLLATE nocase);
@@ -112,4 +107,6 @@ do_execsql_test like3-4.2ck {
SELECT quote(x) FROM t4 WHERE x LIKE 'ab%' ORDER BY +x ASC;
} {'abc' 'abd' 'abe' X'616263' X'616264' X'616265'}
finish_test
+2 -7
View File
@@ -125,8 +125,8 @@ ifcapable attach {
# Default setting of PRAGMA cache_spill is always ON
#
# EVIDENCE-OF: R-63549-59887 PRAGMA cache_spill; PRAGMA
# cache_spill=boolean; PRAGMA schema.cache_spill=N;
# EVIDENCE-OF: R-51036-62828 PRAGMA cache_spill; PRAGMA
# cache_spill=boolean;
#
# EVIDENCE-OF: R-23955-02765 Cache_spill is enabled by default
#
@@ -190,11 +190,6 @@ do_test pragma2-4.5.1 {
PRAGMA lock_status;
}
} {0 main reserved temp unknown} ;# No cache spill, so no exclusive lock
# EVIDENCE-OF: R-34657-61226 The "PRAGMA cache_spill=N" form of this
# pragma sets a minimum cache size threshold required for spilling to
# occur.
do_test pragma2-4.5.2 {
db eval {
ROLLBACK;
-340
View File
@@ -1,340 +0,0 @@
# 2015 December 7
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The focus
# of this file is the sqlite3_snapshot_xxx() APIs.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !snapshot {finish_test; return}
set testprefix snapshot
#-------------------------------------------------------------------------
# Check some error conditions in snapshot_get(). It is an error if:
#
# 1) snapshot_get() is called on a non-WAL database, or
# 2) there is an open write transaction on the database.
#
do_execsql_test 1.0 {
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, 2);
INSERT INTO t1 VALUES(3, 4);
}
do_test 1.1.1 {
execsql { BEGIN; SELECT * FROM t1; }
list [catch { sqlite3_snapshot_get db main } msg] $msg
} {1 SQLITE_ERROR}
do_execsql_test 1.1.2 COMMIT
do_test 1.2.1 {
execsql {
PRAGMA journal_mode = WAL;
BEGIN;
INSERT INTO t1 VALUES(5, 6);
INSERT INTO t1 VALUES(7, 8);
}
list [catch { sqlite3_snapshot_get db main } msg] $msg
} {1 SQLITE_ERROR}
do_execsql_test 1.3.2 COMMIT
#-------------------------------------------------------------------------
# Check that a simple case works. Reuse the database created by the
# block of tests above.
#
do_execsql_test 2.1.0 {
BEGIN;
SELECT * FROM t1;
} {1 2 3 4 5 6 7 8}
breakpoint
do_test 2.1.1 {
set snapshot [sqlite3_snapshot_get db main]
execsql {
COMMIT;
INSERT INTO t1 VALUES(9, 10);
SELECT * FROM t1;
}
} {1 2 3 4 5 6 7 8 9 10}
do_test 2.1.2 {
execsql BEGIN
sqlite3_snapshot_open db main $snapshot
execsql {
SELECT * FROM t1;
}
} {1 2 3 4 5 6 7 8}
do_test 2.1.3 {
sqlite3_snapshot_free $snapshot
execsql COMMIT
} {}
do_test 2.2.0 {
sqlite3 db2 test.db
execsql {
BEGIN;
SELECT * FROM t1;
} db2
} {1 2 3 4 5 6 7 8 9 10}
do_test 2.2.1 {
set snapshot [sqlite3_snapshot_get db2 main]
execsql {
INSERT INTO t1 VALUES(11, 12);
SELECT * FROM t1;
}
} {1 2 3 4 5 6 7 8 9 10 11 12}
do_test 2.2.2 {
execsql BEGIN
sqlite3_snapshot_open db main $snapshot
execsql {
SELECT * FROM t1;
}
} {1 2 3 4 5 6 7 8 9 10}
do_test 2.2.3 {
sqlite3_snapshot_free $snapshot
execsql COMMIT
execsql COMMIT db2
db2 close
} {}
do_test 2.3.1 {
execsql { DELETE FROM t1 WHERE a>6 }
set snapshot [sqlite3_snapshot_get db main]
execsql {
INSERT INTO t1 VALUES('a', 'b');
INSERT INTO t1 VALUES('c', 'd');
SELECT * FROM t1;
}
} {1 2 3 4 5 6 a b c d}
do_test 2.3.2 {
execsql BEGIN
sqlite3_snapshot_open db main $snapshot
execsql { SELECT * FROM t1 }
} {1 2 3 4 5 6}
do_test 2.3.3 {
catchsql {
INSERT INTO t1 VALUES('x','y')
}
} {1 {database is locked}}
do_test 2.3.4 {
execsql COMMIT
sqlite3_snapshot_free $snapshot
} {}
#-------------------------------------------------------------------------
# Check some errors in sqlite3_snapshot_open(). It is an error if:
#
# 1) the db is in auto-commit mode,
# 2) the db has an open (read or write) transaction,
# 3) the db is not a wal database,
#
# Reuse the database created by earlier tests.
#
do_execsql_test 3.0.0 {
CREATE TABLE t2(x, y);
INSERT INTO t2 VALUES('a', 'b');
INSERT INTO t2 VALUES('c', 'd');
BEGIN;
SELECT * FROM t2;
} {a b c d}
do_test 3.0.1 {
set snapshot [sqlite3_snapshot_get db main]
execsql { COMMIT }
execsql { INSERT INTO t2 VALUES('e', 'f'); }
} {}
do_test 3.1 {
list [catch {sqlite3_snapshot_open db main $snapshot } msg] $msg
} {1 SQLITE_ERROR}
do_test 3.2.1 {
execsql {
BEGIN;
SELECT * FROM t2;
}
} {a b c d e f}
do_test 3.2.2 {
list [catch {sqlite3_snapshot_open db main $snapshot } msg] $msg
} {1 SQLITE_ERROR}
do_test 3.2.3 {
execsql {
COMMIT;
BEGIN;
INSERT INTO t2 VALUES('g', 'h');
}
list [catch {sqlite3_snapshot_open db main $snapshot } msg] $msg
} {1 SQLITE_ERROR}
do_execsql_test 3.2.4 COMMIT
do_test 3.3.1 {
execsql { PRAGMA journal_mode = DELETE }
execsql { BEGIN }
list [catch {sqlite3_snapshot_open db main $snapshot } msg] $msg
} {1 SQLITE_ERROR}
do_test 3.3.2 {
sqlite3_snapshot_free $snapshot
execsql COMMIT
} {}
#-------------------------------------------------------------------------
# Check that SQLITE_BUSY_SNAPSHOT is returned if the specified snapshot
# no longer exists because the wal file has been checkpointed.
#
# 1. Reading a snapshot from the middle of a wal file is not possible
# after the wal file has been checkpointed.
#
# 2. That a snapshot from the end of a wal file can not be read once
# the wal file has been wrapped.
#
do_execsql_test 4.1.0 {
PRAGMA journal_mode = wal;
CREATE TABLE t3(i, j);
INSERT INTO t3 VALUES('o', 't');
INSERT INTO t3 VALUES('t', 'f');
BEGIN;
SELECT * FROM t3;
} {wal o t t f}
do_test 4.1.1 {
set snapshot [sqlite3_snapshot_get db main]
execsql COMMIT
} {}
do_test 4.1.2 {
execsql {
INSERT INTO t3 VALUES('f', 's');
BEGIN;
}
sqlite3_snapshot_open db main $snapshot
execsql { SELECT * FROM t3 }
} {o t t f}
do_test 4.1.3 {
execsql {
COMMIT;
PRAGMA wal_checkpoint;
BEGIN;
}
list [catch {sqlite3_snapshot_open db main $snapshot} msg] $msg
} {1 SQLITE_BUSY_SNAPSHOT}
do_test 4.1.4 {
sqlite3_snapshot_free $snapshot
execsql COMMIT
} {}
do_test 4.2.1 {
execsql {
INSERT INTO t3 VALUES('s', 'e');
INSERT INTO t3 VALUES('n', 't');
BEGIN;
SELECT * FROM t3;
}
} {o t t f f s s e n t}
do_test 4.2.2 {
set snapshot [sqlite3_snapshot_get db main]
execsql {
COMMIT;
PRAGMA wal_checkpoint;
BEGIN;
}
sqlite3_snapshot_open db main $snapshot
execsql { SELECT * FROM t3 }
} {o t t f f s s e n t}
do_test 4.2.3 {
execsql {
COMMIT;
INSERT INTO t3 VALUES('e', 't');
BEGIN;
}
list [catch {sqlite3_snapshot_open db main $snapshot} msg] $msg
} {1 SQLITE_BUSY_SNAPSHOT}
do_test 4.2.4 {
sqlite3_snapshot_free $snapshot
} {}
#-------------------------------------------------------------------------
# Check that SQLITE_BUSY is returned if a checkpoint is running when
# sqlite3_snapshot_open() is called.
#
reset_db
db close
testvfs tvfs
sqlite3 db test.db -vfs tvfs
do_execsql_test 5.1 {
PRAGMA journal_mode = wal;
CREATE TABLE x1(x, xx, xxx);
INSERT INTO x1 VALUES('z', 'zz', 'zzz');
BEGIN;
SELECT * FROM x1;
} {wal z zz zzz}
do_test 5.2 {
set ::snapshot [sqlite3_snapshot_get db main]
sqlite3 db2 test.db -vfs tvfs
execsql {
INSERT INTO x1 VALUES('a', 'aa', 'aaa');
COMMIT;
}
} {}
set t53 0
proc write_callback {args} {
do_test 5.3.[incr ::t53] {
execsql BEGIN
list [catch { sqlite3_snapshot_open db main $::snapshot } msg] $msg
} {1 SQLITE_BUSY}
catchsql COMMIT
}
tvfs filter xWrite
tvfs script write_callback
db2 eval { PRAGMA wal_checkpoint }
db close
db2 close
tvfs delete
sqlite3_snapshot_free $snapshot
#-------------------------------------------------------------------------
# Test that sqlite3_snapshot_get() may be called immediately after
# "BEGIN; PRAGMA user_version;". And that sqlite3_snapshot_open() may
# be called after opening the db handle and running the script
# "PRAGMA user_version; BEGIN".
reset_db
do_execsql_test 6.1 {
PRAGMA journal_mode = wal;
CREATE TABLE x1(x, xx, xxx);
INSERT INTO x1 VALUES('z', 'zz', 'zzz');
BEGIN;
PRAGMA user_version;
} {wal 0}
do_test 6.2 {
set ::snapshot [sqlite3_snapshot_get db main]
execsql {
INSERT INTO x1 VALUES('a', 'aa', 'aaa');
COMMIT;
}
} {}
do_test 6.3 {
sqlite3 db2 test.db
db2 eval "PRAGMA user_version ; BEGIN"
sqlite3_snapshot_open db2 main $::snapshot
db2 eval { SELECT * FROM x1 }
} {z zz zzz}
sqlite3_snapshot_free $snapshot
finish_test
-164
View File
@@ -1,164 +0,0 @@
# 2015 December 10
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The focus
# of this file is the sqlite3_snapshot_xxx() APIs.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !snapshot {finish_test; return}
set testprefix snapshot_fault
#-------------------------------------------------------------------------
# Check that an sqlite3_snapshot_open() client cannot be tricked into
# reading a corrupt snapshot even if a second client fails while
# checkpointing the db.
#
do_faultsim_test 1.0 -prep {
faultsim_delete_and_reopen
sqlite3 db2 test.db
db2 eval {
CREATE TABLE t1(a, b UNIQUE, c UNIQUE);
INSERT INTO t1 VALUES(1, randomblob(500), randomblob(500));
INSERT INTO t1 VALUES(2, randomblob(500), randomblob(500));
PRAGMA journal_mode = wal;
INSERT INTO t1 VALUES(3, randomblob(500), randomblob(500));
BEGIN;
SELECT a FROM t1;
}
set ::snapshot [sqlite3_snapshot_get db2 main]
db2 eval COMMIT
db2 eval {
UPDATE t1 SET b=randomblob(501), c=randomblob(501) WHERE a=1;
INSERT INTO t1 VALUES(4, randomblob(500), randomblob(500));
INSERT INTO t1 VALUES(5, randomblob(500), randomblob(500));
INSERT INTO t1 VALUES(6, randomblob(500), randomblob(500));
}
} -body {
db eval { PRAGMA wal_checkpoint }
} -test {
db2 eval BEGIN
if {[catch { sqlite3_snapshot_open db2 main $::snapshot } msg]} {
if {$msg != "SQLITE_BUSY_SNAPSHOT" && $msg != "SQLITE_BUSY"} {
error "error is $msg"
}
} else {
set res [db2 eval {
SELECT a FROM t1;
PRAGMA integrity_check;
}]
if {$res != "1 2 3 ok"} { error "res is $res" }
}
sqlite3_snapshot_free $::snapshot
}
#-------------------------------------------------------------------------
# This test is similar to the previous one. Except, after the
# "PRAGMA wal_checkpoint" command fails the db is closed and reopened
# so as to require wal file recovery. It should not be possible to open
# a snapshot that is part of the body of a recovered wal file.
#
do_faultsim_test 2.0 -prep {
faultsim_delete_and_reopen
db eval {
CREATE TABLE t1(a, b UNIQUE, c UNIQUE);
INSERT INTO t1 VALUES(1, randomblob(500), randomblob(500));
INSERT INTO t1 VALUES(2, randomblob(500), randomblob(500));
PRAGMA journal_mode = wal;
INSERT INTO t1 VALUES(3, randomblob(500), randomblob(500));
BEGIN;
SELECT a FROM t1;
}
set ::snapshot [sqlite3_snapshot_get db main]
db eval COMMIT
db eval {
UPDATE t1 SET b=randomblob(501), c=randomblob(501) WHERE a=1;
INSERT INTO t1 VALUES(4, randomblob(500), randomblob(500));
INSERT INTO t1 VALUES(5, randomblob(500), randomblob(500));
INSERT INTO t1 VALUES(6, randomblob(500), randomblob(500));
}
} -body {
db eval { PRAGMA wal_checkpoint }
} -test {
db_save
db close
db_restore_and_reopen
db eval { SELECT * FROM t1 }
db eval BEGIN
if {[catch { sqlite3_snapshot_open db main $::snapshot } msg]} {
if {$msg != "SQLITE_BUSY_SNAPSHOT" && $msg != "SQLITE_BUSY"} {
error "error is $msg"
}
} else {
# This branch should actually never be taken. But it was useful in
# determining whether or not this test was actually working (by
# running a modified version of SQLite that allowed snapshots to be
# opened following a recovery).
error "TEST HAS FAILED"
set res [db eval {
SELECT a FROM t1;
PRAGMA integrity_check;
}]
if {$res != "1 2 3 ok"} { error "res is $res" }
}
sqlite3_snapshot_free $::snapshot
}
#-------------------------------------------------------------------------
# Test the handling of faults that occur within sqlite3_snapshot_open().
#
do_faultsim_test 3.0 -prep {
faultsim_delete_and_reopen
db eval {
CREATE TABLE t1(a, b UNIQUE, c UNIQUE);
INSERT INTO t1 VALUES(1, randomblob(500), randomblob(500));
INSERT INTO t1 VALUES(2, randomblob(500), randomblob(500));
PRAGMA journal_mode = wal;
INSERT INTO t1 VALUES(3, randomblob(500), randomblob(500));
BEGIN;
SELECT a FROM t1;
}
set ::snapshot [sqlite3_snapshot_get db main]
db eval COMMIT
db eval {
UPDATE t1 SET b=randomblob(501), c=randomblob(501) WHERE a=1;
INSERT INTO t1 VALUES(4, randomblob(500), randomblob(500));
INSERT INTO t1 VALUES(5, randomblob(500), randomblob(500));
INSERT INTO t1 VALUES(6, randomblob(500), randomblob(500));
BEGIN;
}
} -body {
if { [catch { sqlite3_snapshot_open db main $::snapshot } msg] } {
error $msg
}
} -test {
faultsim_test_result {0 {}} {1 SQLITE_IOERR} \
{1 SQLITE_IOERR_NOMEM} {1 SQLITE_IOERR_READ}
if {$testrc==0} {
set res [db eval {
SELECT a FROM t1;
PRAGMA integrity_check;
}]
if {$res != "1 2 3 ok"} { error "res is $res" }
}
sqlite3_snapshot_free $::snapshot
}
finish_test
-43
View File
@@ -1,43 +0,0 @@
# 2015-12-17
#
# 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.
#
#***********************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix spellfix3
ifcapable !vtab { finish_test ; return }
load_static_extension db spellfix
do_execsql_test 100 {
SELECT spellfix1_scriptcode('And God said, “Let there be light”');
} {215}
do_execsql_test 110 {
SELECT spellfix1_scriptcode('Бог сказал: "Да будет свет"');
} {220}
do_execsql_test 120 {
SELECT spellfix1_scriptcode('και ειπεν ο θεος γενηθητω φως και εγενετο φως');
} {200}
do_execsql_test 130 {
SELECT spellfix1_scriptcode('וַיֹּ֥אמֶר אֱלֹהִ֖ים יְהִ֣י א֑וֹר וַֽיְהִי־אֽוֹר׃');
} {125}
do_execsql_test 140 {
SELECT spellfix1_scriptcode('فِي ذَلِكَ الوَقتِ، قالَ اللهُ: لِيَكُنْ نُورٌ. فَصَارَ نُورٌ.');
} {160}
do_execsql_test 200 {
SELECT spellfix1_scriptcode('+3.14159');
} {999}
do_execsql_test 210 {
SELECT spellfix1_scriptcode('And God said: "Да будет свет"');
} {998}
finish_test
-11
View File
@@ -874,17 +874,6 @@ do_test sqllimits1-16.2 {
}
} {1 {string or blob too big}}
do_catchsql_test sqllimits1.17.0 {
SELECT *,*,*,*,*,*,*,* FROM (
SELECT *,*,*,*,*,*,*,* FROM (
SELECT *,*,*,*,*,*,*,* FROM (
SELECT *,*,*,*,*,*,*,* FROM (
SELECT *,*,*,*,*,*,*,* FROM (
SELECT 1,2,3,4,5,6,7,8,9,10
)
))))
} "1 {too many columns in result set}"
foreach {key value} [array get saved] {
catch {set $key $value}
-10
View File
@@ -116,14 +116,4 @@ do_execsql_test 2.5 {
SELECT * FROM t1;
} {1 2}
# Try to open a ridiculously long pathname. Bug found by
# Kostya Serebryany using libFuzzer on 2015-11-30.
#
do_test 3.1 {
db close
catch {sqlite3 db [string repeat [string repeat x 100]/ 6]} res
set res
} {unable to open database file}
finish_test
+1 -1
View File
@@ -60,7 +60,7 @@ foreach s {
open close access getcwd stat fstat ftruncate
fcntl read pread write pwrite fchmod fallocate
pread64 pwrite64 unlink openDirectory mkdir rmdir
statvfs fchown geteuid umask mmap munmap mremap
statvfs fchown umask mmap munmap mremap
getpagesize readlink
} {
if {[test_syscall exists $s]} {lappend syscall_list $s}
-1
View File
@@ -226,7 +226,6 @@ do_faultsim_test 3 -faults vfsfault-* -prep {
faultsim_delete_and_reopen
file_control_chunksize_test db main 8192
execsql {
PRAGMA synchronous=OFF;
CREATE TABLE t1(a, b);
BEGIN;
SELECT * FROM t1;
+20 -50
View File
@@ -88,13 +88,6 @@
#include <fcntl.h>
#include <errno.h>
#include "test_multiplex.h"
/* Required to link test_multiplex.c */
#ifndef SQLITE_OMIT_WSD
int sqlite3PendingByte = 0x40000000;
#endif
/*
* This code implements the MD5 message-digest algorithm.
* The algorithm is due to Ron Rivest. This code was
@@ -875,28 +868,22 @@ static void filecopy_x(
** Used by setstoptime() and timetostop().
*/
static double timelimit = 0.0;
static double currentTime(void){
double t;
static sqlite3_vfs *pTimelimitVfs = 0;
if( pTimelimitVfs==0 ) pTimelimitVfs = sqlite3_vfs_find(0);
if( pTimelimitVfs->iVersion>=1 && pTimelimitVfs->xCurrentTimeInt64!=0 ){
sqlite3_int64 tm;
pTimelimitVfs->xCurrentTimeInt64(pTimelimitVfs, &tm);
t = tm/86400000.0;
}else{
pTimelimitVfs->xCurrentTime(pTimelimitVfs, &t);
}
return t;
}
static sqlite3_vfs *pTimelimitVfs = 0;
static void setstoptime_x(
Error *pErr, /* IN/OUT: Error code */
int nMs /* Milliseconds until "stop time" */
){
if( pErr->rc==SQLITE_OK ){
double t = currentTime();
timelimit = t + ((double)nMs)/(1000.0*60.0*60.0*24.0);
double t;
int rc;
pTimelimitVfs = sqlite3_vfs_find(0);
rc = pTimelimitVfs->xCurrentTime(pTimelimitVfs, &t);
if( rc!=SQLITE_OK ){
pErr->rc = rc;
}else{
timelimit = t + ((double)nMs)/(1000.0*60.0*60.0*24.0);
}
}
}
@@ -905,8 +892,14 @@ static int timetostop_x(
){
int ret = 1;
if( pErr->rc==SQLITE_OK ){
double t = currentTime();
ret = (t >= timelimit);
double t;
int rc;
rc = pTimelimitVfs->xCurrentTime(pTimelimitVfs, &t);
if( rc!=SQLITE_OK ){
pErr->rc = rc;
}else{
ret = (t >= timelimit);
}
}
return ret;
}
@@ -1467,36 +1460,13 @@ int main(int argc, char **argv){
argc = 2;
argv = substArgv;
}
/* Loop through the command-line arguments to ensure that each argument
** selects at least one test. If not, assume there is a typo on the
** command-line and bail out with the usage message. */
for(iArg=1; iArg<argc; iArg++){
const char *zArg = argv[iArg];
if( zArg[0]=='-' ){
if( sqlite3_stricmp(zArg, "-multiplexor")==0 ){
/* Install the multiplexor VFS as the default */
int rc = sqlite3_multiplex_initialize(0, 1);
if( rc!=SQLITE_OK ){
fprintf(stderr, "Failed to install multiplexor VFS (%d)\n", rc);
return 253;
}
}
else {
goto usage;
}
continue;
}
for(i=0; i<sizeof(aTest)/sizeof(aTest[0]); i++){
if( sqlite3_strglob(zArg, aTest[i].zTest)==0 ) break;
if( sqlite3_strglob(argv[iArg],aTest[i].zTest)==0 ) break;
}
if( i>=sizeof(aTest)/sizeof(aTest[0]) ) goto usage;
}
for(iArg=1; iArg<argc; iArg++){
if( argv[iArg][0]=='-' ) continue;
for(i=0; i<sizeof(aTest)/sizeof(aTest[0]); i++){
char const *z = aTest[i].zTest;
if( sqlite3_strglob(argv[iArg],z)==0 ){
@@ -1513,7 +1483,7 @@ int main(int argc, char **argv){
return (nGlobalErr>0 ? 255 : 0);
usage:
printf("Usage: %s [-multiplexor] [testname|testprefix*]...\n", argv[0]);
printf("Usage: %s [testname|testprefix*]...\n", argv[0]);
printf("Available tests are:\n");
for(i=0; i<sizeof(aTest)/sizeof(aTest[0]); i++){
printf(" %s\n", aTest[i].zTest);
+5 -5
View File
@@ -32,8 +32,8 @@ do_test tkt3871-1.3 {
execsql { SELECT * FROM e WHERE a = 1 OR a = 2 }
set echo_module
} [list \
xFilter {SELECT rowid, a, b FROM 't1' WHERE a = ?} 1 \
xFilter {SELECT rowid, a, b FROM 't1' WHERE a = ?} 2 \
xFilter {SELECT rowid, * FROM 't1' WHERE a = ?} 1 \
xFilter {SELECT rowid, * FROM 't1' WHERE a = ?} 2 \
]
do_test tkt3871-1.4 {
@@ -44,9 +44,9 @@ do_test tkt3871-1.5 {
execsql { SELECT * FROM e WHERE a = 1 OR a = 2 OR b = 9 }
set echo_module
} [list \
xFilter {SELECT rowid, a, b FROM 't1' WHERE a = ?} 1 \
xFilter {SELECT rowid, a, b FROM 't1' WHERE a = ?} 2 \
xFilter {SELECT rowid, a, b FROM 't1' WHERE b = ?} 9
xFilter {SELECT rowid, * FROM 't1' WHERE a = ?} 1 \
xFilter {SELECT rowid, * FROM 't1' WHERE a = ?} 2 \
xFilter {SELECT rowid, * FROM 't1' WHERE b = ?} 9
]
+41 -45
View File
@@ -393,7 +393,7 @@ do_test vtab1-3.7 {
SELECT rowid, * FROM t1;
}
} {1 1 2 3 2 4 5 6}
do_test vtab1-3.8.1 {
do_test vtab1-3.8 {
execsql {
SELECT a AS d, b AS e, c AS f FROM t1;
}
@@ -404,14 +404,14 @@ do_test vtab1-3.8.1 {
# in test8.c) to make sure the xBestIndex() and xFilter() methods were
# called correctly.
#
do_test vtab1-3.8.2 {
do_test vtab1-3.8 {
set echo_module ""
execsql {
SELECT * FROM t1;
}
set echo_module
} [list xBestIndex {SELECT rowid, a, b, c FROM 'treal'} \
xFilter {SELECT rowid, a, b, c FROM 'treal'} ]
} [list xBestIndex {SELECT rowid, * FROM 'treal'} \
xFilter {SELECT rowid, * FROM 'treal'} ]
do_test vtab1-3.9 {
set echo_module ""
execsql {
@@ -420,8 +420,8 @@ do_test vtab1-3.9 {
} {4 5 6}
do_test vtab1-3.10 {
set echo_module
} [list xBestIndex {SELECT rowid, a, b, c FROM 'treal' WHERE b = ?} \
xFilter {SELECT rowid, a, b, c FROM 'treal' WHERE b = ?} 5 ]
} [list xBestIndex {SELECT rowid, * FROM 'treal' WHERE b = ?} \
xFilter {SELECT rowid, * FROM 'treal' WHERE b = ?} 5 ]
do_test vtab1-3.10 {
set echo_module ""
execsql {
@@ -430,9 +430,8 @@ do_test vtab1-3.10 {
} {4 5 6}
do_test vtab1-3.11 {
set echo_module
} [list xBestIndex {SELECT rowid, a, b, c FROM 'treal' WHERE b >= ? AND b <= ?}\
xFilter {SELECT rowid, a, b, c FROM 'treal' WHERE b >= ? AND b <= ?}\
5 10 ]
} [list xBestIndex {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?} \
xFilter {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?} 5 10 ]
do_test vtab1-3.12 {
set echo_module ""
execsql {
@@ -441,9 +440,8 @@ do_test vtab1-3.12 {
} {1 2 3 4 5 6}
do_test vtab1-3.13 {
set echo_module
} [list xBestIndex {SELECT rowid, a, b, c FROM 'treal' WHERE b >= ? AND b <= ?}\
xFilter {SELECT rowid, a, b, c FROM 'treal' WHERE b >= ? AND b <= ?}\
2 10 ]
} [list xBestIndex {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?} \
xFilter {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?} 2 10 ]
# Add a function for the MATCH operator. Everything always matches!
#proc test_match {lhs rhs} {
@@ -461,8 +459,8 @@ do_test vtab1-3.12 {
} {1 {unable to use function MATCH in the requested context}}
do_test vtab1-3.13 {
set echo_module
} [list xBestIndex {SELECT rowid, a, b, c FROM 'treal'} \
xFilter {SELECT rowid, a, b, c FROM 'treal'}]
} [list xBestIndex {SELECT rowid, * FROM 'treal'} \
xFilter {SELECT rowid, * FROM 'treal'}]
ifcapable subquery {
# The echo module uses a subquery internally to implement the MATCH operator.
do_test vtab1-3.14 {
@@ -474,9 +472,9 @@ do_test vtab1-3.14 {
do_test vtab1-3.15 {
set echo_module
} [list xBestIndex \
{SELECT rowid, a, b, c FROM 'treal' WHERE b LIKE (SELECT '%'||?||'%')} \
{SELECT rowid, * FROM 'treal' WHERE b LIKE (SELECT '%'||?||'%')} \
xFilter \
{SELECT rowid, a, b, c FROM 'treal' WHERE b LIKE (SELECT '%'||?||'%')} \
{SELECT rowid, * FROM 'treal' WHERE b LIKE (SELECT '%'||?||'%')} \
string ]
}; #ifcapable subquery
@@ -507,8 +505,8 @@ do_test vtab1-4.1 {
} {2 5 nosort}
do_test vtab1-4.2 {
set echo_module
} [list xBestIndex {SELECT rowid, NULL, b, NULL FROM 'treal' ORDER BY b ASC} \
xFilter {SELECT rowid, NULL, b, NULL FROM 'treal' ORDER BY b ASC} ]
} [list xBestIndex {SELECT rowid, * FROM 'treal' ORDER BY b ASC} \
xFilter {SELECT rowid, * FROM 'treal' ORDER BY b ASC} ]
do_test vtab1-4.3 {
set echo_module ""
cksort {
@@ -517,8 +515,8 @@ do_test vtab1-4.3 {
} {5 2 nosort}
do_test vtab1-4.4 {
set echo_module
} [list xBestIndex {SELECT rowid, NULL, b, NULL FROM 'treal' ORDER BY b DESC} \
xFilter {SELECT rowid, NULL, b, NULL FROM 'treal' ORDER BY b DESC} ]
} [list xBestIndex {SELECT rowid, * FROM 'treal' ORDER BY b DESC} \
xFilter {SELECT rowid, * FROM 'treal' ORDER BY b DESC} ]
do_test vtab1-4.3 {
set echo_module ""
cksort {
@@ -527,8 +525,8 @@ do_test vtab1-4.3 {
} {2 5 sort}
do_test vtab1-4.4 {
set echo_module
} [list xBestIndex {SELECT rowid, NULL, b, NULL FROM 'treal'} \
xFilter {SELECT rowid, NULL, b, NULL FROM 'treal'} ]
} [list xBestIndex {SELECT rowid, * FROM 'treal'} \
xFilter {SELECT rowid, * FROM 'treal'} ]
execsql {
DROP TABLE t1;
@@ -577,9 +575,9 @@ do_test vtab1-5-2 {
do_test vtab1-5-3 {
filter $echo_module
} [list \
xFilter {SELECT rowid, a, b, c FROM 't1'} \
xFilter {SELECT rowid, d, e, f FROM 't2'} \
xFilter {SELECT rowid, d, e, f FROM 't2'} \
xFilter {SELECT rowid, * FROM 't1'} \
xFilter {SELECT rowid, * FROM 't2'} \
xFilter {SELECT rowid, * FROM 't2'} \
]
do_test vtab1-5-4 {
set echo_module ""
@@ -593,9 +591,9 @@ do_test vtab1-5-4 {
do_test vtab1-5-5 {
filter $echo_module
} [list \
xFilter {SELECT rowid, a, b, c FROM 't1'} \
xFilter {SELECT rowid, d, e, f FROM 't2'} \
xFilter {SELECT rowid, d, e, f FROM 't2'} \
xFilter {SELECT rowid, * FROM 't1'} \
xFilter {SELECT rowid, * FROM 't2'} \
xFilter {SELECT rowid, * FROM 't2'} \
]
do_test vtab1-5-6 {
execsql {
@@ -617,9 +615,9 @@ do_test vtab1-5-6 {
do_test vtab1-5-7 {
filter $::echo_module
} [list \
xFilter {SELECT rowid, a, b, c FROM 't1'} \
xFilter {SELECT rowid, d, e, f FROM 't2' WHERE d = ?} \
xFilter {SELECT rowid, d, e, f FROM 't2' WHERE d = ?} \
xFilter {SELECT rowid, * FROM 't1'} \
xFilter {SELECT rowid, * FROM 't2' WHERE d = ?} \
xFilter {SELECT rowid, * FROM 't2' WHERE d = ?} \
]
execsql {
@@ -969,8 +967,8 @@ do_test vtab1.10-5 {
}
set echo_module
} [list \
xBestIndex {SELECT rowid, a, b, c FROM 'r'} \
xFilter {SELECT rowid, a, b, c FROM 'r'} \
xBestIndex {SELECT rowid, * FROM 'r'} \
xFilter {SELECT rowid, * FROM 'r'} \
]
proc match_func {args} {return ""}
do_test vtab1.10-6 {
@@ -981,8 +979,8 @@ do_test vtab1.10-6 {
}
set echo_module
} [list \
xBestIndex {SELECT rowid, a, b, c FROM 'r'} \
xFilter {SELECT rowid, a, b, c FROM 'r'} \
xBestIndex {SELECT rowid, * FROM 'r'} \
xFilter {SELECT rowid, * FROM 'r'} \
]
@@ -1155,15 +1153,13 @@ do_test vtab1-14.2 {
set echo_module ""
execsql { SELECT * FROM echo_c WHERE rowid = 1 }
set echo_module
} [list xBestIndex {SELECT rowid, a, b, c FROM 'c' WHERE rowid = ?} \
xFilter {SELECT rowid, a, b, c FROM 'c' WHERE rowid = ?} 1]
} [list xBestIndex {SELECT rowid, * FROM 'c' WHERE rowid = ?} xFilter {SELECT rowid, * FROM 'c' WHERE rowid = ?} 1]
do_test vtab1-14.3 {
set echo_module ""
execsql { SELECT * FROM echo_c WHERE a = 1 }
set echo_module
} [list xBestIndex {SELECT rowid, a, b, c FROM 'c' WHERE a = ?} \
xFilter {SELECT rowid, a, b, c FROM 'c' WHERE a = ?} 1]
} [list xBestIndex {SELECT rowid, * FROM 'c' WHERE a = ?} xFilter {SELECT rowid, * FROM 'c' WHERE a = ?} 1]
#do_test vtab1-14.4 {
# set echo_module ""
@@ -1304,16 +1300,16 @@ do_execsql_test 18.1.0 {
foreach {tn sql res filter} {
1.1 "SELECT a FROM e6 WHERE b>'James'" {4 1 5}
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b > ?} James}
{xFilter {SELECT rowid, * FROM 't6' WHERE b > ?} James}
1.2 "SELECT a FROM e6 WHERE b>='J' AND b<'K'" {3 4}
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ?} J K}
{xFilter {SELECT rowid, * FROM 't6' WHERE b >= ? AND b < ?} J K}
1.3 "SELECT a FROM e6 WHERE b LIKE 'J%'" {3 4}
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} J%}
{xFilter {SELECT rowid, * FROM 't6'}}
1.4 "SELECT a FROM e6 WHERE b LIKE 'j%'" {3 4}
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} j%}
{xFilter {SELECT rowid, * FROM 't6'}}
} {
set echo_module {}
do_execsql_test 18.$tn.1 $sql $res
@@ -1323,10 +1319,10 @@ foreach {tn sql res filter} {
do_execsql_test 18.2.0 { PRAGMA case_sensitive_like = ON }
foreach {tn sql res filter} {
2.1 "SELECT a FROM e6 WHERE b LIKE 'J%'" {3 4}
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} J%}
{xFilter {SELECT rowid, * FROM 't6'}}
2.2 "SELECT a FROM e6 WHERE b LIKE 'j%'" {}
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} j%}
{xFilter {SELECT rowid, * FROM 't6'}}
} {
set echo_module {}
do_execsql_test 18.$tn.1 $sql $res
+16 -16
View File
@@ -57,9 +57,9 @@ do_test vtab4-1.3 {
UPDATE techo SET a = 2;
}
set echo_module
} [list xBestIndex {SELECT rowid, a, b, c FROM 'treal'} \
} [list xBestIndex {SELECT rowid, * FROM 'treal'} \
xBegin echo(treal) \
xFilter {SELECT rowid, a, b, c FROM 'treal'} \
xFilter {SELECT rowid, * FROM 'treal'} \
xSync echo(treal) \
xCommit echo(treal) \
]
@@ -69,9 +69,9 @@ do_test vtab4-1.4 {
DELETE FROM techo;
}
set echo_module
} [list xBestIndex {SELECT rowid, NULL, NULL, NULL FROM 'treal'} \
} [list xBestIndex {SELECT rowid, * FROM 'treal'} \
xBegin echo(treal) \
xFilter {SELECT rowid, NULL, NULL, NULL FROM 'treal'} \
xFilter {SELECT rowid, * FROM 'treal'} \
xSync echo(treal) \
xCommit echo(treal) \
]
@@ -105,12 +105,12 @@ do_test vtab4-2.2 {
COMMIT;
}
set echo_module
} [list xBestIndex {SELECT rowid, a, b, c FROM 'treal'} \
} [list xBestIndex {SELECT rowid, * FROM 'treal'} \
xBegin echo(sreal) \
xFilter {SELECT rowid, a, b, c FROM 'treal'} \
xBestIndex {SELECT rowid, NULL, NULL, NULL FROM 'treal'} \
xFilter {SELECT rowid, * FROM 'treal'} \
xBestIndex {SELECT rowid, * FROM 'treal'} \
xBegin echo(treal) \
xFilter {SELECT rowid, NULL, NULL, NULL FROM 'treal'} \
xFilter {SELECT rowid, * FROM 'treal'} \
xSync echo(sreal) \
xSync echo(treal) \
xCommit echo(sreal) \
@@ -137,12 +137,12 @@ do_test vtab4-2.5 {
ROLLBACK;
}
set echo_module
} [list xBestIndex {SELECT rowid, a, b, c FROM 'sreal'} \
} [list xBestIndex {SELECT rowid, * FROM 'sreal'} \
xBegin echo(treal) \
xFilter {SELECT rowid, a, b, c FROM 'sreal'} \
xBestIndex {SELECT rowid, NULL, NULL, NULL FROM 'sreal'} \
xFilter {SELECT rowid, * FROM 'sreal'} \
xBestIndex {SELECT rowid, * FROM 'sreal'} \
xBegin echo(sreal) \
xFilter {SELECT rowid, NULL, NULL, NULL FROM 'sreal'} \
xFilter {SELECT rowid, * FROM 'sreal'} \
xRollback echo(treal) \
xRollback echo(sreal) \
]
@@ -178,12 +178,12 @@ do_test vtab4-3.3 {
COMMIT;
}
set echo_module
} [list xBestIndex {SELECT rowid, a, b, c FROM 'sreal'} \
} [list xBestIndex {SELECT rowid, * FROM 'sreal'} \
xBegin echo(treal) \
xFilter {SELECT rowid, a, b, c FROM 'sreal'} \
xBestIndex {SELECT rowid, NULL, NULL, NULL FROM 'sreal'} \
xFilter {SELECT rowid, * FROM 'sreal'} \
xBestIndex {SELECT rowid, * FROM 'sreal'} \
xBegin echo(sreal) \
xFilter {SELECT rowid, NULL, NULL, NULL FROM 'sreal'} \
xFilter {SELECT rowid, * FROM 'sreal'} \
xSync echo(treal) \
xSync echo(sreal) \
xRollback echo(treal) \
-2
View File
@@ -46,5 +46,3 @@ do_test vtabE-1 {
ORDER BY t1.value, t2.value;
}
} {vtabE vtabE1 11 vtabE1 w x {} vtabE vtabE1 11 vtabE1 y z {} vtabE vtabE2 22 vtabE2 a b {} vtabE vtabE2 22 vtabE2 c d {}}
finish_test

Some files were not shown because too many files have changed in this diff Show More