Merge all the latest trunk changes into the sessions branch.

FossilOrigin-Name: fc07a4795e027108674d1d41eb4350df629ddc8b
This commit is contained in:
drh 2012-08-15 16:21:55 +00:00
commit 16de7f4d32
76 changed files with 3843 additions and 3279 deletions

View File

@ -172,8 +172,8 @@ LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
icu.lo insert.lo journal.lo legacy.lo loadext.lo \
main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \
memjournal.lo \
mutex.lo mutex_noop.lo mutex_os2.lo mutex_unix.lo mutex_w32.lo \
notify.lo opcodes.lo os.lo os_os2.lo os_unix.lo os_win.lo \
mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \
notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
random.lo resolve.lo rowset.lo rtree.lo select.lo status.lo \
table.lo tokenize.lo trigger.lo \
@ -232,14 +232,12 @@ SRC = \
$(TOP)/src/mutex.c \
$(TOP)/src/mutex.h \
$(TOP)/src/mutex_noop.c \
$(TOP)/src/mutex_os2.c \
$(TOP)/src/mutex_unix.c \
$(TOP)/src/mutex_w32.c \
$(TOP)/src/notify.c \
$(TOP)/src/os.c \
$(TOP)/src/os.h \
$(TOP)/src/os_common.h \
$(TOP)/src/os_os2.c \
$(TOP)/src/os_unix.c \
$(TOP)/src/os_win.c \
$(TOP)/src/pager.c \
@ -402,7 +400,6 @@ TESTSRC2 = \
$(TOP)/src/wal.c \
$(TOP)/src/mem5.c \
$(TOP)/src/os.c \
$(TOP)/src/os_os2.c \
$(TOP)/src/os_unix.c \
$(TOP)/src/os_win.c \
$(TOP)/src/pager.c \
@ -657,9 +654,6 @@ mutex.lo: $(TOP)/src/mutex.c $(HDR)
mutex_noop.lo: $(TOP)/src/mutex_noop.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_noop.c
mutex_os2.lo: $(TOP)/src/mutex_os2.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_os2.c
mutex_unix.lo: $(TOP)/src/mutex_unix.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_unix.c
@ -687,9 +681,6 @@ os_unix.lo: $(TOP)/src/os_unix.c $(HDR)
os_win.lo: $(TOP)/src/os_win.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_win.c
os_os2.lo: $(TOP)/src/os_os2.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_os2.c
pragma.lo: $(TOP)/src/pragma.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pragma.c
@ -950,6 +941,7 @@ clean:
rm -f sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
rm -f sqlite3.c
rm -f sqlite3_analyzer$(TEXE) sqlite3_analyzer.c
rm -f sqlite-output.vsix
distclean: clean
rm -f config.log config.status libtool Makefile sqlite3.pc

View File

@ -15,12 +15,26 @@ USE_AMALGAMATION = 1
#
USE_ICU = 0
# Set this non-0 to dynamically link to the MSVC runtime library.
#
USE_CRT_DLL = 0
# Set this non-0 to use the native libraries paths for cross-compiling
# the command line tools needed during the compilation process.
#
USE_NATIVE_LIBPATHS = 0
# Set this non-0 to compile binaries suitable for the WinRT environment.
# This setting does not apply to any binaries that require Tcl to operate
# properly (i.e. the text fixture, etc).
#
FOR_WINRT = 0
# Set this non-0 to skip attempting to look for and/or link with the Tcl
# runtime library.
#
NO_TCL = 0
# Set this to non-0 to create and use PDBs.
#
SYMBOLS = 1
@ -38,26 +52,108 @@ SYMBOLS = 1
#
DEBUG = 0
# C Compiler and options for use in building executables that
# Check for the predefined command macro CC. This should point to the compiler
# binary for the target platform. If it is not defined, simply define it to
# the legacy default value 'cl.exe'.
#
!IFNDEF CC
CC = cl.exe
!ENDIF
# Check for the command macro LD. This should point to the linker binary for
# the target platform. If it is not defined, simply define it to the legacy
# default value 'link.exe'.
#
!IFNDEF LD
LD = link.exe
!ENDIF
# Check for the command macro NCC. This should point to the compiler binary
# for the platform the compilation process is taking place on. If it is not
# defined, simply define it to have the same value as the CC macro. When
# cross-compiling, it is suggested that this macro be modified via the command
# line (since nmake itself does not provide a built-in method to guess it).
# For example, to use the x86 compiler when cross-compiling for x64, a command
# line similar to the following could be used (all on one line):
#
# nmake /f Makefile.msc
# "NCC=""%VCINSTALLDIR%\bin\cl.exe"""
# USE_NATIVE_LIBPATHS=1
#
!IFDEF NCC
NCC = $(NCC:\\=\)
!ELSE
NCC = $(CC)
!ENDIF
# Check for the MSVC runtime library path macro. Othertise, this
# value will default to the 'lib' directory underneath the MSVC
# installation directory.
#
!IFNDEF NCRTLIBPATH
NCRTLIBPATH = $(VCINSTALLDIR)\lib
!ENDIF
NCRTLIBPATH = $(NCRTLIBPATH:\\=\)
# Check for the Platform SDK library path macro. Othertise, this
# value will default to the 'lib' directory underneath the Windows
# SDK installation directory (the environment variable used appears
# to be available when using Visual C++ 2008 or later via the
# command line).
#
!IFNDEF NSDKLIBPATH
NSDKLIBPATH = $(WINDOWSSDKDIR)\lib
!ENDIF
NSDKLIBPATH = $(NSDKLIBPATH:\\=\)
# C compiler and options for use in building executables that
# will run on the platform that is doing the build.
#
BCC = cl.exe -W3
BCC = $(NCC) -W3
# C Compile and options for use in building executables that
# Check if the native library paths should be used when compiling
# the command line tools used during the compilation process. If
# so, set the necessary macro now.
#
!IF $(USE_NATIVE_LIBPATHS)!=0
NLTLIBPATHS = "/LIBPATH:$(NCRTLIBPATH)" "/LIBPATH:$(NSDKLIBPATH)"
!ENDIF
# C compiler and options for use in building executables that
# will run on the target platform. (BCC and TCC are usually the
# same unless your are cross-compiling.)
#
TCC = cl.exe -W3 -DSQLITE_OS_WIN=1 -I. -I$(TOP)\src -fp:precise
TCC = $(CC) -W3 -DSQLITE_OS_WIN=1 -I. -I$(TOP)\src -fp:precise
# When compiling the library for use in the WinRT environment,
# the following compile-time options must be used as well to
# disable use of Win32 APIs that are not available and to enable
# use of Win32 APIs that are specific to Windows 8 and/or WinRT.
# Also, we need to dynamically link to the MSVC runtime when
# compiling for WinRT.
#
!IF $(FOR_WINRT)!=0
TCC = $(TCC) -DSQLITE_OS_WINRT=1 -MD
TCC = $(TCC) -DSQLITE_OS_WINRT=1
TCC = $(TCC) -DWINAPI_FAMILY=WINAPI_PARTITION_APP
!ENDIF
# Also, we need to dynamically link to the correct MSVC runtime
# when compiling for WinRT (e.g. debug or release) OR if the
# USE_CRT_DLL option is set to force dynamically linking to the
# MSVC runtime library.
#
!IF $(FOR_WINRT)!=0 || $(USE_CRT_DLL)!=0
!IF $(DEBUG)>0
TCC = $(TCC) -MDd
!ELSE
TCC = $(TCC) -MD
!ENDIF
!ELSE
!IF $(DEBUG)>0
TCC = $(TCC) -MTd
!ELSE
TCC = $(TCC) -MT
!ENDIF
!ENDIF
# The mksqlite3c.tcl and mksqlite3h.tcl scripts will pull in
@ -91,11 +187,18 @@ TCC = $(TCC) -DSQLITE_ENABLE_IOTRACE
!ENDIF
#
# Prevent warnings about "insecure" runtime library functions being used.
# Prevent warnings about "insecure" MSVC runtime library functions
# being used.
#
TCC = $(TCC) -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS
BCC = $(BCC) -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS
#
# Prevent warnings about "deprecated" POSIX functions being used.
#
TCC = $(TCC) -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS
BCC = $(BCC) -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS
#
# Use native Win32 heap instead of malloc/free?
#
@ -114,43 +217,43 @@ TCC = $(TCC) -DSQLITE_WIN32_MALLOC_VALIDATE=1
# prior to running nmake in order to match the actual installed location and
# version on this machine.
#
!if "$(TCLINCDIR)" == ""
!IFNDEF TCLINCDIR
TCLINCDIR = c:\tcl\include
!endif
!ENDIF
!if "$(TCLLIBDIR)" == ""
!IFNDEF TCLLIBDIR
TCLLIBDIR = c:\tcl\lib
!endif
!ENDIF
!if "$(LIBTCL)" == ""
!IFNDEF LIBTCL
LIBTCL = tcl85.lib
!endif
!ENDIF
# The locations of the ICU header and library files. These variables
# (ICUINCDIR, ICULIBDIR, and LIBICU) may be overridden via the environment
# prior to running nmake in order to match the actual installed location on
# this machine.
#
!if "$(ICUINCDIR)" == ""
!IFNDEF ICUINCDIR
ICUINCDIR = c:\icu\include
!endif
!ENDIF
!if "$(ICULIBDIR)" == ""
!IFNDEF ICULIBDIR
ICULIBDIR = c:\icu\lib
!endif
!ENDIF
!if "$(LIBICU)" == ""
!IFNDEF LIBICU
LIBICU = icuuc.lib icuin.lib
!endif
!ENDIF
# This is the command to use for tclsh - normally just "tclsh", but we may
# know the specific version we want to use. This variable (TCLSH_CMD) may be
# overridden via the environment prior to running nmake in order to select a
# specific Tcl shell to use.
#
!if "$(TCLSH_CMD)" == ""
!IFNDEF TCLSH_CMD
TCLSH_CMD = tclsh85
!endif
!ENDIF
# Compiler options needed for programs that use the readline() library.
#
@ -170,9 +273,9 @@ TCC = $(TCC) -DSQLITE_THREAD_OVERRIDE_LOCK=-1
# Any target libraries which libsqlite must be linked against
#
!if "$(TLIBS)" == ""
!IFNDEF TLIBS
TLIBS =
!endif
!ENDIF
# Flags controlling use of the in memory btree implementation
#
@ -236,7 +339,7 @@ LTLINK = $(TCC) -Fe$@
# Note that the vcvars*.bat family of batch files typically
# set this for you. Otherwise, the linker will attempt
# to deduce the binary type based on the object files.
!IF "$(PLATFORM)"!=""
!IFDEF PLATFORM
LTLINKOPTS = /MACHINE:$(PLATFORM)
LTLIBOPTS = /MACHINE:$(PLATFORM)
!ENDIF
@ -251,13 +354,14 @@ LTLINKOPTS = $(LTLINKOPTS) /APPCONTAINER
# If either debugging or symbols are enabled, enable PDBs.
!IF $(DEBUG)>0 || $(SYMBOLS)!=0
LTLINKOPTS = $(LTLINKOPTS) /DEBUG
BCC = $(BCC) /DEBUG
LDFLAGS = /DEBUG
!ENDIF
# Start with the Tcl related linker options.
!IF $(NO_TCL)==0
LTLIBPATHS = /LIBPATH:$(TCLLIBDIR)
LTLIBS = $(LIBTCL)
!ENDIF
# If ICU support is enabled, add the linker options for it.
!IF $(USE_ICU)!=0
@ -284,8 +388,8 @@ LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
icu.lo insert.lo journal.lo legacy.lo loadext.lo \
main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \
memjournal.lo \
mutex.lo mutex_noop.lo mutex_os2.lo mutex_unix.lo mutex_w32.lo \
notify.lo opcodes.lo os.lo os_os2.lo os_unix.lo os_win.lo \
mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \
notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
random.lo resolve.lo rowset.lo rtree.lo select.lo status.lo \
table.lo tokenize.lo trigger.lo \
@ -347,14 +451,12 @@ SRC = \
$(TOP)\src\mutex.c \
$(TOP)\src\mutex.h \
$(TOP)\src\mutex_noop.c \
$(TOP)\src\mutex_os2.c \
$(TOP)\src\mutex_unix.c \
$(TOP)\src\mutex_w32.c \
$(TOP)\src\notify.c \
$(TOP)\src\os.c \
$(TOP)\src\os.h \
$(TOP)\src\os_common.h \
$(TOP)\src\os_os2.c \
$(TOP)\src\os_unix.c \
$(TOP)\src\os_win.c \
$(TOP)\src\pager.c \
@ -521,7 +623,6 @@ TESTSRC2 = \
$(TOP)\src\wal.c \
$(TOP)\src\mem5.c \
$(TOP)\src\os.c \
$(TOP)\src\os_os2.c \
$(TOP)\src\os_unix.c \
$(TOP)\src\os_win.c \
$(TOP)\src\pager.c \
@ -653,7 +754,7 @@ lempar.c: $(TOP)\src\lempar.c
copy $(TOP)\src\lempar.c .
lemon.exe: $(TOP)\tool\lemon.c lempar.c
$(BCC) -Fe$@ $(TOP)\tool\lemon.c
$(BCC) -Daccess=_access -Fe$@ $(TOP)\tool\lemon.c /link $(NLTLIBPATHS)
# Rules to build individual *.lo files from generated *.c files. This
# applies to:
@ -771,9 +872,6 @@ mutex.lo: $(TOP)\src\mutex.c $(HDR)
mutex_noop.lo: $(TOP)\src\mutex_noop.c $(HDR)
$(LTCOMPILE) -c $(TOP)\src\mutex_noop.c
mutex_os2.lo: $(TOP)\src\mutex_os2.c $(HDR)
$(LTCOMPILE) -c $(TOP)\src\mutex_os2.c
mutex_unix.lo: $(TOP)\src\mutex_unix.c $(HDR)
$(LTCOMPILE) -c $(TOP)\src\mutex_unix.c
@ -801,9 +899,6 @@ os_unix.lo: $(TOP)\src\os_unix.c $(HDR)
os_win.lo: $(TOP)\src\os_win.c $(HDR)
$(LTCOMPILE) -c $(TOP)\src\os_win.c
os_os2.lo: $(TOP)\src\os_os2.c $(HDR)
$(LTCOMPILE) -c $(TOP)\src\os_os2.c
pragma.lo: $(TOP)\src\pragma.c $(HDR)
$(LTCOMPILE) -c $(TOP)\src\pragma.c
@ -915,7 +1010,7 @@ sqlite3.h: $(TOP)\src\sqlite.h.in $(TOP)\manifest.uuid $(TOP)\VERSION
$(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP) > sqlite3.h
mkkeywordhash.exe: $(TOP)\tool\mkkeywordhash.c
$(BCC) -Femkkeywordhash.exe $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)\tool\mkkeywordhash.c
$(BCC) -Fe$@ $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)\tool\mkkeywordhash.c /link $(NLTLIBPATHS)
keywordhash.h: $(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe
.\mkkeywordhash.exe > keywordhash.h
@ -1047,6 +1142,7 @@ clean:
del /Q sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
del /Q sqlite3.c
del /Q sqlite3_analyzer.exe sqlite3_analyzer.exp sqlite3_analyzer.c
del /Q sqlite-output.vsix
#
# Windows section
@ -1060,4 +1156,4 @@ sqlite3.def: libsqlite3.lib
| sort >> sqlite3.def
sqlite3.dll: $(LIBOBJ) sqlite3.def
link $(LTLINKOPTS) $(LTLIBPATHS) /DLL /DEF:sqlite3.def /OUT:$@ $(LIBOBJ) $(LTLIBS) $(TLIBS)
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /DEF:sqlite3.def /OUT:$@ $(LIBOBJ) $(LTLIBS) $(TLIBS)

View File

@ -204,8 +204,8 @@ LIBOBJ+= alter.o analyze.o attach.o auth.o \
icu.o insert.o journal.o legacy.o loadext.o \
main.o malloc.o mem0.o mem1.o mem2.o mem3.o mem5.o \
memjournal.o \
mutex.o mutex_noop.o mutex_os2.o mutex_unix.o mutex_w32.o \
notify.o opcodes.o os.o os_os2.o os_unix.o os_win.o \
mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \
notify.o opcodes.o os.o os_unix.o os_win.o \
pager.o parse.o pcache.o pcache1.o pragma.o prepare.o printf.o \
random.o resolve.o rowset.o rtree.o select.o status.o \
table.o tokenize.o trigger.o \
@ -256,14 +256,12 @@ SRC = \
$(TOP)/src/mutex.c \
$(TOP)/src/mutex.h \
$(TOP)/src/mutex_noop.c \
$(TOP)/src/mutex_os2.c \
$(TOP)/src/mutex_unix.c \
$(TOP)/src/mutex_w32.c \
$(TOP)/src/notify.c \
$(TOP)/src/os.c \
$(TOP)/src/os.h \
$(TOP)/src/os_common.h \
$(TOP)/src/os_os2.c \
$(TOP)/src/os_unix.c \
$(TOP)/src/os_win.c \
$(TOP)/src/pager.c \
@ -396,7 +394,7 @@ TESTSRC2 = \
$(TOP)/src/attach.c $(TOP)/src/backup.c $(TOP)/src/btree.c \
$(TOP)/src/build.c $(TOP)/src/ctime.c $(TOP)/src/date.c \
$(TOP)/src/expr.c $(TOP)/src/func.c $(TOP)/src/insert.c $(TOP)/src/os.c \
$(TOP)/src/os_os2.c $(TOP)/src/os_unix.c $(TOP)/src/os_win.c \
$(TOP)/src/os_unix.c $(TOP)/src/os_win.c \
$(TOP)/src/pager.c $(TOP)/src/pragma.c $(TOP)/src/prepare.c \
$(TOP)/src/printf.c $(TOP)/src/random.c $(TOP)/src/pcache.c \
$(TOP)/src/pcache1.c $(TOP)/src/select.c $(TOP)/src/tokenize.c \

View File

@ -1 +1 @@
3.7.13
3.7.14

40
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.62 for sqlite 3.7.13.
# Generated by GNU Autoconf 2.62 for sqlite 3.7.14.
#
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite'
PACKAGE_VERSION='3.7.13'
PACKAGE_STRING='sqlite 3.7.13'
PACKAGE_VERSION='3.7.14'
PACKAGE_STRING='sqlite 3.7.14'
PACKAGE_BUGREPORT=''
# Factoring default headers for most tests.
@ -1485,7 +1485,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures sqlite 3.7.13 to adapt to many kinds of systems.
\`configure' configures sqlite 3.7.14 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1550,7 +1550,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.7.13:";;
short | recursive ) echo "Configuration of sqlite 3.7.14:";;
esac
cat <<\_ACEOF
@ -1666,7 +1666,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
sqlite configure 3.7.13
sqlite configure 3.7.14
generated by GNU Autoconf 2.62
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@ -1680,7 +1680,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by sqlite $as_me 3.7.13, which was
It was created by sqlite $as_me 3.7.14, which was
generated by GNU Autoconf 2.62. Invocation command line was
$ $0 $@
@ -12778,14 +12778,16 @@ $as_echo "$as_me: error: ${with_tclconfig} directory doesn't contain tclConfig.s
fi
# Start autosearch by asking tclsh
if test x"$cross_compiling" = xno; then
for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}`
do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig="$i"
break
fi
done
if test x"${ac_cv_c_tclconfig}" = x ; then
if test x"$cross_compiling" = xno; then
for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}`
do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig="$i"
break
fi
done
fi
fi
# then check for a private Tcl installation
@ -14032,7 +14034,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by sqlite $as_me 3.7.13, which was
This file was extended by sqlite $as_me 3.7.14, which was
generated by GNU Autoconf 2.62. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@ -14085,7 +14087,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\
sqlite config.status 3.7.13
sqlite config.status 3.7.14
configured by $0, generated by GNU Autoconf 2.62,
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
@ -14518,7 +14520,8 @@ $debug ||
if test -n "$CONFIG_FILES"; then
ac_cr=' '
ac_cr='
'
ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
ac_cs_awk_cr='\\r'
@ -15753,4 +15756,3 @@ if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
{ $as_echo "$as_me:$LINENO: WARNING: Unrecognized options: $ac_unrecognized_opts" >&5
$as_echo "$as_me: WARNING: Unrecognized options: $ac_unrecognized_opts" >&2;}
fi

View File

@ -388,14 +388,16 @@ if test "${use_tcl}" = "yes" ; then
fi
# Start autosearch by asking tclsh
if test x"$cross_compiling" = xno; then
for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}`
do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig="$i"
break
fi
done
if test x"${ac_cv_c_tclconfig}" = x ; then
if test x"$cross_compiling" = xno; then
for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}`
do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig="$i"
break
fi
done
fi
fi
# then check for a private Tcl installation

View File

@ -199,7 +199,7 @@ static int icuNext(
while( iStart<iEnd ){
int iWhite = iStart;
U8_NEXT(pCsr->aChar, iWhite, pCsr->nChar, c);
U16_NEXT(pCsr->aChar, iWhite, pCsr->nChar, c);
if( u_isspace(c) ){
iStart = iWhite;
}else{

View File

@ -146,7 +146,7 @@ int sqlite3FtsUnicodeIsalnum(int c){
}
assert( aEntry[0]<key );
assert( key>=aEntry[iRes] );
return (c >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF)));
return (((unsigned int)c) >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF)));
}
return 1;
}

View File

@ -61,8 +61,8 @@ LIBOBJ+= alter.o analyze.o attach.o auth.o \
icu.o insert.o journal.o legacy.o loadext.o \
main.o malloc.o mem0.o mem1.o mem2.o mem3.o mem5.o \
memjournal.o \
mutex.o mutex_noop.o mutex_os2.o mutex_unix.o mutex_w32.o \
notify.o opcodes.o os.o os_os2.o os_unix.o os_win.o \
mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \
notify.o opcodes.o os.o os_unix.o os_win.o \
pager.o parse.o pcache.o pcache1.o pragma.o prepare.o printf.o \
random.o resolve.o rowset.o rtree.o select.o status.o \
table.o tokenize.o trigger.o \
@ -114,14 +114,12 @@ SRC = \
$(TOP)/src/mutex.c \
$(TOP)/src/mutex.h \
$(TOP)/src/mutex_noop.c \
$(TOP)/src/mutex_os2.c \
$(TOP)/src/mutex_unix.c \
$(TOP)/src/mutex_w32.c \
$(TOP)/src/notify.c \
$(TOP)/src/os.c \
$(TOP)/src/os.h \
$(TOP)/src/os_common.h \
$(TOP)/src/os_os2.c \
$(TOP)/src/os_unix.c \
$(TOP)/src/os_win.c \
$(TOP)/src/pager.c \
@ -283,7 +281,6 @@ TESTSRC2 = \
$(TOP)/src/wal.c \
$(TOP)/src/mem5.c \
$(TOP)/src/os.c \
$(TOP)/src/os_os2.c \
$(TOP)/src/os_unix.c \
$(TOP)/src/os_win.c \
$(TOP)/src/pager.c \
@ -622,3 +619,4 @@ clean:
rm -f threadtest3 threadtest3.exe
rm -f sqlite3.c fts?amal.c tclsqlite3.c
rm -f sqlite3_analyzer sqlite3_analyzer.exe sqlite3_analyzer.c
rm -f sqlite-output.vsix

151
manifest
View File

@ -1,12 +1,12 @@
C Merge\slatest\strunk\schanges\swith\ssessions\sbranch.
D 2012-06-09T19:15:43.423
C Merge\sall\sthe\slatest\strunk\schanges\sinto\sthe\ssessions\sbranch.
D 2012-08-15T16:21:55.837
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in d17fddaa4e81f93a7c9c7c0808aacb3fc95f79f4
F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.msc f4c1ecc6adf3e81857ccae612247db401df63e4c
F Makefile.vxworks 3b7fe7a0571fdadc61363ebc1b23732d2d6363ca
F Makefile.msc 49411436c99bf768dcd1cc749a52d7b071803e05
F Makefile.vxworks 879f034a64062a364b21000266bbd5bc6e0c19b9
F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6
F VERSION 3e857b9b826e818eec9411eafe2c3fa22c1dbb8a
F VERSION a71848df48082f1d6585d4b0819d530fc455485d
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F addopcodes.awk 17dc593f791f874d2c23a0f9360850ded0286531
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
@ -15,8 +15,8 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
F config.h.in 0921066a13130082764ab4ab6456f7b5bebe56de
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
F configure 79405675c313ce4a5e94afac6ec880bb3e27b4f1 x
F configure.ac 9ee886c21c095b3272137b1553ae416c8b8c8557
F configure 4dd7d5fa033f649d7372e9ebd4aff68db6026da4 x
F configure.ac 6e909664785b8184db2179013cd9d574f96ca3a3
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/lemon.html 3091574143dd3415669b6745843ff8d011d33549
F doc/pager-invariants.txt 870107036470d7c419e93768676fae2f8749cf9e
@ -62,7 +62,7 @@ F ext/fts3/fts3_aux.c 5205182bd8f372782597888156404766edf5781e
F ext/fts3/fts3_expr.c dbc7ba4c3a6061adde0f38ed8e9b349568299551
F ext/fts3/fts3_hash.c 8dd2d06b66c72c628c2732555a32bc0943114914
F ext/fts3/fts3_hash.h 8331fb2206c609f9fc4c4735b9ab5ad6137c88ec
F ext/fts3/fts3_icu.c 62ec177c55f6a5c6e994dd3e5fd3194b4045c347
F ext/fts3/fts3_icu.c b85eca4a52e5ec11b94392de5167974c11906d4a
F ext/fts3/fts3_porter.c a465b49fcb8249a755792f87516eff182efa42b3
F ext/fts3/fts3_snippet.c bf67520ae9d2352a65368ed101729ff701c08808
F ext/fts3/fts3_term.c a521f75132f9a495bdca1bdd45949b3191c52763
@ -71,7 +71,7 @@ F ext/fts3/fts3_tokenizer.c e94a8b901066031437ccfe4769fc76370257cede
F ext/fts3/fts3_tokenizer.h 66dec98e365854b6cd2d54f1a96bb6d428fc5a68
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
F ext/fts3/fts3_unicode.c 49e36e6ba59f79e6bd6a8bfe434570fe48d20559
F ext/fts3/fts3_unicode2.c 2965d217c37079f1dbbdbd2c58f843be285d73f2
F ext/fts3/fts3_unicode2.c a863f05f758af36777dffc2facc898bc73fec896
F ext/fts3/fts3_write.c 794438f904cdf4516b258e530c0065efadb7b9b5
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
@ -115,7 +115,7 @@ F ext/session/sqlite3session.h f374c9c4c96e08f67ac418871c29d423245c7673
F ext/session/test_session.c ea4dc9b4a1895c8e6bddcbfe3838d7eb57df2d99
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F main.mk d1663c1ef1e9352b86138f40363f172f7a7f7728
F main.mk 1e1c4a0f975cc43e3e4221249367a40c076b34c0
F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac
@ -129,35 +129,35 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
F src/alter.c 149cc80d9257971b0bff34e58fb2263e01998289
F src/analyze.c 70c46504c0d2543ea5cdca01140b2cd3e1d886e7
F src/analyze.c 7553068d21e32a57fc33ab6b2393fc8c1ba41410
F src/attach.c 577bf5675b0c50495fc28549f2fcbdb1bac71143
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c d7fb4c6d2ad3fe51a4ce1a897fde7b00f4de5fef
F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef
F src/backup.c 5b31b24d6814b11de763debf342c8cd0a15a4910
F src/bitvec.c 26675fe8e431dc555e6f2d0e11e651d172234aa1
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c f0b71054103cb77eb5e782088c16998ec4f06624
F src/btree.h 48a013f8964f12d944d90e4700df47b72dd6d923
F src/btreeInt.h 38a639c0542c29fe8331a221c4aed0cb8686249e
F src/build.c 47c4506afe4bcb4ed1f4b5357582d1cb3402f8ad
F src/btree.c 82b6fcbec3101ff951f47797f407d5eb5d06fa44
F src/btree.h 4aee02e879211bfcfd3f551769578d2e940ab6c2
F src/btreeInt.h 4e5c2bd0f9b36b2a815a6d84f771a61a65830621
F src/build.c 0f6b40ad6211dcaba6159d0f9a297f0704f22142
F src/callback.c 0cb4228cdcd827dcc5def98fb099edcc9142dbcd
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c 500d019da966631ad957c37705642be87524463b
F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
F src/delete.c 32041c65dc05a94914cf979fad7b82bc8a963fe9
F src/expr.c 06a7733d19dc725dc46ba51afd9feadb4b85d991
F src/expr.c e2927abf9c69ce4ff9a931bd201946961c34819a
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5
F src/func.c c6b3c94320253a35bda43fb69cc292618e3285d6
F src/func.c 18dfedfb857e100b05755a1b12e88b389f957879
F src/global.c 4cfdca5cb0edd33c4d021baec4ede958cb2c793b
F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af
F src/hash.c a4031441741932da9e7a65bee2b36b5d0e81c073
F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c e32d8d0b761ae5e57d804948bb4e01029a9653b0
F src/insert.c 49dd0445a92aece7dea9f9b3018e479892b77a68
F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416
F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d
F src/main.c 629ec4720d85c3908a896f15002e65cae7405caa
F src/main.c 1f15146d32b183d45fd0d41e8370a326c5d647ac
F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c b3677415e69603d6a0e7c5410a1b3731d55beda1
@ -166,35 +166,33 @@ F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534
F src/mem5.c c2c63b7067570b00bf33d751c39af24182316f7f
F src/memjournal.c 0ebce851677a7ac035ba1512a7e65851b34530c6
F src/mutex.c d3b66a569368015e0fcb1ac15f81c119f504d3bc
F src/mutex.h 2a79e0c10c26412546b501ee0f3d92b42decf63e
F src/mutex.h 5bc526e19dccc412b7ff04642f6fdad3fdfdabea
F src/mutex_noop.c 7682796b7d8d39bf1c138248858efcd10c9e1553
F src/mutex_os2.c 882d735098c07c8c6a5472b8dd66e19675fe117f
F src/mutex_unix.c c3a4e00f96ba068a8dbef34084465979aaf369cc
F src/mutex_w32.c db8970270841e2385a43602477e84c4b19aff1db
F src/mutex_w32.c 32a9b3841e2d757355f0012b860b1bc5e01eafa0
F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
F src/os.c e1acdc09ff3ac2412945cca9766e2dcf4675f31c
F src/os.h 38aabd5e3ecd4162332076f55bb09cec02165cca
F src/os.h 027491c77d2404c0a678bb3fb06286f331eb9b57
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440
F src/os_unix.c d7c96b5d140f550f07345870112fae5d7ef99757
F src/os_win.c e3d3d3e26b65a35d4293d753137a58510bd3299b
F src/os_win.c 370c6f3399e3cd9f14343fb7dc4b2bbe8619d3bf
F src/pager.c e381c118b77dc22021a1a59d3fec24815e91df78
F src/pager.h 8b8c9bc065a3c66769df8724dfdf492ee1aab3c5
F src/parse.y f29df90bd3adc64b33114ab1de9fb7768fcf2099
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
F src/pcache.h 1b5dcc3dc8103d03e625b177023ee67764fa6b7c
F src/pcache1.c 2234d84f9c003d800a57f00f8535c91667fa4f6c
F src/pragma.c eee3e3161f82a1e06f632a8d2a82b29ba3c45889
F src/pcache1.c 9fd22671c270b35131ef480bbc00392b8b5f8ab9
F src/pragma.c 97f9357f0e7e5fb46a2519f14539550aa07db49f
F src/prepare.c 33291b83cca285718048d219c67b8298501fa3a5
F src/printf.c 7ffb4ebb8b341f67e049695ba031da717b3d2699
F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
F src/resolve.c b3c70ab28cac60de33684c9aa9e5138dcf71d6dd
F src/rowset.c f6a49f3e9579428024662f6e2931832511f831a1
F src/select.c f6c4833c4d8e94714761d99013d74f381e084f1d
F src/shell.c c16f72e34f611f060546709564c121a67cb2b31b
F src/sqlite.h.in 40b1e84aa065bcc05d583c74036bc2dd836db36d
F src/select.c a365da6d7a6d7d8a10ad60ca71837ab5e9369466
F src/shell.c 076e1c90d594644f36027c8ecff9a392cf2d3a06
F src/sqlite.h.in f0bc4a3e082cda4e52ce74e96dc47043ec3c3e9b
F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
F src/sqliteInt.h 5b446b260eb774eb663ea0fe8dab10e056a9a859
F src/sqliteInt.h 23284c2be677c1fb3c14051cd67427077825e8ee
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@ -206,16 +204,16 @@ F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7
F src/test5.c a6d1ac55ac054d0b2b8f37b5e655b6c92645a013
F src/test6.c 417e1e214734393c24a8ee80b41485a9c4169123
F src/test7.c 2e0781754905c8adc3268d8f0967e7633af58843
F src/test8.c 235f1d19716fa768c46fc461ccbf529b2c9e4399
F src/test8.c 8bcce65e5ee027fbfd7da41d28371aabbfd369ff
F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
F src/test_async.c 0612a752896fad42d55c3999a5122af10dcf22ad
F src/test_autoext.c 30e7bd98ab6d70a62bb9ba572e4c7df347fe645e
F src/test_backup.c c129c91127e9b46e335715ae2e75756e25ba27de
F src/test_btree.c 5b89601dcb42a33ba8b820a6b763cc9cb48bac16
F src/test_config.c f87165e4c5eb066fe9c930e634dfe65199f1bfc5
F src/test_config.c aa0f42add3ea63920a8b7d1869be4c9b4106bdaa
F src/test_demovfs.c 20a4975127993f4959890016ae9ce5535a880094
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
F src/test_func.c 090f2c3339e85c2c964435f99aed6f3da9d59525
F src/test_func.c 3a8dd37c08ab43b76d38eea2836e34a3897bf170
F src/test_fuzzer.c 1d26aa965120420bc14807da29d4d4541bfa6148
F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
F src/test_init.c 3cbad7ce525aec925f8fda2192d576d47f0d478a
@ -230,18 +228,18 @@ F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e
F src/test_onefile.c 0396f220561f3b4eedc450cef26d40c593c69a25
F src/test_osinst.c 90a845c8183013d80eccb1f29e8805608516edba
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
F src/test_quota.c 0af3e1e9a1f22bc5f431dd3efcc32762f4109f58
F src/test_quota.c 8ab295092c70903ca6f3209fa4c75f5cb6c1bf8e
F src/test_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb
F src/test_rtree.c aba603c949766c4193f1068b91c787f57274e0d9
F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0
F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f
F src/test_spellfix.c 495535f3eb57acdc384572da570e869bb1834bf4
F src/test_spellfix.c 3a260d237fabbf5884389aa8c0e516b4e61ab98a
F src/test_stat.c d1569c7a4839f13e80187e2c26b2ab4da2d03935
F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd
F src/test_syscall.c a992d8c80ea91fbf21fb2dd570db40e77dd7e6ae
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
F src/test_thread.c e286f2173563f2a1747c24bcda6b9d030bf4f4e4
F src/test_vfs.c 9d934e111021d56c629efc73a796648c9519ad12
F src/test_vfs.c c6260ef238c1142c8f8bd402db02216afd182ae3
F src/test_vfstrace.c 6b28adb2a0e8ecd0f2e3581482e1f658b11b4067
F src/test_wholenumber.c 3d2b9ed1505c40ad5c5ca2ad16ae7a289d6cc251
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
@ -249,19 +247,19 @@ F src/tokenize.c 1e86210d3976717a19238ea7b047fac481fe8c12
F src/trigger.c ee7e178fb9188f44b532cebd449a7c1df90fb684
F src/update.c 89de085a0bf4da448472029d0420a2b1cf1824ee
F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84
F src/util.c 4f6cfad661b2e3454b0cdd5b1b9d39a54942d0e3
F src/util.c 0af2e515dc0dabacec931bca39525f6c3f1c5455
F src/vacuum.c 587a52bb8833d7ac15af8916f25437e2575028bd
F src/vdbe.c 687fdb8636a4ca286febe4e4e4f19b6f681b445a
F src/vdbe.c 9a1c2f78ae8baba248c0369a2f7717a288c22205
F src/vdbe.h 87b8ff40de3f55dbcdc33029416862f517c37a2f
F src/vdbeInt.h f1956902b06b4f05ce965aafab6fe220a5477f9c
F src/vdbeapi.c 2fc381f651738feb2495cb001cf2114dea596cc3
F src/vdbeaux.c dcff925ee54f73a6a729ea56e4197c91b38645c4
F src/vdbeInt.h 3f5d994703b6d61032d48f3086329c960b1697e9
F src/vdbeapi.c 7d23764ea26c1fff2959e6a0984dd96de0fa8f75
F src/vdbeaux.c 91923b781aa3db404fea7c7567617bf61a9a32d0
F src/vdbeblob.c 11248c6362389569764682eb0f59ce910f3cc381
F src/vdbemem.c cb55e84b8e2c15704968ee05f0fae25883299b74
F src/vdbesort.c b25814d385895544ebc8118245c8311ded7f81c9
F src/vdbetrace.c 79059ebd17b3c8545fab2a24253713e77e4ab392
F src/vdbesort.c 0dc1b274dcb4d4c8e71b0b2b15261f286caba39b
F src/vdbetrace.c 8bd5da325fc90f28464335e4cc4ad1407fe30835
F src/vtab.c bb8ea3a26608bb1357538a5d2fc72beba6638998
F src/wal.c 7bb3ad807afc7973406c805d5157ec7a2f65e146
F src/wal.c 9294df6f96aae5909ae1a9b733fd1e1b4736978b
F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
F src/where.c 24c7494d8875ead994b4dfe5461340c27fd424ca
@ -286,6 +284,7 @@ F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7
F test/async4.test 1787e3952128aa10238bf39945126de7ca23685a
F test/async5.test 0dd8701bd588bf6e70c2557a22ae3f22b2567b4c
F test/atof1.test 9bf1d25180a2e05fc12ce3940cc8003033642f68
F test/attach.test 0d112b7713611fdf0340260192749737135fda5f
F test/attach2.test e54436ed956d3d88bdee61221da59bf3935a0966
F test/attach3.test d89ccfe4fe6e2b5e368d480fcdfe4b496c54cf4e
@ -300,7 +299,7 @@ F test/autovacuum.test fcaf4616ae5bb18098db1cb36262565e5c841c3c
F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85
F test/backcompat.test bccbc64769d9c755ad65ee7c2f7336b86e3cc0c8
F test/backup.test 717346db953e9e435c2a94916e4af177330d60d3
F test/backup.test c9cdd23a495864b9edf75a9fa66f5cb7e10fcf62
F test/backup2.test 34986ef926ea522911a51dfdb2f8e99b7b75ebcf
F test/backup_ioerr.test 40d208bc9224b666ee3ed423f49bc9062a36a9d0
F test/backup_malloc.test 7162d604ec2b4683c4b3799a48657fb8b5e2d450
@ -375,7 +374,7 @@ F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8
F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47
F test/date.test a18a2ce81add84b17b06559e82ad7bb91bc6ddff
F test/date.test f3228180c87bbe5d39c9397bf001c0095c3821b9
F test/dbstatus.test 207e5b63fcb7b9c3bb8e1fdf38ebd4654ad0e54b
F test/dbstatus2.test b1de8250fde1f3474d6b86f0e89de38d84794f56
F test/default.test 6faf23ccb300114924353007795aa9a8ec0aa9dc
@ -476,7 +475,7 @@ F test/fts3al.test 07d64326e79bbdbab20ee87fc3328fbf01641c9f
F test/fts3am.test 218aa6ba0dfc50c7c16b2022aac5c6be593d08d8
F test/fts3an.test a49ccadc07a2f7d646ec1b81bc09da2d85a85b18
F test/fts3ao.test e7b80272efcced57d1d087a9da5c690dd7c21fd9
F test/fts3atoken.test 402ef2f7c2fb4b3d4fa0587df6441c1447e799b3
F test/fts3atoken.test fb398ab50aa232489e2a17f9b29d7ad3a3885f36
F test/fts3auto.test b39f3f51227aea145eae6638690355dbdf9abf18
F test/fts3aux1.test 0b02743955d56fc0d4d66236a26177bd1b726de0
F test/fts3b.test e93bbb653e52afde110ad53bbd793f14fe7a8984
@ -513,8 +512,8 @@ F test/fts4langid.test 24a6e41063b416bbdf371ff6b4476fa41c194aa7
F test/fts4merge.test c424309743fdd203f8e56a1f1cd7872cd66cc0ee
F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891
F test/fts4merge3.test aab02a09f50fe6baaddc2e159c3eabc116d45fc7
F test/fts4unicode.test 247e6c64563b5f930aec0f89a5b01ed6b4b129cd
F test/func.test 9809b7622d721904a8cc33c1ffb87f46d506ed01
F test/fts4unicode.test aad033abdcfa0f87ce5f56468f59fdf2a0acbcef
F test/func.test 0d89043dab9a8853358d14c68e028ee0093bf066
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
F test/func3.test 001021e5b88bd02a3b365a5c5fd8f6f49d39744a
F test/fuzz-oss1.test 4912e528ec9cf2f42134456933659d371c9e0d74
@ -544,6 +543,7 @@ F test/index.test b5429732b3b983fa810e3ac867d7ca85dae35097
F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6
F test/index3.test 423a25c789fc8cc51aaf2a4370bbdde2d9e9eed7
F test/index4.test 2983216eb8c86ee62d9ed7cb206b5cc3331c0026
F test/index5.test edc8c64ca78bee140c21ce3836820fadf47906bb
F test/indexedby.test be501e381b82b2f8ab406309ba7aac46e221f4ad
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
@ -579,7 +579,7 @@ F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
F test/like.test 7b4aaa4a8192fdec90e0a905984c92a688c51e48
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
F test/limit.test 2db7b3b34fb925b8e847d583d2eb67531d0ce67e
F test/loadext.test dab17f7014f8079698dbd4b02705562b0ce6db5f
F test/loadext.test 2b5e249c51c986a5aff1f0950cf7ba30976c8f22
F test/loadext2.test 0bcaeb4d81cd5b6e883fdfea3c1bdbe1f173cbca
F test/lock.test db74fdf5a73bad29ab3d862ea78bf1068972cc1d
F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff
@ -629,7 +629,7 @@ F test/misc3.test fe55130a43e444ee75e2156ff75dc96e964b5738
F test/misc4.test 9c078510fbfff05a9869a0b6d8b86a623ad2c4f6
F test/misc5.test 528468b26d03303b1f047146e5eefc941b9069f5
F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
F test/misc7.test 4337d84e441f36cee62656f9f7ba8bc22a7ca721
F test/misc7.test f00dad9a004da659330013e6f21819d018b683d3
F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054
F test/multiplex.test e08cc7177bd6d85990ee1d71100bb6c684c02256
F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a
@ -654,8 +654,8 @@ F test/pageropt.test 9191867ed19a2b3db6c42d1b36b6fbc657cd1ab0
F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0
F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
F test/permutations.test c67d4f41daa30aeb157eb45d991eb3fc271a7096
F test/pragma.test cb736bcc75b8b629af21ac0ad83ba1d054a2107b
F test/permutations.test b4f49af522304134d32966ccef8b00d2c4765664
F test/pragma.test a62f73293b0f0d79b0c87f8dd32d46fe53b0bd17
F test/pragma2.test 3a55f82b954242c642f8342b17dffc8b47472947
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301
@ -670,7 +670,7 @@ F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df
F test/rdonly.test c267d050a1d9a6a321de502b737daf28821a518d
F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
F test/releasetest.mk 2eced2f9ae701fd0a29e714a241760503ccba25a
F test/releasetest.tcl fa302d03fd9acfce6d910553a33473bfcf561958
F test/releasetest.tcl 4014e2bfb93f276d82a604e7a5eda62c129916c9
F test/rollback.test a1b4784b864331eae8b2a98c189efa2a8b11ff07
F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
F test/rowid.test e58e0acef38b527ed1b0b70d3ada588f804af287
@ -688,6 +688,7 @@ F test/schema3.test 1bc1008e1f8cb5654b248c55f27249366eb7ed38
F test/schema4.test e6a66e20cc69f0e306667c08be7fda3d11707dc5
F test/schema5.test 0103e4c0313b3725b5ae5600bdca53006ab53db3
F test/securedel.test 87a2561151af1f1e349071a89fdd77059f50113c
F test/securedel2.test f13a916155f790a6b9de835049641b14ef312986
F test/select1.test deba017eed9daa5af33de868676c997e7eebb931
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
@ -730,6 +731,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
F test/spellfix.test 8bdb52dc612711660cfb64540b11830f21827983
F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298
F test/stat.test 08e8185b3fd5b010c90d7ad82b9dd4ea1cbf14b0
F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
@ -939,8 +941,8 @@ F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
F test/vtab_shared.test 82f463886e18d7f8395a4b6167c91815efe54839
F test/wal.test a040047d7f2b9f34bc4d597964e5e7c09609c635
F test/wal2.test d5021064bebfc717fe2bf4db2536ea030b76a773
F test/wal3.test 6504bbf348b2d6dfade64a064f1050fd617e8706
F test/wal2.test 7ca814723c487de87d945cdc85c9a0fa45fa8de8
F test/wal3.test b22eb662bcbc148c5f6d956eaf94b047f7afe9c0
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
F test/wal5.test f58ed4b8b542f71c7441da12fbd769d99b362437
F test/wal6.test 2e3bc767d9c2ce35c47106148d43fcbd072a93b3
@ -958,10 +960,10 @@ F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483
F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c
F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496
F test/walpersist.test 8c6b7e3ec1ba91b5e4dc4e0921d6d3f87cd356a6
F test/walro.test e6bb27762c9f22601cbb8bff6e0acfd124e74b63
F test/walro.test a31deb621033442a76c3a61e44929250d06f81b1
F test/walshared.test 6dda2293880c300baf5d791c307f653094585761
F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
F test/walthread.test a2ed5270eb695284d4ad27d252517bdc3317ee2a
F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
F test/where.test 4c9f69987ed2aa0173fa930f2b41ab9879478cd8
F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554
F test/where3.test 667e75642102c97a00bf9b23d3cb267db321d006
@ -979,6 +981,7 @@ F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31
F test/win32lock.test b2a539e85ae6b2d78475e016a9636b4451dc7fb9
F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688
F test/zerodamage.test 0de750389990b1078bab203c712dc3fefd1d8b82
F tool/build-all-msvc.bat 1a18aa39983ae7354d834bc55a850a54fc007576 x
F tool/build-shell.sh b64a481901fc9ffe5ca8812a2a9255b6cfb77381
F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2
@ -986,17 +989,18 @@ F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439
F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4
F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
F tool/lemon.c 90f46af31c92b940fec25b491f39409fd95dcdfa
F tool/lemon.c 8b7afc12a6671e3a932a5209a9e64abbfbd0f025
F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc
F tool/mkkeywordhash.c bb52064aa614e1426445e4b2b9b00eeecd23cc79
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
F tool/mksqlite3c-noext.tcl 105023aa86f696a74b1d6a4929d1e1c3baf9471c
F tool/mksqlite3c.tcl f289ba51f74f45c71a80c13e6c74a6dd92763253
F tool/mksqlite3c-noext.tcl 8bce31074e4cbe631bb7676526a048335f4c9f02
F tool/mksqlite3c.tcl 589c7f44e990be1b8443cfe4808dce392b0327fa
F tool/mksqlite3h.tcl 78013ad79a5e492e5f764f3c7a8ef834255061f8
F tool/mksqlite3internalh.tcl 7b43894e21bcb1bb39e11547ce7e38a063357e87
F tool/mksqlite3internalh.tcl 3dca7bb5374cee003379b8cbac73714f610ef795
F tool/mkvsix.tcl 19b2ab9ea16445953a76568a5bbe4cb864f92dfe
F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091
F tool/omittest.tcl 72a49b8a9a8b0bf213a438180307a0df836d4380
F tool/omittest.tcl 4665982e95a6e5c1bd806cf7bc3dea95be422d77
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5
@ -1018,7 +1022,8 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
P c62140398344fd1a68a3e6dfe8b4fab280731ebb 0ae0ce630a2e11f81dca50a9cfb04c4a41c03b2d
R 3d7646a2017b0e596385909c0de9563e
U dan
Z 770dd5c1bc35db7eb59646895dc3fb87
F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9
P 47f8f0711d63ef4166db9115db44b166959df14c 772d0de3f311f2035f8a42f01371c96c9fa587ce
R e864d66a36e838c2faa41d39d7a05218
U drh
Z abda2788c852df70f4e42cf73ff52089

View File

@ -1 +1 @@
47f8f0711d63ef4166db9115db44b166959df14c
fc07a4795e027108674d1d41eb4350df629ddc8b

View File

@ -176,7 +176,7 @@ static void openStatTable(
"CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols
);
aRoot[i] = pParse->regRoot;
aCreateTbl[i] = 1;
aCreateTbl[i] = OPFLAG_P2ISREG;
}else{
/* The table already exists. If zWhere is not NULL, delete all entries
** associated with the table zWhere. If zWhere is NULL, delete the
@ -256,12 +256,11 @@ static void stat3Init(
nRow = (tRowcnt)sqlite3_value_int64(argv[0]);
mxSample = sqlite3_value_int(argv[1]);
n = sizeof(*p) + sizeof(p->a[0])*mxSample;
p = sqlite3_malloc( n );
p = sqlite3MallocZero( n );
if( p==0 ){
sqlite3_result_error_nomem(context);
return;
}
memset(p, 0, n);
p->a = (struct Stat3Sample*)&p[1];
p->nRow = nRow;
p->mxSample = mxSample;

View File

@ -164,7 +164,7 @@ sqlite3_backup *sqlite3_backup_init(
** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a
** call to sqlite3_backup_init() and is destroyed by a call to
** sqlite3_backup_finish(). */
p = (sqlite3_backup *)sqlite3_malloc(sizeof(sqlite3_backup));
p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup));
if( !p ){
sqlite3Error(pDestDb, SQLITE_NOMEM, 0);
}
@ -172,7 +172,6 @@ sqlite3_backup *sqlite3_backup_init(
/* If the allocation succeeded, populate the new object. */
if( p ){
memset(p, 0, sizeof(sqlite3_backup));
p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb);
p->pDest = findBtree(pDestDb, pDestDb, zDestDb);
p->pDestDb = pDestDb;
@ -543,14 +542,14 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
*/
int sqlite3_backup_finish(sqlite3_backup *p){
sqlite3_backup **pp; /* Ptr to head of pagers backup list */
MUTEX_LOGIC( sqlite3_mutex *mutex; ) /* Mutex to protect source database */
sqlite3 *pSrcDb; /* Source database connection */
int rc; /* Value to return */
/* Enter the mutexes */
if( p==0 ) return SQLITE_OK;
sqlite3_mutex_enter(p->pSrcDb->mutex);
pSrcDb = p->pSrcDb;
sqlite3_mutex_enter(pSrcDb->mutex);
sqlite3BtreeEnter(p->pSrc);
MUTEX_LOGIC( mutex = p->pSrcDb->mutex; )
if( p->pDestDb ){
sqlite3_mutex_enter(p->pDestDb->mutex);
}
@ -576,7 +575,7 @@ int sqlite3_backup_finish(sqlite3_backup *p){
/* Exit the mutexes and free the backup context structure. */
if( p->pDestDb ){
sqlite3_mutex_leave(p->pDestDb->mutex);
sqlite3LeaveMutexAndCloseZombie(p->pDestDb);
}
sqlite3BtreeLeave(p->pSrc);
if( p->pDestDb ){
@ -585,7 +584,7 @@ int sqlite3_backup_finish(sqlite3_backup *p){
** sqlite3_backup_finish(). */
sqlite3_free(p);
}
sqlite3_mutex_leave(mutex);
sqlite3LeaveMutexAndCloseZombie(pSrcDb);
return rc;
}

View File

@ -340,10 +340,9 @@ int sqlite3BitvecBuiltinTest(int sz, int *aOp){
/* Allocate the Bitvec to be tested and a linear array of
** bits to act as the reference */
pBitvec = sqlite3BitvecCreate( sz );
pV = sqlite3_malloc( (sz+7)/8 + 1 );
pV = sqlite3MallocZero( (sz+7)/8 + 1 );
pTmpSpace = sqlite3_malloc(BITVEC_SZ);
if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end;
memset(pV, 0, (sz+7)/8 + 1);
/* NULL pBitvec tests */
sqlite3BitvecSet(0, 1);

View File

@ -5926,7 +5926,8 @@ static int balance_nonroot(
MemPage *pParent, /* Parent page of siblings being balanced */
int iParentIdx, /* Index of "the page" in pParent */
u8 *aOvflSpace, /* page-size bytes of space for parent ovfl */
int isRoot /* True if pParent is a root-page */
int isRoot, /* True if pParent is a root-page */
int bBulk /* True if this call is part of a bulk load */
){
BtShared *pBt; /* The whole database */
int nCell = 0; /* Number of cells in apCell[] */
@ -5990,18 +5991,19 @@ static int balance_nonroot(
i = pParent->nOverflow + pParent->nCell;
if( i<2 ){
nxDiv = 0;
nOld = i+1;
}else{
nOld = 3;
assert( bBulk==0 || bBulk==1 );
if( iParentIdx==0 ){
nxDiv = 0;
}else if( iParentIdx==i ){
nxDiv = i-2;
nxDiv = i-2+bBulk;
}else{
assert( bBulk==0 );
nxDiv = iParentIdx-1;
}
i = 2;
i = 2-bBulk;
}
nOld = i+1;
if( (i+nxDiv-pParent->nOverflow)==pParent->nCell ){
pRight = &pParent->aData[pParent->hdrOffset+8];
}else{
@ -6210,7 +6212,9 @@ static int balance_nonroot(
d = r + 1 - leafData;
assert( d<nMaxCells );
assert( r<nMaxCells );
while( szRight==0 || szRight+szCell[d]+2<=szLeft-(szCell[r]+2) ){
while( szRight==0
|| (!bBulk && szRight+szCell[d]+2<=szLeft-(szCell[r]+2))
){
szRight += szCell[d] + 2;
szLeft -= szCell[r] + 2;
cntNew[i-1]--;
@ -6257,7 +6261,7 @@ static int balance_nonroot(
if( rc ) goto balance_cleanup;
}else{
assert( i>0 );
rc = allocateBtreePage(pBt, &pNew, &pgno, pgno, 0);
rc = allocateBtreePage(pBt, &pNew, &pgno, (bBulk ? 1 : pgno), 0);
if( rc ) goto balance_cleanup;
apNew[i] = pNew;
nNew++;
@ -6469,6 +6473,7 @@ static int balance_nonroot(
** sibling page j. If the siblings are not leaf pages of an
** intkey b-tree, then cell i was a divider cell. */
assert( j+1 < ArraySize(apCopy) );
assert( j+1 < nOld );
pOld = apCopy[++j];
iNextOld = i + !leafData + pOld->nCell + pOld->nOverflow;
if( pOld->nOverflow ){
@ -6707,7 +6712,7 @@ static int balance(BtCursor *pCur){
** pSpace buffer passed to the latter call to balance_nonroot().
*/
u8 *pSpace = sqlite3PageMalloc(pCur->pBt->pageSize);
rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1);
rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1, pCur->hints);
if( pFree ){
/* If pFree is not NULL, it points to the pSpace buffer used
** by a previous call to balance_nonroot(). Its contents are
@ -8294,3 +8299,12 @@ int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){
pBt->btsFlags &= ~BTS_NO_WAL;
return rc;
}
/*
** set the mask of hint flags for cursor pCsr. Currently the only valid
** values are 0 and BTREE_BULKLOAD.
*/
void sqlite3BtreeCursorHints(BtCursor *pCsr, unsigned int mask){
assert( mask==BTREE_BULKLOAD || mask==0 );
pCsr->hints = mask;
}

View File

@ -135,6 +135,12 @@ int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
#define BTREE_USER_VERSION 6
#define BTREE_INCR_VACUUM 7
/*
** Values that may be OR'd together to form the second argument of an
** sqlite3BtreeCursorHints() call.
*/
#define BTREE_BULKLOAD 0x00000001
int sqlite3BtreeCursor(
Btree*, /* BTree containing table to open */
int iTable, /* Index of root page */
@ -178,8 +184,8 @@ struct Pager *sqlite3BtreePager(Btree*);
int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
void sqlite3BtreeCacheOverflow(BtCursor *);
void sqlite3BtreeClearCursor(BtCursor *);
int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask);
#ifndef NDEBUG
int sqlite3BtreeCursorIsValid(BtCursor*);

View File

@ -510,6 +510,7 @@ struct BtCursor {
#ifndef SQLITE_OMIT_INCRBLOB
u8 isIncrblobHandle; /* True if this cursor is an incr. io handle */
#endif
u8 hints; /* As configured by CursorSetHints() */
i16 iPage; /* Index of current page in apPage */
u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */
MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */

View File

@ -1581,7 +1581,7 @@ void sqlite3EndTable(
assert(pParse->nTab==1);
sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb);
sqlite3VdbeChangeP5(v, 1);
sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG);
pParse->nTab = 2;
sqlite3SelectDestInit(&dest, SRT_Table, 1);
sqlite3Select(pParse, pSelect, &dest);
@ -2397,9 +2397,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
pKey = sqlite3IndexKeyinfo(pParse, pIndex);
sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb,
(char *)pKey, P4_KEYINFO_HANDOFF);
if( memRootPage>=0 ){
sqlite3VdbeChangeP5(v, 1);
}
sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
#ifndef SQLITE_OMIT_MERGE_SORT
/* Open the sorter cursor if we are to use one. */

View File

@ -1701,7 +1701,7 @@ int sqlite3CodeSubselect(
assert( !isRowid );
sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
dest.affinity = (u8)affinity;
dest.affSdst = (u8)affinity;
assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
pExpr->x.pSelect->iLimit = 0;
if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){
@ -1794,11 +1794,11 @@ int sqlite3CodeSubselect(
sqlite3SelectDestInit(&dest, 0, ++pParse->nMem);
if( pExpr->op==TK_SELECT ){
dest.eDest = SRT_Mem;
sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iParm);
sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iSDParm);
VdbeComment((v, "Init subquery result"));
}else{
dest.eDest = SRT_Exists;
sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iParm);
sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
VdbeComment((v, "Init EXISTS result"));
}
sqlite3ExprDelete(pParse->db, pSel->pLimit);
@ -1808,7 +1808,7 @@ int sqlite3CodeSubselect(
if( sqlite3Select(pParse, pSel, &dest) ){
return 0;
}
rReg = dest.iParm;
rReg = dest.iSDParm;
ExprSetIrreducible(pExpr);
break;
}

View File

@ -863,8 +863,19 @@ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
assert( argc==1 );
UNUSED_PARAMETER(argc);
switch( sqlite3_value_type(argv[0]) ){
case SQLITE_INTEGER:
case SQLITE_FLOAT: {
double r1, r2;
char zBuf[50];
r1 = sqlite3_value_double(argv[0]);
sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1);
sqlite3AtoF(zBuf, &r2, 20, SQLITE_UTF8);
if( r1!=r2 ){
sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.20e", r1);
}
sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
break;
}
case SQLITE_INTEGER: {
sqlite3_result_value(context, argv[0]);
break;
}

View File

@ -113,7 +113,11 @@ static int rehash(Hash *pH, unsigned int new_size){
/* The inability to allocates space for a larger hash table is
** a performance hit but it is not a fatal error. So mark the
** allocation as a benign.
** allocation as a benign. Use sqlite3Malloc()/memset(0) instead of
** sqlite3MallocZero() to make the allocation, as sqlite3MallocZero()
** only zeroes the requested number of bytes whereas this module will
** use the actual amount of space allocated for the hash table (which
** may be larger than the requested amount).
*/
sqlite3BeginBenignMalloc();
new_ht = (struct _ht *)sqlite3Malloc( new_size*sizeof(struct _ht) );

View File

@ -597,7 +597,7 @@ void sqlite3Insert(
VdbeComment((v, "SELECT eof flag"));
sqlite3SelectDestInit(&dest, SRT_Coroutine, ++pParse->nMem);
addrSelect = sqlite3VdbeCurrentAddr(v)+2;
sqlite3VdbeAddOp2(v, OP_Integer, addrSelect-1, dest.iParm);
sqlite3VdbeAddOp2(v, OP_Integer, addrSelect-1, dest.iSDParm);
j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
VdbeComment((v, "Jump over SELECT coroutine"));
@ -608,15 +608,15 @@ void sqlite3Insert(
goto insert_cleanup;
}
sqlite3VdbeAddOp2(v, OP_Integer, 1, regEof); /* EOF <- 1 */
sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm); /* yield X */
sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); /* yield X */
sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort);
VdbeComment((v, "End of SELECT coroutine"));
sqlite3VdbeJumpHere(v, j1); /* label B: */
regFromSelect = dest.iMem;
regFromSelect = dest.iSdst;
assert( pSelect->pEList );
nColumn = pSelect->pEList->nExpr;
assert( dest.nMem==nColumn );
assert( dest.nSdst==nColumn );
/* Set useTempTable to TRUE if the result of the SELECT statement
** should be written into a temporary table (template 4). Set to
@ -652,7 +652,7 @@ void sqlite3Insert(
regRec = sqlite3GetTempReg(pParse);
regTempRowid = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn);
addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm);
addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
addrIf = sqlite3VdbeAddOp1(v, OP_If, regEof);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec);
sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid);
@ -789,7 +789,7 @@ void sqlite3Insert(
** goto C
** D: ...
*/
addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm);
addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
addrInsTop = sqlite3VdbeAddOp1(v, OP_If, regEof);
}

View File

@ -765,13 +765,25 @@ static void disconnectAllVtab(sqlite3 *db){
#endif
}
/*
** Return TRUE if database connection db has unfinalized prepared
** statements or unfinished sqlite3_backup objects.
*/
static int connectionIsBusy(sqlite3 *db){
int j;
assert( sqlite3_mutex_held(db->mutex) );
if( db->pVdbe ) return 1;
for(j=0; j<db->nDb; j++){
Btree *pBt = db->aDb[j].pBt;
if( pBt && sqlite3BtreeIsInBackup(pBt) ) return 1;
}
return 0;
}
/*
** Close an existing SQLite database
*/
int sqlite3_close(sqlite3 *db){
HashElem *i; /* Hash table iterator */
int j;
static int sqlite3Close(sqlite3 *db, int forceZombie){
if( !db ){
return SQLITE_OK;
}
@ -792,25 +804,63 @@ int sqlite3_close(sqlite3 *db){
*/
sqlite3VtabRollback(db);
/* If there are any outstanding VMs, return SQLITE_BUSY. */
if( db->pVdbe ){
sqlite3Error(db, SQLITE_BUSY,
"unable to close due to unfinalised statements");
/* Legacy behavior (sqlite3_close() behavior) is to return
** SQLITE_BUSY if the connection can not be closed immediately.
*/
if( !forceZombie && connectionIsBusy(db) ){
sqlite3Error(db, SQLITE_BUSY, "unable to close due to unfinalized "
"statements or unfinished backups");
sqlite3_mutex_leave(db->mutex);
return SQLITE_BUSY;
}
assert( sqlite3SafetyCheckSickOrOk(db) );
for(j=0; j<db->nDb; j++){
Btree *pBt = db->aDb[j].pBt;
if( pBt && sqlite3BtreeIsInBackup(pBt) ){
sqlite3Error(db, SQLITE_BUSY,
"unable to close due to unfinished backup operation");
sqlite3_mutex_leave(db->mutex);
return SQLITE_BUSY;
}
/* Convert the connection into a zombie and then close it.
*/
db->magic = SQLITE_MAGIC_ZOMBIE;
sqlite3LeaveMutexAndCloseZombie(db);
return SQLITE_OK;
}
/*
** Two variations on the public interface for closing a database
** connection. The sqlite3_close() version returns SQLITE_BUSY and
** leaves the connection option if there are unfinalized prepared
** statements or unfinished sqlite3_backups. The sqlite3_close_v2()
** version forces the connection to become a zombie if there are
** unclosed resources, and arranges for deallocation when the last
** prepare statement or sqlite3_backup closes.
*/
int sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); }
int sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); }
/*
** Close the mutex on database connection db.
**
** Furthermore, if database connection db is a zombie (meaning that there
** has been a prior call to sqlite3_close(db) or sqlite3_close_v2(db)) and
** every sqlite3_stmt has now been finalized and every sqlite3_backup has
** finished, then free all resources.
*/
void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
HashElem *i; /* Hash table iterator */
int j;
/* If there are outstanding sqlite3_stmt or sqlite3_backup objects
** or if the connection has not yet been closed by sqlite3_close_v2(),
** then just leave the mutex and return.
*/
if( db->magic!=SQLITE_MAGIC_ZOMBIE || connectionIsBusy(db) ){
sqlite3_mutex_leave(db->mutex);
return;
}
/* If we reach this point, it means that the database connection has
** closed all sqlite3_stmt and sqlite3_backup objects and has been
** pased to sqlite3_close (meaning that it is a zombie). Therefore,
** go ahead and free all resources.
*/
/* Free any outstanding Savepoint structures. */
sqlite3CloseSavepoints(db);
@ -898,7 +948,6 @@ int sqlite3_close(sqlite3 *db){
sqlite3_free(db->lookaside.pStart);
}
sqlite3_free(db);
return SQLITE_OK;
}
/*

View File

@ -36,8 +36,6 @@
** SQLITE_MUTEX_PTHREADS For multi-threaded applications on Unix.
**
** SQLITE_MUTEX_W32 For multi-threaded applications on Win32.
**
** SQLITE_MUTEX_OS2 For multi-threaded applications on OS/2.
*/
#if !SQLITE_THREADSAFE
# define SQLITE_MUTEX_OMIT
@ -47,8 +45,6 @@
# define SQLITE_MUTEX_PTHREADS
# elif SQLITE_OS_WIN
# define SQLITE_MUTEX_W32
# elif SQLITE_OS_OS2
# define SQLITE_MUTEX_OS2
# else
# define SQLITE_MUTEX_NOOP
# endif

View File

@ -1,274 +0,0 @@
/*
** 2007 August 28
**
** 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 the C functions that implement mutexes for OS/2
*/
#include "sqliteInt.h"
/*
** The code in this file is only used if SQLITE_MUTEX_OS2 is defined.
** See the mutex.h file for details.
*/
#ifdef SQLITE_MUTEX_OS2
/********************** OS/2 Mutex Implementation **********************
**
** This implementation of mutexes is built using the OS/2 API.
*/
/*
** The mutex object
** Each recursive mutex is an instance of the following structure.
*/
struct sqlite3_mutex {
HMTX mutex; /* Mutex controlling the lock */
int id; /* Mutex type */
#ifdef SQLITE_DEBUG
int trace; /* True to trace changes */
#endif
};
#ifdef SQLITE_DEBUG
#define SQLITE3_MUTEX_INITIALIZER { 0, 0, 0 }
#else
#define SQLITE3_MUTEX_INITIALIZER { 0, 0 }
#endif
/*
** Initialize and deinitialize the mutex subsystem.
*/
static int os2MutexInit(void){ return SQLITE_OK; }
static int os2MutexEnd(void){ return SQLITE_OK; }
/*
** The sqlite3_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it. If it returns NULL
** that means that a mutex could not be allocated.
** SQLite will unwind its stack and return an error. The argument
** to sqlite3_mutex_alloc() is one of these integer constants:
**
** <ul>
** <li> SQLITE_MUTEX_FAST
** <li> SQLITE_MUTEX_RECURSIVE
** <li> SQLITE_MUTEX_STATIC_MASTER
** <li> SQLITE_MUTEX_STATIC_MEM
** <li> SQLITE_MUTEX_STATIC_MEM2
** <li> SQLITE_MUTEX_STATIC_PRNG
** <li> SQLITE_MUTEX_STATIC_LRU
** <li> SQLITE_MUTEX_STATIC_LRU2
** </ul>
**
** The first two constants cause sqlite3_mutex_alloc() to create
** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
** The mutex implementation does not need to make a distinction
** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
** not want to. But SQLite will only request a recursive mutex in
** cases where it really needs one. If a faster non-recursive mutex
** implementation is available on the host platform, the mutex subsystem
** might return such a mutex in response to SQLITE_MUTEX_FAST.
**
** The other allowed parameters to sqlite3_mutex_alloc() each return
** a pointer to a static preexisting mutex. Six static mutexes are
** used by the current version of SQLite. Future versions of SQLite
** may add additional static mutexes. Static mutexes are for internal
** use by SQLite only. Applications that use SQLite mutexes should
** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
** SQLITE_MUTEX_RECURSIVE.
**
** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
** returns a different mutex on every call. But for the static
** mutex types, the same mutex is returned on every call that has
** the same type number.
*/
static sqlite3_mutex *os2MutexAlloc(int iType){
sqlite3_mutex *p = NULL;
switch( iType ){
case SQLITE_MUTEX_FAST:
case SQLITE_MUTEX_RECURSIVE: {
p = sqlite3MallocZero( sizeof(*p) );
if( p ){
p->id = iType;
if( DosCreateMutexSem( 0, &p->mutex, 0, FALSE ) != NO_ERROR ){
sqlite3_free( p );
p = NULL;
}
}
break;
}
default: {
static volatile int isInit = 0;
static sqlite3_mutex staticMutexes[6] = {
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
};
if ( !isInit ){
APIRET rc;
PTIB ptib;
PPIB ppib;
HMTX mutex;
char name[32];
DosGetInfoBlocks( &ptib, &ppib );
sqlite3_snprintf( sizeof(name), name, "\\SEM32\\SQLITE%04x",
ppib->pib_ulpid );
while( !isInit ){
mutex = 0;
rc = DosCreateMutexSem( name, &mutex, 0, FALSE);
if( rc == NO_ERROR ){
unsigned int i;
if( !isInit ){
for( i = 0; i < sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++ ){
DosCreateMutexSem( 0, &staticMutexes[i].mutex, 0, FALSE );
}
isInit = 1;
}
DosCloseMutexSem( mutex );
}else if( rc == ERROR_DUPLICATE_NAME ){
DosSleep( 1 );
}else{
return p;
}
}
}
assert( iType-2 >= 0 );
assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) );
p = &staticMutexes[iType-2];
p->id = iType;
break;
}
}
return p;
}
/*
** This routine deallocates a previously allocated mutex.
** SQLite is careful to deallocate every mutex that it allocates.
*/
static void os2MutexFree(sqlite3_mutex *p){
#ifdef SQLITE_DEBUG
TID tid;
PID pid;
ULONG ulCount;
DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
assert( ulCount==0 );
assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
#endif
DosCloseMutexSem( p->mutex );
sqlite3_free( p );
}
#ifdef SQLITE_DEBUG
/*
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
** intended for use inside assert() statements.
*/
static int os2MutexHeld(sqlite3_mutex *p){
TID tid;
PID pid;
ULONG ulCount;
PTIB ptib;
DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
if( ulCount==0 || ( ulCount>1 && p->id!=SQLITE_MUTEX_RECURSIVE ) )
return 0;
DosGetInfoBlocks(&ptib, NULL);
return tid==ptib->tib_ptib2->tib2_ultid;
}
static int os2MutexNotheld(sqlite3_mutex *p){
TID tid;
PID pid;
ULONG ulCount;
PTIB ptib;
DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
if( ulCount==0 )
return 1;
DosGetInfoBlocks(&ptib, NULL);
return tid!=ptib->tib_ptib2->tib2_ultid;
}
static void os2MutexTrace(sqlite3_mutex *p, char *pAction){
TID tid;
PID pid;
ULONG ulCount;
DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
printf("%s mutex %p (%d) with nRef=%ld\n", pAction, (void*)p, p->trace, ulCount);
}
#endif
/*
** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
** to enter a mutex. If another thread is already within the mutex,
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
** be entered multiple times by the same thread. In such cases the,
** mutex must be exited an equal number of times before another thread
** can enter. If the same thread tries to enter any other kind of mutex
** more than once, the behavior is undefined.
*/
static void os2MutexEnter(sqlite3_mutex *p){
assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) );
DosRequestMutexSem(p->mutex, SEM_INDEFINITE_WAIT);
#ifdef SQLITE_DEBUG
if( p->trace ) os2MutexTrace(p, "enter");
#endif
}
static int os2MutexTry(sqlite3_mutex *p){
int rc = SQLITE_BUSY;
assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) );
if( DosRequestMutexSem(p->mutex, SEM_IMMEDIATE_RETURN) == NO_ERROR ) {
rc = SQLITE_OK;
#ifdef SQLITE_DEBUG
if( p->trace ) os2MutexTrace(p, "try");
#endif
}
return rc;
}
/*
** The sqlite3_mutex_leave() routine exits a mutex that was
** previously entered by the same thread. The behavior
** is undefined if the mutex is not currently entered or
** is not currently allocated. SQLite will never do either.
*/
static void os2MutexLeave(sqlite3_mutex *p){
assert( os2MutexHeld(p) );
DosReleaseMutexSem(p->mutex);
#ifdef SQLITE_DEBUG
if( p->trace ) os2MutexTrace(p, "leave");
#endif
}
sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
static const sqlite3_mutex_methods sMutex = {
os2MutexInit,
os2MutexEnd,
os2MutexAlloc,
os2MutexFree,
os2MutexEnter,
os2MutexTry,
os2MutexLeave,
#ifdef SQLITE_DEBUG
os2MutexHeld,
os2MutexNotheld
#else
0,
0
#endif
};
return &sMutex;
}
#endif /* SQLITE_MUTEX_OS2 */

View File

@ -109,7 +109,7 @@ static int winMutex_isInit = 0;
*/
static long winMutex_lock = 0;
extern void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
static int winMutexInit(void){
/* The first to increment to 1 does actual initialization */

View File

@ -23,7 +23,7 @@
/*
** Figure out if we are dealing with Unix, Windows, or some other
** operating system. After the following block of preprocess macros,
** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, SQLITE_OS_OS2, and SQLITE_OS_OTHER
** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, and SQLITE_OS_OTHER
** will defined to either 1 or 0. One of the four will be 1. The other
** three will be 0.
*/
@ -33,8 +33,6 @@
# define SQLITE_OS_UNIX 0
# undef SQLITE_OS_WIN
# define SQLITE_OS_WIN 0
# undef SQLITE_OS_OS2
# define SQLITE_OS_OS2 0
# else
# undef SQLITE_OS_OTHER
# endif
@ -45,19 +43,12 @@
# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
# define SQLITE_OS_WIN 1
# define SQLITE_OS_UNIX 0
# define SQLITE_OS_OS2 0
# elif defined(__EMX__) || defined(_OS2) || defined(OS2) || defined(_OS2_) || defined(__OS2__)
# define SQLITE_OS_WIN 0
# define SQLITE_OS_UNIX 0
# define SQLITE_OS_OS2 1
# else
# define SQLITE_OS_WIN 0
# define SQLITE_OS_UNIX 1
# define SQLITE_OS_OS2 0
# endif
# else
# define SQLITE_OS_UNIX 0
# define SQLITE_OS_OS2 0
# endif
#else
# ifndef SQLITE_OS_WIN
@ -69,21 +60,6 @@
# include <windows.h>
#endif
#if SQLITE_OS_OS2
# if (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 3) && defined(OS2_HIGH_MEMORY)
# include <os2safe.h> /* has to be included before os2.h for linking to work */
# endif
# define INCL_DOSDATETIME
# define INCL_DOSFILEMGR
# define INCL_DOSERRORS
# define INCL_DOSMISC
# define INCL_DOSPROCESS
# define INCL_DOSMODULEMGR
# define INCL_DOSSEMAPHORES
# include <os2.h>
# include <uconv.h>
#endif
/*
** Determine if we are dealing with Windows NT.
**
@ -116,8 +92,8 @@
#endif
/*
** Determine if we are dealing with WindowsRT (Metro) as this has a different and
** incompatible API from win32.
** Determine if we are dealing with WinRT, which provides only a subset of
** the full Win32 API.
*/
#if !defined(SQLITE_OS_WINRT)
# define SQLITE_OS_WINRT 0

File diff suppressed because it is too large Load Diff

View File

@ -288,7 +288,8 @@ static struct win_syscall {
#define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \
LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
!defined(SQLITE_OMIT_WAL))
{ "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 },
#else
{ "CreateFileMappingW", (SYSCALL)0, 0 },
@ -600,7 +601,7 @@ static struct win_syscall {
LPOVERLAPPED))aSyscall[45].pCurrent)
#endif
#if !SQLITE_OS_WINRT
#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL))
{ "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 },
#else
{ "MapViewOfFile", (SYSCALL)0, 0 },
@ -670,7 +671,11 @@ static struct win_syscall {
#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
LPOVERLAPPED))aSyscall[55].pCurrent)
#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL)
{ "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 },
#else
{ "UnmapViewOfFile", (SYSCALL)0, 0 },
#endif
#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[56].pCurrent)
@ -702,7 +707,7 @@ static struct win_syscall {
#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
DWORD))aSyscall[60].pCurrent)
#if !SQLITE_OS_WINCE
#if SQLITE_OS_WINRT
{ "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 },
#else
{ "WaitForSingleObjectEx", (SYSCALL)0, 0 },
@ -711,7 +716,7 @@ static struct win_syscall {
#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
BOOL))aSyscall[61].pCurrent)
#if !SQLITE_OS_WINCE
#if SQLITE_OS_WINRT
{ "SetFilePointerEx", (SYSCALL)SetFilePointerEx, 0 },
#else
{ "SetFilePointerEx", (SYSCALL)0, 0 },
@ -729,7 +734,7 @@ static struct win_syscall {
#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[63].pCurrent)
#if SQLITE_OS_WINRT
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
{ "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 },
#else
{ "MapViewOfFileFromApp", (SYSCALL)0, 0 },
@ -793,7 +798,7 @@ static struct win_syscall {
#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[71].pCurrent)
#if SQLITE_OS_WINRT
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
{ "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
#else
{ "CreateFileMappingFromApp", (SYSCALL)0, 0 },

View File

@ -396,11 +396,10 @@ static int pcache1ResizeHash(PCache1 *p){
pcache1LeaveMutex(p->pGroup);
if( p->nHash ){ sqlite3BeginBenignMalloc(); }
apNew = (PgHdr1 **)sqlite3_malloc(sizeof(PgHdr1 *)*nNew);
apNew = (PgHdr1 **)sqlite3MallocZero(sizeof(PgHdr1 *)*nNew);
if( p->nHash ){ sqlite3EndBenignMalloc(); }
pcache1EnterMutex(p->pGroup);
if( apNew ){
memset(apNew, 0, sizeof(PgHdr1 *)*nNew);
for(i=0; i<p->nHash; i++){
PgHdr1 *pPage;
PgHdr1 *pNext = p->apHash[i];
@ -584,9 +583,8 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
assert( szExtra < 300 );
sz = sizeof(PCache1) + sizeof(PGroup)*separateCache;
pCache = (PCache1 *)sqlite3_malloc(sz);
pCache = (PCache1 *)sqlite3MallocZero(sz);
if( pCache ){
memset(pCache, 0, sz);
if( separateCache ){
pGroup = (PGroup*)&pCache[1];
pGroup->mxPinned = 10;

View File

@ -1160,6 +1160,19 @@ void sqlite3Pragma(
int isQuick = (sqlite3Tolower(zLeft[0])=='q');
/* If the PRAGMA command was of the form "PRAGMA <db>.integrity_check",
** then iDb is set to the index of the database identified by <db>.
** In this case, the integrity of database iDb only is verified by
** the VDBE created below.
**
** Otherwise, if the command was simply "PRAGMA integrity_check" (or
** "PRAGMA quick_check"), then iDb is set to 0. In this case, set iDb
** to -1 here, to indicate that the VDBE should verify the integrity
** of all attached databases. */
assert( iDb>=0 );
assert( iDb==0 || pId2->z );
if( pId2->z==0 ) iDb = -1;
/* Initialize the VDBE program */
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
pParse->nMem = 6;
@ -1183,6 +1196,7 @@ void sqlite3Pragma(
int cnt = 0;
if( OMIT_TEMPDB && i==1 ) continue;
if( iDb>=0 && i!=iDb ) continue;
sqlite3CodeVerifySchema(pParse, i);
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */
@ -1194,7 +1208,7 @@ void sqlite3Pragma(
** Begin by filling registers 2, 3, ... with the root pages numbers
** for all tables and indices in the database.
*/
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
assert( sqlite3SchemaMutexHeld(db, i, 0) );
pTbls = &db->aDb[i].pSchema->tblHash;
for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
Table *pTab = sqliteHashData(x);

View File

@ -124,7 +124,8 @@ static const et_info fmtinfo[] = {
static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
int digit;
LONGDOUBLE_TYPE d;
if( (*cnt)++ >= 16 ) return '0';
if( (*cnt)<=0 ) return '0';
(*cnt)--;
digit = (int)*val;
d = digit;
digit += '0';
@ -428,9 +429,12 @@ void sqlite3VXPrintf(
break;
}
if( realvalue>0.0 ){
while( realvalue>=1e32 && exp<=350 ){ realvalue *= 1e-32; exp+=32; }
while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; }
while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; }
LONGDOUBLE_TYPE scale = 1.0;
while( realvalue>=1e100*scale && exp<=350 ){ scale *= 1e100;exp+=100;}
while( realvalue>=1e64*scale && exp<=350 ){ scale *= 1e64; exp+=64; }
while( realvalue>=1e8*scale && exp<=350 ){ scale *= 1e8; exp+=8; }
while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; }
realvalue /= scale;
while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; }
while( realvalue<1.0 ){ realvalue *= 10.0; exp--; }
if( exp>350 ){
@ -463,7 +467,7 @@ void sqlite3VXPrintf(
xtype = etFLOAT;
}
}else{
flag_rtz = 0;
flag_rtz = flag_altform2;
}
if( xtype==etEXP ){
e2 = 0;
@ -478,7 +482,7 @@ void sqlite3VXPrintf(
}
}
zOut = bufpt;
nsd = 0;
nsd = 16 + flag_altform2*10;
flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
/* The sign in front of the number */
if( prefix ){

View File

@ -36,10 +36,10 @@ static void clearSelect(sqlite3 *db, Select *p){
*/
void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){
pDest->eDest = (u8)eDest;
pDest->iParm = iParm;
pDest->affinity = 0;
pDest->iMem = 0;
pDest->nMem = 0;
pDest->iSDParm = iParm;
pDest->affSdst = 0;
pDest->iSdst = 0;
pDest->nSdst = 0;
}
@ -551,7 +551,7 @@ static void selectInnerLoop(
int hasDistinct; /* True if the DISTINCT keyword is present */
int regResult; /* Start of memory holding result set */
int eDest = pDest->eDest; /* How to dispose of results */
int iParm = pDest->iParm; /* First argument to disposal method */
int iParm = pDest->iSDParm; /* First argument to disposal method */
int nResultCol; /* Number of result columns */
assert( v );
@ -569,14 +569,14 @@ static void selectInnerLoop(
}else{
nResultCol = pEList->nExpr;
}
if( pDest->iMem==0 ){
pDest->iMem = pParse->nMem+1;
pDest->nMem = nResultCol;
if( pDest->iSdst==0 ){
pDest->iSdst = pParse->nMem+1;
pDest->nSdst = nResultCol;
pParse->nMem += nResultCol;
}else{
assert( pDest->nMem==nResultCol );
assert( pDest->nSdst==nResultCol );
}
regResult = pDest->iMem;
regResult = pDest->iSdst;
if( nColumn>0 ){
for(i=0; i<nColumn; i++){
sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i);
@ -655,7 +655,7 @@ static void selectInnerLoop(
*/
case SRT_Set: {
assert( nColumn==1 );
p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affinity);
p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst);
if( pOrderBy ){
/* At first glance you would think we could optimize out the
** ORDER BY in this case since the order of entries in the set
@ -710,7 +710,7 @@ static void selectInnerLoop(
pushOntoSorter(pParse, pOrderBy, p, r1);
sqlite3ReleaseTempReg(pParse, r1);
}else if( eDest==SRT_Coroutine ){
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm);
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
}else{
sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nColumn);
sqlite3ExprCacheAffinityChange(pParse, regResult, nColumn);
@ -890,7 +890,7 @@ static void generateSortTail(
ExprList *pOrderBy = p->pOrderBy;
int eDest = pDest->eDest;
int iParm = pDest->iParm;
int iParm = pDest->iSDParm;
int regRow;
int regRowid;
@ -949,17 +949,17 @@ static void generateSortTail(
testcase( eDest==SRT_Output );
testcase( eDest==SRT_Coroutine );
for(i=0; i<nColumn; i++){
assert( regRow!=pDest->iMem+i );
sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iMem+i);
assert( regRow!=pDest->iSdst+i );
sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iSdst+i);
if( i==0 ){
sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
}
}
if( eDest==SRT_Output ){
sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iMem, nColumn);
sqlite3ExprCacheAffinityChange(pParse, pDest->iMem, nColumn);
sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn);
sqlite3ExprCacheAffinityChange(pParse, pDest->iSdst, nColumn);
}else{
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm);
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
}
break;
}
@ -1610,7 +1610,7 @@ static int multiSelect(
*/
if( dest.eDest==SRT_EphemTab ){
assert( p->pEList );
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iParm, p->pEList->nExpr);
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr);
sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
dest.eDest = SRT_Table;
}
@ -1696,7 +1696,7 @@ static int multiSelect(
** of a 3-way or more compound */
assert( p->pLimit==0 ); /* Not allowed on leftward elements */
assert( p->pOffset==0 ); /* Not allowed on leftward elements */
unionTab = dest.iParm;
unionTab = dest.iSDParm;
}else{
/* We will need to create our own temporary table to hold the
** intermediate results.
@ -1753,7 +1753,7 @@ static int multiSelect(
/* Convert the data in the temporary table into whatever form
** it is that we currently need.
*/
assert( unionTab==dest.iParm || dest.eDest!=priorOp );
assert( unionTab==dest.iSDParm || dest.eDest!=priorOp );
if( dest.eDest!=priorOp ){
int iCont, iBreak, iStart;
assert( p->pEList );
@ -1817,7 +1817,7 @@ static int multiSelect(
p->pLimit = 0;
pOffset = p->pOffset;
p->pOffset = 0;
intersectdest.iParm = tab2;
intersectdest.iSDParm = tab2;
explainSetInteger(iSub2, pParse->iNextSelectId);
rc = sqlite3Select(pParse, p, &intersectdest);
testcase( rc!=SQLITE_OK );
@ -1911,8 +1911,8 @@ static int multiSelect(
}
multi_select_end:
pDest->iMem = dest.iMem;
pDest->nMem = dest.nMem;
pDest->iSdst = dest.iSdst;
pDest->nSdst = dest.nSdst;
sqlite3SelectDelete(db, pDelete);
return rc;
}
@ -1922,8 +1922,8 @@ multi_select_end:
** Code an output subroutine for a coroutine implementation of a
** SELECT statment.
**
** The data to be output is contained in pIn->iMem. There are
** pIn->nMem columns to be output. pDest is where the output should
** The data to be output is contained in pIn->iSdst. There are
** pIn->nSdst columns to be output. pDest is where the output should
** be sent.
**
** regReturn is the number of the register holding the subroutine
@ -1961,11 +1961,11 @@ static int generateOutputSubroutine(
if( regPrev ){
int j1, j2;
j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev);
j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iMem, regPrev+1, pIn->nMem,
j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst,
(char*)pKeyInfo, p4type);
sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2);
sqlite3VdbeJumpHere(v, j1);
sqlite3ExprCodeCopy(pParse, pIn->iMem, regPrev+1, pIn->nMem);
sqlite3ExprCodeCopy(pParse, pIn->iSdst, regPrev+1, pIn->nSdst);
sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev);
}
if( pParse->db->mallocFailed ) return 0;
@ -1983,9 +1983,9 @@ static int generateOutputSubroutine(
int r2 = sqlite3GetTempReg(pParse);
testcase( pDest->eDest==SRT_Table );
testcase( pDest->eDest==SRT_EphemTab );
sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iMem, pIn->nMem, r1);
sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iParm, r2);
sqlite3VdbeAddOp3(v, OP_Insert, pDest->iParm, r1, r2);
sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1);
sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iSDParm, r2);
sqlite3VdbeAddOp3(v, OP_Insert, pDest->iSDParm, r1, r2);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
sqlite3ReleaseTempReg(pParse, r2);
sqlite3ReleaseTempReg(pParse, r1);
@ -1999,13 +1999,13 @@ static int generateOutputSubroutine(
*/
case SRT_Set: {
int r1;
assert( pIn->nMem==1 );
assert( pIn->nSdst==1 );
p->affinity =
sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affinity);
sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affSdst);
r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iMem, 1, r1, &p->affinity, 1);
sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, 1);
sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iParm, r1);
sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, 1, r1, &p->affinity, 1);
sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, 1);
sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1);
sqlite3ReleaseTempReg(pParse, r1);
break;
}
@ -2014,7 +2014,7 @@ static int generateOutputSubroutine(
/* If any row exist in the result set, record that fact and abort.
*/
case SRT_Exists: {
sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iParm);
sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iSDParm);
/* The LIMIT clause will terminate the loop for us */
break;
}
@ -2025,23 +2025,23 @@ static int generateOutputSubroutine(
** of the scan loop.
*/
case SRT_Mem: {
assert( pIn->nMem==1 );
sqlite3ExprCodeMove(pParse, pIn->iMem, pDest->iParm, 1);
assert( pIn->nSdst==1 );
sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, 1);
/* The LIMIT clause will jump out of the loop for us */
break;
}
#endif /* #ifndef SQLITE_OMIT_SUBQUERY */
/* The results are stored in a sequence of registers
** starting at pDest->iMem. Then the co-routine yields.
** starting at pDest->iSdst. Then the co-routine yields.
*/
case SRT_Coroutine: {
if( pDest->iMem==0 ){
pDest->iMem = sqlite3GetTempRange(pParse, pIn->nMem);
pDest->nMem = pIn->nMem;
if( pDest->iSdst==0 ){
pDest->iSdst = sqlite3GetTempRange(pParse, pIn->nSdst);
pDest->nSdst = pIn->nSdst;
}
sqlite3ExprCodeMove(pParse, pIn->iMem, pDest->iMem, pDest->nMem);
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm);
sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pDest->nSdst);
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
break;
}
@ -2055,8 +2055,8 @@ static int generateOutputSubroutine(
*/
default: {
assert( pDest->eDest==SRT_Output );
sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iMem, pIn->nMem);
sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, pIn->nMem);
sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iSdst, pIn->nSdst);
sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst);
break;
}
}
@ -2475,7 +2475,7 @@ static int multiSelectOrderBy(
*/
sqlite3VdbeResolveLabel(v, labelCmpr);
sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
sqlite3VdbeAddOp4(v, OP_Compare, destA.iMem, destB.iMem, nOrderBy,
sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
(char*)pKeyMerge, P4_KEYINFO_HANDOFF);
sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
@ -3721,23 +3721,24 @@ static void explainSimpleCount(
**
** SRT_Mem Only valid if the result is a single column.
** Store the first column of the first result row
** in register pDest->iParm then abandon the rest
** in register pDest->iSDParm then abandon the rest
** of the query. This destination implies "LIMIT 1".
**
** SRT_Set The result must be a single column. Store each
** row of result as the key in table pDest->iParm.
** Apply the affinity pDest->affinity before storing
** row of result as the key in table pDest->iSDParm.
** Apply the affinity pDest->affSdst before storing
** results. Used to implement "IN (SELECT ...)".
**
** SRT_Union Store results as a key in a temporary table pDest->iParm.
** SRT_Union Store results as a key in a temporary table
** identified by pDest->iSDParm.
**
** SRT_Except Remove results from the temporary table pDest->iParm.
** SRT_Except Remove results from the temporary table pDest->iSDParm.
**
** SRT_Table Store results in temporary table pDest->iParm.
** SRT_Table Store results in temporary table pDest->iSDParm.
** This is like SRT_EphemTab except that the table
** is assumed to already be open.
**
** SRT_EphemTab Create an temporary table pDest->iParm and store
** SRT_EphemTab Create an temporary table pDest->iSDParm and store
** the result there. The cursor is left open after
** returning. This is like SRT_Table except that
** this destination uses OP_OpenEphemeral to create
@ -3745,9 +3746,9 @@ static void explainSimpleCount(
**
** SRT_Coroutine Generate a co-routine that returns a new row of
** results each time it is invoked. The entry point
** of the co-routine is stored in register pDest->iParm.
** of the co-routine is stored in register pDest->iSDParm.
**
** SRT_Exists Store a 1 in memory cell pDest->iParm if the result
** SRT_Exists Store a 1 in memory cell pDest->iSDParm if the result
** set is not empty.
**
** SRT_Discard Throw the results away. This is used by SELECT
@ -3991,7 +3992,7 @@ int sqlite3Select(
/* If the output is destined for a temporary table, open that table.
*/
if( pDest->eDest==SRT_EphemTab ){
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iParm, pEList->nExpr);
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr);
}
/* Set the limiter.

View File

@ -36,7 +36,7 @@
#include <ctype.h>
#include <stdarg.h>
#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__)
#if !defined(_WIN32) && !defined(WIN32)
# include <signal.h>
# if !defined(__RTP__) && !defined(_WRS_KERNEL)
# include <pwd.h>
@ -45,10 +45,6 @@
# include <sys/types.h>
#endif
#ifdef __OS2__
# include <unistd.h>
#endif
#ifdef HAVE_EDITLINE
# include <editline/editline.h>
#endif
@ -92,7 +88,7 @@ static int enableTimer = 0;
#define IsDigit(X) isdigit((unsigned char)X)
#define ToLower(X) (char)tolower((unsigned char)X)
#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)
#if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL)
#include <sys/time.h>
#include <sys/resource.h>
@ -1453,6 +1449,7 @@ static int process_input(struct callback_data *p, FILE *in);
*/
static void open_db(struct callback_data *p){
if( p->db==0 ){
sqlite3_initialize();
sqlite3_open(p->zDbFilename, &p->db);
db = p->db;
if( db && sqlite3_errcode(db)==SQLITE_OK ){
@ -2468,7 +2465,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
open_db(p);
output_file_close(p->traceOut);
p->traceOut = output_file_open(azArg[1]);
#ifndef SQLITE_OMIT_TRACE
#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
if( p->traceOut==0 ){
sqlite3_trace(p->db, 0, 0);
}else{
@ -2696,11 +2693,13 @@ static char *find_home_dir(void){
static char *home_dir = NULL;
if( home_dir ) return home_dir;
#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
struct passwd *pwent;
uid_t uid = getuid();
if( (pwent=getpwuid(uid)) != NULL) {
home_dir = pwent->pw_dir;
#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
{
struct passwd *pwent;
uid_t uid = getuid();
if( (pwent=getpwuid(uid)) != NULL) {
home_dir = pwent->pw_dir;
}
}
#endif
@ -2710,7 +2709,7 @@ static char *find_home_dir(void){
home_dir = "/";
#else
#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
#if defined(_WIN32) || defined(WIN32)
if (!home_dir) {
home_dir = getenv("USERPROFILE");
}
@ -2720,7 +2719,7 @@ static char *find_home_dir(void){
home_dir = getenv("HOME");
}
#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
#if defined(_WIN32) || defined(WIN32)
if (!home_dir) {
char *zDrive, *zPath;
int n;
@ -2773,6 +2772,7 @@ static int process_sqliterc(
#endif
return 1;
}
sqlite3_initialize();
zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
sqliterc = zBuf;
}
@ -2936,11 +2936,7 @@ int main(int argc, char **argv){
}
}
if( i<argc ){
#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
#else
data.zDbFilename = argv[i++];
#endif
}else{
#ifndef SQLITE_OMIT_MEMORYDB
data.zDbFilename = ":memory:";

View File

@ -214,7 +214,8 @@ int sqlite3_threadsafe(void);
** the opaque structure named "sqlite3". It is useful to think of an sqlite3
** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and
** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()]
** is its destructor. There are many other interfaces (such as
** and [sqlite3_close_v2()] are its destructors. There are many other
** interfaces (such as
** [sqlite3_prepare_v2()], [sqlite3_create_function()], and
** [sqlite3_busy_timeout()] to name but three) that are methods on an
** sqlite3 object.
@ -261,28 +262,46 @@ typedef sqlite_uint64 sqlite3_uint64;
/*
** CAPI3REF: Closing A Database Connection
**
** ^The sqlite3_close() routine is the destructor for the [sqlite3] object.
** ^Calls to sqlite3_close() return SQLITE_OK if the [sqlite3] object is
** successfully destroyed and all associated resources are deallocated.
** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors
** for the [sqlite3] object.
** ^Calls to sqlite3_close() and sqlite3_close_v2() return SQLITE_OK if
** the [sqlite3] object is successfully destroyed and all associated
** resources are deallocated.
**
** Applications must [sqlite3_finalize | finalize] all [prepared statements]
** and [sqlite3_blob_close | close] all [BLOB handles] associated with
** the [sqlite3] object prior to attempting to close the object. ^If
** ^If the database connection is associated with unfinalized prepared
** statements or unfinished sqlite3_backup objects then sqlite3_close()
** will leave the database connection open and return [SQLITE_BUSY].
** ^If sqlite3_close_v2() is called with unfinalized prepared statements
** and unfinished sqlite3_backups, then the database connection becomes
** an unusable "zombie" which will automatically be deallocated when the
** last prepared statement is finalized or the last sqlite3_backup is
** finished. The sqlite3_close_v2() interface is intended for use with
** host languages that are garbage collected, and where the order in which
** destructors are called is arbitrary.
**
** Applications should [sqlite3_finalize | finalize] all [prepared statements],
** [sqlite3_blob_close | close] all [BLOB handles], and
** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
** with the [sqlite3] object prior to attempting to close the object. ^If
** sqlite3_close() is called on a [database connection] that still has
** outstanding [prepared statements] or [BLOB handles], then it returns
** SQLITE_BUSY.
** outstanding [prepared statements], [BLOB handles], and/or
** [sqlite3_backup] objects then it returns SQLITE_OK but the deallocation
** of resources is deferred until all [prepared statements], [BLOB handles],
** and [sqlite3_backup] objects are also destroyed.
**
** ^If [sqlite3_close()] is invoked while a transaction is open,
** ^If an [sqlite3] object is destroyed while a transaction is open,
** the transaction is automatically rolled back.
**
** The C parameter to [sqlite3_close(C)] must be either a NULL
** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)]
** must be either a NULL
** pointer or an [sqlite3] object pointer obtained
** from [sqlite3_open()], [sqlite3_open16()], or
** [sqlite3_open_v2()], and not previously closed.
** ^Calling sqlite3_close() with a NULL pointer argument is a
** harmless no-op.
** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer
** argument is a harmless no-op.
*/
int sqlite3_close(sqlite3 *);
int sqlite3_close(sqlite3*);
int sqlite3_close_v2(sqlite3*);
/*
** The type for a callback function.
@ -4133,11 +4152,11 @@ typedef void (*sqlite3_destructor_type)(void*);
** the error code is SQLITE_ERROR. ^A subsequent call to sqlite3_result_error()
** or sqlite3_result_error16() resets the error code to SQLITE_ERROR.
**
** ^The sqlite3_result_toobig() interface causes SQLite to throw an error
** indicating that a string or BLOB is too long to represent.
** ^The sqlite3_result_error_toobig() interface causes SQLite to throw an
** error indicating that a string or BLOB is too long to represent.
**
** ^The sqlite3_result_nomem() interface causes SQLite to throw an error
** indicating that a memory allocation failed.
** ^The sqlite3_result_error_nomem() interface causes SQLite to throw an
** error indicating that a memory allocation failed.
**
** ^The sqlite3_result_int() interface sets the return value
** of the application-defined function to be the 32-bit signed integer
@ -5489,7 +5508,6 @@ int sqlite3_vfs_unregister(sqlite3_vfs*);
** implementations are available in the SQLite core:
**
** <ul>
** <li> SQLITE_MUTEX_OS2
** <li> SQLITE_MUTEX_PTHREADS
** <li> SQLITE_MUTEX_W32
** <li> SQLITE_MUTEX_NOOP
@ -5497,9 +5515,9 @@ int sqlite3_vfs_unregister(sqlite3_vfs*);
**
** ^The SQLITE_MUTEX_NOOP implementation is a set of routines
** that does no real locking and is appropriate for use in
** a single-threaded application. ^The SQLITE_MUTEX_OS2,
** SQLITE_MUTEX_PTHREADS, and SQLITE_MUTEX_W32 implementations
** are appropriate for use on OS/2, Unix, and Windows.
** a single-threaded application. ^The SQLITE_MUTEX_PTHREADS and
** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix
** and Windows.
**
** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex

View File

@ -149,6 +149,7 @@
**
** SQLITE_SYSTEM_MALLOC // Use normal system malloc()
** SQLITE_WIN32_MALLOC // Use Win32 native heap API
** SQLITE_ZERO_MALLOC // Use a stub allocator that always fails
** SQLITE_MEMDEBUG // Debugging version of system malloc()
**
** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the
@ -162,11 +163,19 @@
** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as
** the default.
*/
#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)>1
# error "At most one of the following compile-time configuration options\
is allows: SQLITE_SYSTEM_MALLOC, SQLITE_WIN32_MALLOC, SQLITE_MEMDEBUG"
#if defined(SQLITE_SYSTEM_MALLOC) \
+ defined(SQLITE_WIN32_MALLOC) \
+ defined(SQLITE_ZERO_MALLOC) \
+ defined(SQLITE_MEMDEBUG)>1
# error "Two or more of the following compile-time configuration options\
are defined but at most one is allowed:\
SQLITE_SYSTEM_MALLOC, SQLITE_WIN32_MALLOC, SQLITE_MEMDEBUG,\
SQLITE_ZERO_MALLOC"
#endif
#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)==0
#if defined(SQLITE_SYSTEM_MALLOC) \
+ defined(SQLITE_WIN32_MALLOC) \
+ defined(SQLITE_ZERO_MALLOC) \
+ defined(SQLITE_MEMDEBUG)==0
# define SQLITE_SYSTEM_MALLOC 1
#endif
@ -982,6 +991,7 @@ struct sqlite3 {
#define SQLITE_MAGIC_SICK 0x4b771290 /* Error and awaiting close */
#define SQLITE_MAGIC_BUSY 0xf03b7906 /* Database currently in use */
#define SQLITE_MAGIC_ERROR 0xb5357930 /* An SQLITE_MISUSE error occurred */
#define SQLITE_MAGIC_ZOMBIE 0x64cffc7f /* Close with last statement close */
/*
** Each SQL function is defined by an instance of the following
@ -2116,10 +2126,10 @@ struct Select {
typedef struct SelectDest SelectDest;
struct SelectDest {
u8 eDest; /* How to dispose of the results */
u8 affinity; /* Affinity used when eDest==SRT_Set */
int iParm; /* A parameter used by the eDest disposal method */
int iMem; /* Base register where results are written */
int nMem; /* Number of registers allocated */
u8 affSdst; /* Affinity used when eDest==SRT_Set */
int iSDParm; /* A parameter used by the eDest disposal method */
int iSdst; /* Base register where results are written */
int nSdst; /* Number of registers allocated */
};
/*
@ -2319,6 +2329,8 @@ struct AuthContext {
#define OPFLAG_ISNOOP 0x40 /* OP_Delete does pre-update-hook only */
#define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */
#define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */
#define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
#define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */
/*
* Each trigger present in the database schema is stored as an instance of
@ -2847,6 +2859,7 @@ void sqlite3CommitTransaction(Parse*);
void sqlite3RollbackTransaction(Parse*);
void sqlite3Savepoint(Parse*, int, Token*);
void sqlite3CloseSavepoints(sqlite3 *);
void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
int sqlite3ExprIsConstant(Expr*);
int sqlite3ExprIsConstantNotJoin(Expr*);
int sqlite3ExprIsConstantOrFunction(Expr*);

View File

@ -1370,6 +1370,29 @@ static int declare_vtab(
return TCL_OK;
}
#include "test_spellfix.c"
/*
** Register the spellfix virtual table module.
*/
static int register_spellfix_module(
ClientData clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
sqlite3 *db;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB");
return TCL_ERROR;
}
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
sqlite3Spellfix1Register(db);
return TCL_OK;
}
#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
/*
@ -1382,8 +1405,9 @@ int Sqlitetest8_Init(Tcl_Interp *interp){
Tcl_ObjCmdProc *xProc;
void *clientData;
} aObjCmd[] = {
{ "register_echo_module", register_echo_module, 0 },
{ "sqlite3_declare_vtab", declare_vtab, 0 },
{ "register_echo_module", register_echo_module, 0 },
{ "register_spellfix_module", register_spellfix_module, 0 },
{ "sqlite3_declare_vtab", declare_vtab, 0 },
};
int i;
for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){

View File

@ -628,6 +628,21 @@ Tcl_SetVar2(interp, "sqlite_options", "long_double",
Tcl_LinkVar(interp, "TEMP_STORE", (char *)&(cv_TEMP_STORE),
TCL_LINK_INT | TCL_LINK_READ_ONLY);
}
#ifdef _MSC_VER
{
static const int cv__MSC_VER = 1;
Tcl_LinkVar(interp, "_MSC_VER", (char *)&(cv__MSC_VER),
TCL_LINK_INT | TCL_LINK_READ_ONLY);
}
#endif
#ifdef __GNUC__
{
static const int cv___GNUC__ = 1;
Tcl_LinkVar(interp, "__GNUC__", (char *)&(cv___GNUC__),
TCL_LINK_INT | TCL_LINK_READ_ONLY);
}
#endif
}

View File

@ -422,6 +422,43 @@ static void testHexToUtf16le(
}
#endif
/*
** SQL function: real2hex(X)
**
** If argument X is a real number, then convert it into a string which is
** the big-endian hexadecimal representation of the ieee754 encoding of
** that number. If X is not a real number, return NULL.
*/
static void real2hex(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
union {
sqlite3_uint64 i;
double r;
unsigned char x[8];
} v;
char zOut[20];
int i;
int bigEndian;
v.i = 1;
bigEndian = v.x[0]==0;
v.r = sqlite3_value_double(argv[0]);
for(i=0; i<8; i++){
if( bigEndian ){
zOut[i*2] = "0123456789abcdef"[v.x[i]>>4];
zOut[i*2+1] = "0123456789abcdef"[v.x[i]&0xf];
}else{
zOut[14-i*2] = "0123456789abcdef"[v.x[i]>>4];
zOut[14-i*2+1] = "0123456789abcdef"[v.x[i]&0xf];
}
}
zOut[16] = 0;
sqlite3_result_text(context, zOut, -1, SQLITE_TRANSIENT);
}
static int registerTestFunctions(sqlite3 *db){
static const struct {
char *zName;
@ -444,6 +481,7 @@ static int registerTestFunctions(sqlite3 *db){
{ "test_eval", 1, SQLITE_UTF8, test_eval},
{ "test_isolation", 2, SQLITE_UTF8, test_isolation},
{ "test_counter", 1, SQLITE_UTF8, counterFunc},
{ "real2hex", 1, SQLITE_UTF8, real2hex},
};
int i;

View File

@ -48,7 +48,7 @@
/*
** Figure out if we are dealing with Unix, Windows, or some other
** operating system. After the following block of preprocess macros,
** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, SQLITE_OS_OS2, and SQLITE_OS_OTHER
** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, and SQLITE_OS_OTHER
** will defined to either 1 or 0. One of the four will be 1. The other
** three will be 0.
*/
@ -58,8 +58,6 @@
# define SQLITE_OS_UNIX 0
# undef SQLITE_OS_WIN
# define SQLITE_OS_WIN 0
# undef SQLITE_OS_OS2
# define SQLITE_OS_OS2 0
# else
# undef SQLITE_OS_OTHER
# endif
@ -71,20 +69,12 @@
|| defined(__MINGW32__) || defined(__BORLANDC__)
# define SQLITE_OS_WIN 1
# define SQLITE_OS_UNIX 0
# define SQLITE_OS_OS2 0
# elif defined(__EMX__) || defined(_OS2) || defined(OS2) \
|| defined(_OS2_) || defined(__OS2__)
# define SQLITE_OS_WIN 0
# define SQLITE_OS_UNIX 0
# define SQLITE_OS_OS2 1
# else
# define SQLITE_OS_WIN 0
# define SQLITE_OS_UNIX 1
# define SQLITE_OS_OS2 0
# endif
# else
# define SQLITE_OS_UNIX 0
# define SQLITE_OS_OS2 0
# endif
#else
# ifndef SQLITE_OS_WIN

File diff suppressed because it is too large Load Diff

View File

@ -81,6 +81,7 @@ struct Testvfs {
Tcl_Obj *pScript; /* Script to execute */
TestvfsBuffer *pBuffer; /* List of shared buffers */
int isNoshm;
int isFullshm;
int mask; /* Mask controlling [script] and [ioerr] */
@ -360,7 +361,8 @@ static int tvfsWrite(
if( p->pScript && p->mask&TESTVFS_WRITE_MASK ){
tvfsExecTcl(p, "xWrite",
Tcl_NewStringObj(pFd->zFilename, -1), pFd->pShmId, 0
Tcl_NewStringObj(pFd->zFilename, -1), pFd->pShmId,
Tcl_NewWideIntObj(iOfst)
);
tvfsResultCode(p, &rc);
}
@ -760,6 +762,7 @@ static int tvfsShmOpen(sqlite3_file *pFile){
pFd = tvfsGetFd(pFile);
p = (Testvfs *)pFd->pVfs->pAppData;
assert( 0==p->isFullshm );
assert( pFd->pShmId && pFd->pShm==0 && pFd->pNext==0 );
/* Evaluate the Tcl script:
@ -820,6 +823,10 @@ static int tvfsShmMap(
TestvfsFd *pFd = tvfsGetFd(pFile);
Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData);
if( p->isFullshm ){
return sqlite3OsShmMap(pFd->pReal, iPage, pgsz, isWrite, pp);
}
if( 0==pFd->pShm ){
rc = tvfsShmOpen(pFile);
if( rc!=SQLITE_OK ){
@ -864,6 +871,10 @@ static int tvfsShmLock(
int nLock;
char zLock[80];
if( p->isFullshm ){
return sqlite3OsShmLock(pFd->pReal, ofst, n, flags);
}
if( p->pScript && p->mask&TESTVFS_SHMLOCK_MASK ){
sqlite3_snprintf(sizeof(zLock), zLock, "%d %d", ofst, n);
nLock = (int)strlen(zLock);
@ -919,6 +930,11 @@ static void tvfsShmBarrier(sqlite3_file *pFile){
TestvfsFd *pFd = tvfsGetFd(pFile);
Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData);
if( p->isFullshm ){
sqlite3OsShmBarrier(pFd->pReal);
return;
}
if( p->pScript && p->mask&TESTVFS_SHMBARRIER_MASK ){
tvfsExecTcl(p, "xShmBarrier",
Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, 0
@ -936,6 +952,10 @@ static int tvfsShmUnmap(
TestvfsBuffer *pBuffer = pFd->pShm;
TestvfsFd **ppFd;
if( p->isFullshm ){
return sqlite3OsShmUnmap(pFd->pReal, deleteFlag);
}
if( !pBuffer ) return SQLITE_OK;
assert( pFd->pShmId && pFd->pShm );
@ -1350,6 +1370,7 @@ static int testvfs_cmd(
int i;
int isNoshm = 0; /* True if -noshm is passed */
int isFullshm = 0; /* True if -fullshm is passed */
int isDefault = 0; /* True if -default is passed */
int szOsFile = 0; /* Value passed to -szosfile */
int mxPathname = -1; /* Value passed to -mxpathname */
@ -1365,6 +1386,7 @@ static int testvfs_cmd(
if( Tcl_GetBooleanFromObj(interp, objv[i+1], &isNoshm) ){
return TCL_ERROR;
}
if( isNoshm ) isFullshm = 0;
}
else if( nSwitch>2 && 0==strncmp("-default", zSwitch, nSwitch) ){
if( Tcl_GetBooleanFromObj(interp, objv[i+1], &isDefault) ){
@ -1386,6 +1408,12 @@ static int testvfs_cmd(
return TCL_ERROR;
}
}
else if( nSwitch>2 && 0==strncmp("-fullshm", zSwitch, nSwitch) ){
if( Tcl_GetBooleanFromObj(interp, objv[i+1], &isFullshm) ){
return TCL_ERROR;
}
if( isFullshm ) isNoshm = 0;
}
else{
goto bad_args;
}
@ -1427,6 +1455,7 @@ static int testvfs_cmd(
pVfs->szOsFile = szOsFile;
p->pVfs = pVfs;
p->isNoshm = isNoshm;
p->isFullshm = isFullshm;
p->mask = TESTVFS_ALL_MASK;
sqlite3_vfs_register(pVfs, isDefault);

View File

@ -371,7 +371,7 @@ do_atof_calc:
/* if exponent, scale significand as appropriate
** and store in result. */
if( e ){
double scale = 1.0;
LONGDOUBLE_TYPE scale = 1.0;
/* attempt to handle extremely small/large numbers better */
if( e>307 && e<342 ){
while( e%308 ) { scale *= 1.0e+1; e -= 1; }

View File

@ -3130,6 +3130,9 @@ case OP_OpenWrite: {
VdbeCursor *pCur;
Db *pDb;
assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 );
assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 );
if( p->expired ){
rc = SQLITE_ABORT;
break;
@ -3153,7 +3156,7 @@ case OP_OpenWrite: {
}else{
wrFlag = 0;
}
if( pOp->p5 ){
if( pOp->p5 & OPFLAG_P2ISREG ){
assert( p2>0 );
assert( p2<=p->nMem );
pIn2 = &aMem[p2];
@ -3184,6 +3187,8 @@ case OP_OpenWrite: {
pCur->isOrdered = 1;
rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor);
pCur->pKeyInfo = pKeyInfo;
assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
sqlite3BtreeCursorHints(pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR));
/* Since it performs no memory allocation or IO, the only value that
** sqlite3BtreeCursor() may return is SQLITE_OK. */

View File

@ -452,11 +452,11 @@ int sqlite3VdbeTransferError(Vdbe *p);
#else
int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *);
void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *);
int sqlite3VdbeSorterRowkey(VdbeCursor *, Mem *);
int sqlite3VdbeSorterNext(sqlite3 *, VdbeCursor *, int *);
int sqlite3VdbeSorterRewind(sqlite3 *, VdbeCursor *, int *);
int sqlite3VdbeSorterWrite(sqlite3 *, VdbeCursor *, Mem *);
int sqlite3VdbeSorterCompare(VdbeCursor *, Mem *, int *);
int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *);
int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *);
int sqlite3VdbeSorterRewind(sqlite3 *, const VdbeCursor *, int *);
int sqlite3VdbeSorterWrite(sqlite3 *, const VdbeCursor *, Mem *);
int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int *);
#endif
#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0

View File

@ -71,17 +71,11 @@ int sqlite3_finalize(sqlite3_stmt *pStmt){
}else{
Vdbe *v = (Vdbe*)pStmt;
sqlite3 *db = v->db;
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex;
#endif
if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT;
#if SQLITE_THREADSAFE
mutex = v->db->mutex;
#endif
sqlite3_mutex_enter(mutex);
sqlite3_mutex_enter(db->mutex);
rc = sqlite3VdbeFinalize(v);
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(mutex);
sqlite3LeaveMutexAndCloseZombie(db);
}
return rc;
}

View File

@ -2470,6 +2470,7 @@ void sqlite3VdbeDelete(Vdbe *p){
if( NEVER(p==0) ) return;
db = p->db;
assert( sqlite3_mutex_held(db->mutex) );
if( p->pPrev ){
p->pPrev->pNext = p->pNext;
}else{

View File

@ -22,6 +22,7 @@
typedef struct VdbeSorterIter VdbeSorterIter;
typedef struct SorterRecord SorterRecord;
typedef struct FileWriter FileWriter;
/*
** NOTES ON DATA STRUCTURE USED FOR N-WAY MERGES:
@ -119,6 +120,24 @@ struct VdbeSorterIter {
sqlite3_file *pFile; /* File iterator is reading from */
u8 *aAlloc; /* Allocated space */
u8 *aKey; /* Pointer to current key */
u8 *aBuffer; /* Current read buffer */
int nBuffer; /* Size of read buffer in bytes */
};
/*
** An instance of this structure is used to organize the stream of records
** being written to files by the merge-sort code into aligned, page-sized
** blocks. Doing all I/O in aligned page-sized blocks helps I/O to go
** faster on many operating systems.
*/
struct FileWriter {
int eFWErr; /* Non-zero if in an error state */
u8 *aBuffer; /* Pointer to write buffer */
int nBuffer; /* Size of write buffer in bytes */
int iBufStart; /* First byte of buffer to write */
int iBufEnd; /* Last byte of buffer to write */
i64 iWriteOff; /* Offset of start of buffer in file */
sqlite3_file *pFile; /* File to write to */
};
/*
@ -144,9 +163,123 @@ struct SorterRecord {
*/
static void vdbeSorterIterZero(sqlite3 *db, VdbeSorterIter *pIter){
sqlite3DbFree(db, pIter->aAlloc);
sqlite3DbFree(db, pIter->aBuffer);
memset(pIter, 0, sizeof(VdbeSorterIter));
}
/*
** Read nByte bytes of data from the stream of data iterated by object p.
** If successful, set *ppOut to point to a buffer containing the data
** and return SQLITE_OK. Otherwise, if an error occurs, return an SQLite
** error code.
**
** The buffer indicated by *ppOut may only be considered valid until the
** next call to this function.
*/
static int vdbeSorterIterRead(
sqlite3 *db, /* Database handle (for malloc) */
VdbeSorterIter *p, /* Iterator */
int nByte, /* Bytes of data to read */
u8 **ppOut /* OUT: Pointer to buffer containing data */
){
int iBuf; /* Offset within buffer to read from */
int nAvail; /* Bytes of data available in buffer */
assert( p->aBuffer );
/* If there is no more data to be read from the buffer, read the next
** p->nBuffer bytes of data from the file into it. Or, if there are less
** than p->nBuffer bytes remaining in the PMA, read all remaining data. */
iBuf = p->iReadOff % p->nBuffer;
if( iBuf==0 ){
int nRead; /* Bytes to read from disk */
int rc; /* sqlite3OsRead() return code */
/* Determine how many bytes of data to read. */
nRead = (int)(p->iEof - p->iReadOff);
if( nRead>p->nBuffer ) nRead = p->nBuffer;
assert( nRead>0 );
/* Read data from the file. Return early if an error occurs. */
rc = sqlite3OsRead(p->pFile, p->aBuffer, nRead, p->iReadOff);
assert( rc!=SQLITE_IOERR_SHORT_READ );
if( rc!=SQLITE_OK ) return rc;
}
nAvail = p->nBuffer - iBuf;
if( nByte<=nAvail ){
/* The requested data is available in the in-memory buffer. In this
** case there is no need to make a copy of the data, just return a
** pointer into the buffer to the caller. */
*ppOut = &p->aBuffer[iBuf];
p->iReadOff += nByte;
}else{
/* The requested data is not all available in the in-memory buffer.
** In this case, allocate space at p->aAlloc[] to copy the requested
** range into. Then return a copy of pointer p->aAlloc to the caller. */
int nRem; /* Bytes remaining to copy */
/* Extend the p->aAlloc[] allocation if required. */
if( p->nAlloc<nByte ){
int nNew = p->nAlloc*2;
while( nByte>nNew ) nNew = nNew*2;
p->aAlloc = sqlite3DbReallocOrFree(db, p->aAlloc, nNew);
if( !p->aAlloc ) return SQLITE_NOMEM;
p->nAlloc = nNew;
}
/* Copy as much data as is available in the buffer into the start of
** p->aAlloc[]. */
memcpy(p->aAlloc, &p->aBuffer[iBuf], nAvail);
p->iReadOff += nAvail;
nRem = nByte - nAvail;
/* The following loop copies up to p->nBuffer bytes per iteration into
** the p->aAlloc[] buffer. */
while( nRem>0 ){
int rc; /* vdbeSorterIterRead() return code */
int nCopy; /* Number of bytes to copy */
u8 *aNext; /* Pointer to buffer to copy data from */
nCopy = nRem;
if( nRem>p->nBuffer ) nCopy = p->nBuffer;
rc = vdbeSorterIterRead(db, p, nCopy, &aNext);
if( rc!=SQLITE_OK ) return rc;
assert( aNext!=p->aAlloc );
memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy);
nRem -= nCopy;
}
*ppOut = p->aAlloc;
}
return SQLITE_OK;
}
/*
** Read a varint from the stream of data accessed by p. Set *pnOut to
** the value read.
*/
static int vdbeSorterIterVarint(sqlite3 *db, VdbeSorterIter *p, u64 *pnOut){
int iBuf;
iBuf = p->iReadOff % p->nBuffer;
if( iBuf && (p->nBuffer-iBuf)>=9 ){
p->iReadOff += sqlite3GetVarint(&p->aBuffer[iBuf], pnOut);
}else{
u8 aVarint[16], *a;
int i = 0, rc;
do{
rc = vdbeSorterIterRead(db, p, 1, &a);
if( rc ) return rc;
aVarint[(i++)&0xf] = a[0];
}while( (a[0]&0x80)!=0 );
sqlite3GetVarint(aVarint, pnOut);
}
return SQLITE_OK;
}
/*
** Advance iterator pIter to the next key in its PMA. Return SQLITE_OK if
** no error occurs, or an SQLite error code if one does.
@ -156,96 +289,18 @@ static int vdbeSorterIterNext(
VdbeSorterIter *pIter /* Iterator to advance */
){
int rc; /* Return Code */
int nRead; /* Number of bytes read */
int nRec = 0; /* Size of record in bytes */
int iOff = 0; /* Size of serialized size varint in bytes */
u64 nRec = 0; /* Size of record in bytes */
assert( pIter->iEof>=pIter->iReadOff );
if( pIter->iEof-pIter->iReadOff>5 ){
nRead = 5;
}else{
nRead = (int)(pIter->iEof - pIter->iReadOff);
}
if( nRead<=0 ){
if( pIter->iReadOff>=pIter->iEof ){
/* This is an EOF condition */
vdbeSorterIterZero(db, pIter);
return SQLITE_OK;
}
rc = sqlite3OsRead(pIter->pFile, pIter->aAlloc, nRead, pIter->iReadOff);
rc = vdbeSorterIterVarint(db, pIter, &nRec);
if( rc==SQLITE_OK ){
iOff = getVarint32(pIter->aAlloc, nRec);
if( (iOff+nRec)>nRead ){
int nRead2; /* Number of extra bytes to read */
if( (iOff+nRec)>pIter->nAlloc ){
int nNew = pIter->nAlloc*2;
while( (iOff+nRec)>nNew ) nNew = nNew*2;
pIter->aAlloc = sqlite3DbReallocOrFree(db, pIter->aAlloc, nNew);
if( !pIter->aAlloc ) return SQLITE_NOMEM;
pIter->nAlloc = nNew;
}
nRead2 = iOff + nRec - nRead;
rc = sqlite3OsRead(
pIter->pFile, &pIter->aAlloc[nRead], nRead2, pIter->iReadOff+nRead
);
}
}
assert( rc!=SQLITE_OK || nRec>0 );
pIter->iReadOff += iOff+nRec;
pIter->nKey = nRec;
pIter->aKey = &pIter->aAlloc[iOff];
return rc;
}
/*
** Write a single varint, value iVal, to file-descriptor pFile. Return
** SQLITE_OK if successful, or an SQLite error code if some error occurs.
**
** The value of *piOffset when this function is called is used as the byte
** offset in file pFile to write to. Before returning, *piOffset is
** incremented by the number of bytes written.
*/
static int vdbeSorterWriteVarint(
sqlite3_file *pFile, /* File to write to */
i64 iVal, /* Value to write as a varint */
i64 *piOffset /* IN/OUT: Write offset in file pFile */
){
u8 aVarint[9]; /* Buffer large enough for a varint */
int nVarint; /* Number of used bytes in varint */
int rc; /* Result of write() call */
nVarint = sqlite3PutVarint(aVarint, iVal);
rc = sqlite3OsWrite(pFile, aVarint, nVarint, *piOffset);
*piOffset += nVarint;
return rc;
}
/*
** Read a single varint from file-descriptor pFile. Return SQLITE_OK if
** successful, or an SQLite error code if some error occurs.
**
** The value of *piOffset when this function is called is used as the
** byte offset in file pFile from whence to read the varint. If successful
** (i.e. if no IO error occurs), then *piOffset is set to the offset of
** the first byte past the end of the varint before returning. *piVal is
** set to the integer value read. If an error occurs, the final values of
** both *piOffset and *piVal are undefined.
*/
static int vdbeSorterReadVarint(
sqlite3_file *pFile, /* File to read from */
i64 *piOffset, /* IN/OUT: Read offset in pFile */
i64 *piVal /* OUT: Value read from file */
){
u8 aVarint[9]; /* Buffer large enough for a varint */
i64 iOff = *piOffset; /* Offset in file to read from */
int rc; /* Return code */
rc = sqlite3OsRead(pFile, aVarint, 9, iOff);
if( rc==SQLITE_OK ){
*piOffset += getVarint(aVarint, (u64 *)piVal);
pIter->nKey = (int)nRec;
rc = vdbeSorterIterRead(db, pIter, (int)nRec, &pIter->aKey);
}
return rc;
@ -259,27 +314,52 @@ static int vdbeSorterReadVarint(
*/
static int vdbeSorterIterInit(
sqlite3 *db, /* Database handle */
VdbeSorter *pSorter, /* Sorter object */
const VdbeSorter *pSorter, /* Sorter object */
i64 iStart, /* Start offset in pFile */
VdbeSorterIter *pIter, /* Iterator to populate */
i64 *pnByte /* IN/OUT: Increment this value by PMA size */
){
int rc;
int rc = SQLITE_OK;
int nBuf;
nBuf = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
assert( pSorter->iWriteOff>iStart );
assert( pIter->aAlloc==0 );
assert( pIter->aBuffer==0 );
pIter->pFile = pSorter->pTemp1;
pIter->iReadOff = iStart;
pIter->nAlloc = 128;
pIter->aAlloc = (u8 *)sqlite3DbMallocRaw(db, pIter->nAlloc);
if( !pIter->aAlloc ){
pIter->nBuffer = nBuf;
pIter->aBuffer = (u8 *)sqlite3DbMallocRaw(db, nBuf);
if( !pIter->aBuffer ){
rc = SQLITE_NOMEM;
}else{
i64 nByte; /* Total size of PMA in bytes */
rc = vdbeSorterReadVarint(pSorter->pTemp1, &pIter->iReadOff, &nByte);
*pnByte += nByte;
pIter->iEof = pIter->iReadOff + nByte;
int iBuf;
iBuf = iStart % nBuf;
if( iBuf ){
int nRead = nBuf - iBuf;
if( (iStart + nRead) > pSorter->iWriteOff ){
nRead = (int)(pSorter->iWriteOff - iStart);
}
rc = sqlite3OsRead(
pSorter->pTemp1, &pIter->aBuffer[iBuf], nRead, iStart
);
assert( rc!=SQLITE_IOERR_SHORT_READ );
}
if( rc==SQLITE_OK ){
u64 nByte; /* Size of PMA in bytes */
pIter->iEof = pSorter->iWriteOff;
rc = vdbeSorterIterVarint(db, pIter, &nByte);
pIter->iEof = pIter->iReadOff + nByte;
*pnByte += nByte;
}
}
if( rc==SQLITE_OK ){
rc = vdbeSorterIterNext(db, pIter);
}
@ -303,10 +383,10 @@ static int vdbeSorterIterInit(
** has been allocated and contains an unpacked record that is used as key2.
*/
static void vdbeSorterCompare(
VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */
const VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */
int bOmitRowid, /* Ignore rowid field at end of keys */
void *pKey1, int nKey1, /* Left side of comparison */
void *pKey2, int nKey2, /* Right side of comparison */
const void *pKey1, int nKey1, /* Left side of comparison */
const void *pKey2, int nKey2, /* Right side of comparison */
int *pRes /* OUT: Result of comparison */
){
KeyInfo *pKeyInfo = pCsr->pKeyInfo;
@ -338,7 +418,7 @@ static void vdbeSorterCompare(
** multiple b-tree segments. Parameter iOut is the index of the aTree[]
** value to recalculate.
*/
static int vdbeSorterDoCompare(VdbeCursor *pCsr, int iOut){
static int vdbeSorterDoCompare(const VdbeCursor *pCsr, int iOut){
VdbeSorter *pSorter = pCsr->pSorter;
int i1;
int i2;
@ -464,7 +544,7 @@ static int vdbeSorterOpenTempFile(sqlite3 *db, sqlite3_file **ppFile){
** Set *ppOut to the head of the new list.
*/
static void vdbeSorterMerge(
VdbeCursor *pCsr, /* For pKeyInfo */
const VdbeCursor *pCsr, /* For pKeyInfo */
SorterRecord *p1, /* First list to merge */
SorterRecord *p2, /* Second list to merge */
SorterRecord **ppOut /* OUT: Head of merged list */
@ -498,7 +578,7 @@ static void vdbeSorterMerge(
** if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if an error
** occurs.
*/
static int vdbeSorterSort(VdbeCursor *pCsr){
static int vdbeSorterSort(const VdbeCursor *pCsr){
int i;
SorterRecord **aSlot;
SorterRecord *p;
@ -531,6 +611,91 @@ static int vdbeSorterSort(VdbeCursor *pCsr){
return SQLITE_OK;
}
/*
** Initialize a file-writer object.
*/
static void fileWriterInit(
sqlite3 *db, /* Database (for malloc) */
sqlite3_file *pFile, /* File to write to */
FileWriter *p, /* Object to populate */
i64 iStart /* Offset of pFile to begin writing at */
){
int nBuf = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
memset(p, 0, sizeof(FileWriter));
p->aBuffer = (u8 *)sqlite3DbMallocRaw(db, nBuf);
if( !p->aBuffer ){
p->eFWErr = SQLITE_NOMEM;
}else{
p->iBufEnd = p->iBufStart = (iStart % nBuf);
p->iWriteOff = iStart - p->iBufStart;
p->nBuffer = nBuf;
p->pFile = pFile;
}
}
/*
** Write nData bytes of data to the file-write object. Return SQLITE_OK
** if successful, or an SQLite error code if an error occurs.
*/
static void fileWriterWrite(FileWriter *p, u8 *pData, int nData){
int nRem = nData;
while( nRem>0 && p->eFWErr==0 ){
int nCopy = nRem;
if( nCopy>(p->nBuffer - p->iBufEnd) ){
nCopy = p->nBuffer - p->iBufEnd;
}
memcpy(&p->aBuffer[p->iBufEnd], &pData[nData-nRem], nCopy);
p->iBufEnd += nCopy;
if( p->iBufEnd==p->nBuffer ){
p->eFWErr = sqlite3OsWrite(p->pFile,
&p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart,
p->iWriteOff + p->iBufStart
);
p->iBufStart = p->iBufEnd = 0;
p->iWriteOff += p->nBuffer;
}
assert( p->iBufEnd<p->nBuffer );
nRem -= nCopy;
}
}
/*
** Flush any buffered data to disk and clean up the file-writer object.
** The results of using the file-writer after this call are undefined.
** Return SQLITE_OK if flushing the buffered data succeeds or is not
** required. Otherwise, return an SQLite error code.
**
** Before returning, set *piEof to the offset immediately following the
** last byte written to the file.
*/
static int fileWriterFinish(sqlite3 *db, FileWriter *p, i64 *piEof){
int rc;
if( p->eFWErr==0 && ALWAYS(p->aBuffer) && p->iBufEnd>p->iBufStart ){
p->eFWErr = sqlite3OsWrite(p->pFile,
&p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart,
p->iWriteOff + p->iBufStart
);
}
*piEof = (p->iWriteOff + p->iBufEnd);
sqlite3DbFree(db, p->aBuffer);
rc = p->eFWErr;
memset(p, 0, sizeof(FileWriter));
return rc;
}
/*
** Write value iVal encoded as a varint to the file-write object. Return
** SQLITE_OK if successful, or an SQLite error code if an error occurs.
*/
static void fileWriterWriteVarint(FileWriter *p, u64 iVal){
int nByte;
u8 aByte[10];
nByte = sqlite3PutVarint(aByte, iVal);
fileWriterWrite(p, aByte, nByte);
}
/*
** Write the current contents of the in-memory linked-list to a PMA. Return
@ -545,9 +710,12 @@ static int vdbeSorterSort(VdbeCursor *pCsr){
** Each record consists of a varint followed by a blob of data (the
** key). The varint is the number of bytes in the blob of data.
*/
static int vdbeSorterListToPMA(sqlite3 *db, VdbeCursor *pCsr){
static int vdbeSorterListToPMA(sqlite3 *db, const VdbeCursor *pCsr){
int rc = SQLITE_OK; /* Return code */
VdbeSorter *pSorter = pCsr->pSorter;
FileWriter writer;
memset(&writer, 0, sizeof(FileWriter));
if( pSorter->nInMemory==0 ){
assert( pSorter->pRecord==0 );
@ -565,39 +733,20 @@ static int vdbeSorterListToPMA(sqlite3 *db, VdbeCursor *pCsr){
}
if( rc==SQLITE_OK ){
i64 iOff = pSorter->iWriteOff;
SorterRecord *p;
SorterRecord *pNext = 0;
static const char eightZeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
fileWriterInit(db, pSorter->pTemp1, &writer, pSorter->iWriteOff);
pSorter->nPMA++;
rc = vdbeSorterWriteVarint(pSorter->pTemp1, pSorter->nInMemory, &iOff);
for(p=pSorter->pRecord; rc==SQLITE_OK && p; p=pNext){
fileWriterWriteVarint(&writer, pSorter->nInMemory);
for(p=pSorter->pRecord; p; p=pNext){
pNext = p->pNext;
rc = vdbeSorterWriteVarint(pSorter->pTemp1, p->nVal, &iOff);
if( rc==SQLITE_OK ){
rc = sqlite3OsWrite(pSorter->pTemp1, p->pVal, p->nVal, iOff);
iOff += p->nVal;
}
fileWriterWriteVarint(&writer, p->nVal);
fileWriterWrite(&writer, p->pVal, p->nVal);
sqlite3DbFree(db, p);
}
/* This assert verifies that unless an error has occurred, the size of
** the PMA on disk is the same as the expected size stored in
** pSorter->nInMemory. */
assert( rc!=SQLITE_OK || pSorter->nInMemory==(
iOff-pSorter->iWriteOff-sqlite3VarintLen(pSorter->nInMemory)
));
pSorter->iWriteOff = iOff;
if( rc==SQLITE_OK ){
/* Terminate each file with 8 extra bytes so that from any offset
** in the file we can always read 9 bytes without a SHORT_READ error */
rc = sqlite3OsWrite(pSorter->pTemp1, eightZeros, 8, iOff);
}
pSorter->pRecord = p;
rc = fileWriterFinish(db, &writer, &pSorter->iWriteOff);
}
return rc;
@ -608,7 +757,7 @@ static int vdbeSorterListToPMA(sqlite3 *db, VdbeCursor *pCsr){
*/
int sqlite3VdbeSorterWrite(
sqlite3 *db, /* Database handle */
VdbeCursor *pCsr, /* Sorter cursor */
const VdbeCursor *pCsr, /* Sorter cursor */
Mem *pVal /* Memory cell containing record */
){
VdbeSorter *pSorter = pCsr->pSorter;
@ -642,8 +791,14 @@ int sqlite3VdbeSorterWrite(
(pSorter->nInMemory>pSorter->mxPmaSize)
|| (pSorter->nInMemory>pSorter->mnPmaSize && sqlite3HeapNearlyFull())
)){
#ifdef SQLITE_DEBUG
i64 nExpect = pSorter->iWriteOff
+ sqlite3VarintLen(pSorter->nInMemory)
+ pSorter->nInMemory;
#endif
rc = vdbeSorterListToPMA(db, pCsr);
pSorter->nInMemory = 0;
assert( rc!=SQLITE_OK || (nExpect==pSorter->iWriteOff) );
}
return rc;
@ -654,7 +809,7 @@ int sqlite3VdbeSorterWrite(
*/
static int vdbeSorterInitMerge(
sqlite3 *db, /* Database handle */
VdbeCursor *pCsr, /* Cursor handle for this sorter */
const VdbeCursor *pCsr, /* Cursor handle for this sorter */
i64 *pnByte /* Sum of bytes in all opened PMAs */
){
VdbeSorter *pSorter = pCsr->pSorter;
@ -684,7 +839,7 @@ static int vdbeSorterInitMerge(
** Once the sorter has been populated, this function is called to prepare
** for iterating through its contents in sorted order.
*/
int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){
int sqlite3VdbeSorterRewind(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){
VdbeSorter *pSorter = pCsr->pSorter;
int rc; /* Return code */
sqlite3_file *pTemp2 = 0; /* Second temp file to use */
@ -704,7 +859,7 @@ int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){
return vdbeSorterSort(pCsr);
}
/* Write the current b-tree to a PMA. Close the b-tree cursor. */
/* Write the current in-memory list to a PMA. */
rc = vdbeSorterListToPMA(db, pCsr);
if( rc!=SQLITE_OK ) return rc;
@ -726,8 +881,12 @@ int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){
rc==SQLITE_OK && iNew*SORTER_MAX_MERGE_COUNT<pSorter->nPMA;
iNew++
){
int rc2; /* Return code from fileWriterFinish() */
FileWriter writer; /* Object used to write to disk */
i64 nWrite; /* Number of bytes in new PMA */
memset(&writer, 0, sizeof(FileWriter));
/* If there are SORTER_MAX_MERGE_COUNT or less PMAs in file pTemp1,
** initialize an iterator for each of them and break out of the loop.
** These iterators will be incrementally merged as the VDBE layer calls
@ -749,23 +908,20 @@ int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){
rc = vdbeSorterOpenTempFile(db, &pTemp2);
}
if( rc==SQLITE_OK ){
rc = vdbeSorterWriteVarint(pTemp2, nWrite, &iWrite2);
}
if( rc==SQLITE_OK ){
int bEof = 0;
fileWriterInit(db, pTemp2, &writer, iWrite2);
fileWriterWriteVarint(&writer, nWrite);
while( rc==SQLITE_OK && bEof==0 ){
int nToWrite;
VdbeSorterIter *pIter = &pSorter->aIter[ pSorter->aTree[1] ];
assert( pIter->pFile );
nToWrite = pIter->nKey + sqlite3VarintLen(pIter->nKey);
rc = sqlite3OsWrite(pTemp2, pIter->aAlloc, nToWrite, iWrite2);
iWrite2 += nToWrite;
if( rc==SQLITE_OK ){
rc = sqlite3VdbeSorterNext(db, pCsr, &bEof);
}
fileWriterWriteVarint(&writer, pIter->nKey);
fileWriterWrite(&writer, pIter->aKey, pIter->nKey);
rc = sqlite3VdbeSorterNext(db, pCsr, &bEof);
}
rc2 = fileWriterFinish(db, &writer, &iWrite2);
if( rc==SQLITE_OK ) rc = rc2;
}
}
@ -792,7 +948,7 @@ int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){
/*
** Advance to the next element in the sorter.
*/
int sqlite3VdbeSorterNext(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){
int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){
VdbeSorter *pSorter = pCsr->pSorter;
int rc; /* Return code */
@ -822,7 +978,7 @@ int sqlite3VdbeSorterNext(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){
** current key.
*/
static void *vdbeSorterRowkey(
VdbeSorter *pSorter, /* Sorter object */
const VdbeSorter *pSorter, /* Sorter object */
int *pnKey /* OUT: Size of current key in bytes */
){
void *pKey;
@ -841,7 +997,7 @@ static void *vdbeSorterRowkey(
/*
** Copy the current sorter key into the memory cell pOut.
*/
int sqlite3VdbeSorterRowkey(VdbeCursor *pCsr, Mem *pOut){
int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){
VdbeSorter *pSorter = pCsr->pSorter;
void *pKey; int nKey; /* Sorter key to copy into pOut */
@ -867,7 +1023,7 @@ int sqlite3VdbeSorterRowkey(VdbeCursor *pCsr, Mem *pOut){
** key.
*/
int sqlite3VdbeSorterCompare(
VdbeCursor *pCsr, /* Sorter cursor */
const VdbeCursor *pCsr, /* Sorter cursor */
Mem *pVal, /* Value to compare to current sorter key */
int *pRes /* OUT: Result of comparison */
){

View File

@ -169,9 +169,8 @@ void sqlite3ExplainBegin(Vdbe *pVdbe){
if( pVdbe ){
Explain *p;
sqlite3BeginBenignMalloc();
p = sqlite3_malloc( sizeof(Explain) );
p = (Explain *)sqlite3MallocZero( sizeof(Explain) );
if( p ){
memset(p, 0, sizeof(*p));
p->pVdbe = pVdbe;
sqlite3_free(pVdbe->pExplain);
pVdbe->pExplain = p;

View File

@ -142,8 +142,9 @@
** byte order of the host computer.
**
** The purpose of the wal-index is to answer this question quickly: Given
** a page number P, return the index of the last frame for page P in the WAL,
** or return NULL if there are no frames for page P in the WAL.
** a page number P and a maximum frame index M, return the index of the
** last frame in the wal before frame M for page P in the WAL, or return
** NULL if there are no frames for page P in the WAL prior to M.
**
** The wal-index consists of a header region, followed by an one or
** more index blocks.
@ -1198,6 +1199,7 @@ finished:
pInfo->nBackfill = 0;
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;
/* If more than one frame was recovered from the log file, report an
** event via sqlite3_log(). This is to help with identifying performance
@ -1698,7 +1700,7 @@ static int walCheckpoint(
assert( y<=pWal->hdr.mxFrame );
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
if( rc==SQLITE_OK ){
pInfo->aReadMark[i] = READMARK_NOT_USED;
pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
}else if( rc==SQLITE_BUSY ){
mxSafeFrame = y;
@ -2611,7 +2613,8 @@ static int walRestartLog(Wal *pWal){
aSalt[1] = salt1;
walIndexWriteHdr(pWal);
pInfo->nBackfill = 0;
for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
pInfo->aReadMark[1] = 0;
for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
assert( pInfo->aReadMark[0]==0 );
walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
}else if( rc!=SQLITE_BUSY ){

60
test/atof1.test Normal file
View File

@ -0,0 +1,60 @@
# 2012 June 18
#
# 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.
#
#***********************************************************************
#
# Tests of the sqlite3AtoF() function.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
if {![info exists __GNUC__]} {
finish_test
return
}
expr srand(1)
for {set i 1} {$i<20000} {incr i} {
set pow [expr {int((rand()-0.5)*100)}]
set x [expr {pow((rand()-0.5)*2*rand(),$pow)}]
set xf [format %.32e $x]
# Verify that text->real conversions get exactly same ieee754 floating-
# point value in SQLite as they do in TCL.
#
do_test atof1-1.$i.1 {
set y [db eval "SELECT $xf=\$x"]
if {!$y} {
puts -nonewline \173[db eval "SELECT real2hex($xf), real2hex(\$x)"]\175
db eval "SELECT $xf+0.0 AS a, \$x AS b" {
puts [format "\n%.60e\n%.60e\n%.60e" $x $a $b]
}
}
set y
} {1}
# Verify that round-trip real->text->real conversions using the quote()
# function preserve the bits of the numeric value exactly.
#
do_test atof1-1.$i.2 {
set y [db eval {SELECT $x=CAST(quote($x) AS real)}]
if {!$y} {
db eval {SELECT real2hex($x) a, real2hex(CAST(quote($x) AS real)) b} {}
puts "\nIN: $a $xf"
puts [format {QUOTE: %16s %s} {} [db eval {SELECT quote($x)}]]
db eval {SELECT CAST(quote($x) AS real) c} {}
puts "OUT: $b [format %.32e $c]"
}
set y
} {1}
}
finish_test

View File

@ -423,7 +423,7 @@ do_test backup-4.3.2 {
} {SQLITE_BUSY}
do_test backup-4.3.3 {
sqlite3_errmsg db2
} {unable to close due to unfinished backup operation}
} {unable to close due to unfinalized statements or unfinished backups}
do_test backup-4.3.4 {
B step 50
} {SQLITE_DONE}

View File

@ -151,7 +151,7 @@ datetest 3.2.1 {strftime('pre%fpost','2003-10-31 12:34:56.432')} pre56.432post
datetest 3.2.2 {strftime('%f','2003-10-31 12:34:59.9999999')} 59.999
datetest 3.3 {strftime('%H','2003-10-31 12:34:56.432')} 12
datetest 3.4 {strftime('%j','2003-10-31 12:34:56.432')} 304
datetest 3.5 {strftime('%J','2003-10-31 12:34:56.432')} 2452944.02426426
datetest 3.5 {strftime('%J','2003-10-31 12:34:56.432')} 2452944.024264259
datetest 3.6 {strftime('%m','2003-10-31 12:34:56.432')} 10
datetest 3.7 {strftime('%M','2003-10-31 12:34:56.432')} 34
datetest 3.8.1 {strftime('%s','2003-10-31 12:34:56.432')} 1067603696

View File

@ -174,6 +174,16 @@ ifcapable icu {
insert into x1 (name) values (NULL);
delete from x1;
}
proc cp_to_str {codepoint_list} {
set fmt [string repeat %c [llength $codepoint_list]]
eval [list format $fmt] $codepoint_list
}
do_test 5.2 {
set str [cp_to_str {19968 26085 32822 32645 27874 23433 20986}]
execsql { INSERT INTO x1 VALUES($str) }
} {}
}

View File

@ -326,5 +326,62 @@ do_unicode_token_test3 5.11 "tokenchars=\u0301" \
"0 hello\u0301world hello\u0301world 1 helloworld helloworld"
#-------------------------------------------------------------------------
proc do_tokenize {tokenizer txt} {
set res [list]
foreach {a b c} [db one {SELECT fts3_tokenizer_test($tokenizer, $txt)}] {
lappend res $b
}
set res
}
# Argument $lCodepoint must be a list of codepoints (integers) that
# correspond to whitespace characters. This command creates a string
# $W from the codepoints, then tokenizes "${W}hello{$W}world${W}"
# using tokenizer $tokenizer. The test passes if the tokenizer successfully
# extracts the two 5 character tokens.
#
proc do_isspace_test {tn tokenizer lCp} {
set whitespace [format [string repeat %c [llength $lCp]] {*}$lCp]
set txt "${whitespace}hello${whitespace}world${whitespace}"
uplevel [list do_test $tn [list do_tokenize $tokenizer $txt] {hello world}]
}
set tokenizers [list unicode61]
ifcapable icu { lappend tokenizers icu }
# Some tests to check that the tokenizers can both identify white-space
# codepoints. All codepoints tested below are of type "Zs" in the
# UnicodeData.txt file.
foreach T $tokenizers {
do_isspace_test 6.$T.1 $T 32
do_isspace_test 6.$T.2 $T 160
do_isspace_test 6.$T.3 $T 5760
do_isspace_test 6.$T.4 $T 6158
do_isspace_test 6.$T.5 $T 8192
do_isspace_test 6.$T.6 $T 8193
do_isspace_test 6.$T.7 $T 8194
do_isspace_test 6.$T.8 $T 8195
do_isspace_test 6.$T.9 $T 8196
do_isspace_test 6.$T.10 $T 8197
do_isspace_test 6.$T.11 $T 8198
do_isspace_test 6.$T.12 $T 8199
do_isspace_test 6.$T.13 $T 8200
do_isspace_test 6.$T.14 $T 8201
do_isspace_test 6.$T.15 $T 8202
do_isspace_test 6.$T.16 $T 8239
do_isspace_test 6.$T.17 $T 8287
do_isspace_test 6.$T.18 $T 12288
do_isspace_test 6.$T.19 $T {32 160 5760 6158}
do_isspace_test 6.$T.19 $T {8192 8193 8194 8195}
do_isspace_test 6.$T.19 $T {8196 8197 8198 8199}
do_isspace_test 6.$T.19 $T {8200 8201 8202 8239}
do_isspace_test 6.$T.19 $T {8287 12288}
}
finish_test

View File

@ -312,7 +312,7 @@ ifcapable floatingpoint {
execsql {SELECT round(9999999999999.55,1);}
} {9999999999999.6}
do_test func-4.38 {
execsql {SELECT round(9999999999999.555,2);}
execsql {SELECT round(9999999999999.556,2);}
} {9999999999999.56}
}

75
test/index5.test Normal file
View File

@ -0,0 +1,75 @@
# 2012 August 6
#
# 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 index5
do_test 1.1 {
execsql {
PRAGMA page_size = 1024;
CREATE TABLE t1(x);
BEGIN;
}
for {set i 0} {$i < 100000} {incr i} {
execsql { INSERT INTO t1 VALUES(randstr(100,100)) }
}
execsql COMMIT
execsql {
CREATE INDEX i1 ON t1(x);
DROP INDEX I1;
PRAGMA main.page_size;
}
} {1024}
db close
testvfs tvfs
tvfs filter xWrite
tvfs script write_cb
proc write_cb {xCall file handle iOfst} {
if {[file tail $file]=="test.db"} {
lappend ::write_list [expr $iOfst/1024]
}
puts "$xCall $file $args"
}
do_test 1.2 {
sqlite3 db test.db -vfs tvfs
set ::write_list [list]
execsql { CREATE INDEX i1 ON t1(x) }
} {}
do_test 1.3 {
set nForward 0
set nBackward 0
set nNoncont 0
set iPrev [lindex $::write_list 0]
for {set i 1} {$i < [llength $::write_list]} {incr i} {
set iNext [lindex $::write_list $i]
if {$iNext==($iPrev+1)} {
incr nForward
} elseif {$iNext==($iPrev-1)} {
incr nBackward
} else {
incr nNoncont
}
set iPrev $iNext
}
expr {$nForward > $nBackward}
} {1}
db close
tvfs delete
finish_test

View File

@ -23,7 +23,7 @@ ifcapable !load_ext {
# The name of the test extension varies by operating system.
#
if {$::tcl_platform(platform) eq "windows" || $::tcl_platform(platform) eq "os2"} {
if {$::tcl_platform(platform) eq "windows"} {
set testextension ./testloadext.dll
} else {
set testextension ./libtestloadext.so

View File

@ -377,7 +377,7 @@ do_test misc7-16.X {
# These tests do not work on windows due to restrictions in the
# windows file system.
#
if {$tcl_platform(platform)!="windows" && $tcl_platform(platform)!="os2"} {
if {$tcl_platform(platform)!="windows"} {
# Some network filesystems (ex: AFP) do not support setting read-only
# permissions. Only run these tests if full unix permission setting

View File

@ -114,7 +114,7 @@ set allquicktests [test_set $alltests -exclude {
thread003.test thread004.test thread005.test trans2.test vacuum3.test
incrvacuum_ioerr.test autovacuum_crash.test btree8.test shared_err.test
vtab_err.test walslow.test walcrash.test walcrash3.test
walthread.test rtree3.test indexfault.test
walthread.test rtree3.test indexfault.test securedel2.test
}]
if {[info exists ::env(QUICKTEST_INCLUDE)]} {
set allquicktests [concat $allquicktests $::env(QUICKTEST_INCLUDE)]

View File

@ -16,6 +16,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix pragma
# 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).
@ -41,6 +42,8 @@ do_not_use_codec
# reset when the schema is reloaded.
# pragma-16.*: Test proxy locking
# pragma-20.*: Test data_store_directory.
# pragma-22.*: Test that "PRAGMA [db].integrity_check" respects the "db"
# directive - if it is present.
#
ifcapable !pragma {
@ -1554,4 +1557,67 @@ do_test pragma-20.8 {
forcedelete data_dir
} ;# endif windows
do_test 21.1 {
# Create a corrupt database in testerr.db. And a non-corrupt at test.db.
#
db close
forcedelete test.db
sqlite3 db test.db
execsql {
PRAGMA page_size = 1024;
PRAGMA auto_vacuum = 0;
CREATE TABLE t1(a PRIMARY KEY, b);
INSERT INTO t1 VALUES(1, 1);
}
for {set i 0} {$i < 10} {incr i} {
execsql { INSERT INTO t1 SELECT a + (1 << $i), b + (1 << $i) FROM t1 }
}
db close
forcecopy test.db testerr.db
hexio_write testerr.db 15000 [string repeat 55 100]
} {100}
set mainerr {*** in database main ***
Multiple uses for byte 672 of page 15}
set auxerr {*** in database aux ***
Multiple uses for byte 672 of page 15}
do_test 22.2 {
catch { db close }
sqlite3 db testerr.db
execsql { PRAGMA integrity_check }
} [list $mainerr]
do_test 22.3.1 {
catch { db close }
sqlite3 db test.db
execsql {
ATTACH 'testerr.db' AS 'aux';
PRAGMA integrity_check;
}
} [list $auxerr]
do_test 22.3.2 {
execsql { PRAGMA main.integrity_check; }
} {ok}
do_test 22.3.3 {
execsql { PRAGMA aux.integrity_check; }
} [list $auxerr]
do_test 22.4.1 {
catch { db close }
sqlite3 db testerr.db
execsql {
ATTACH 'test.db' AS 'aux';
PRAGMA integrity_check;
}
} [list $mainerr]
do_test 22.4.2 {
execsql { PRAGMA main.integrity_check; }
} [list $mainerr]
do_test 22.4.3 {
execsql { PRAGMA aux.integrity_check; }
} {ok}
finish_test

View File

@ -218,8 +218,6 @@ proc run_test_suite {name testtarget config} {
if {$::tcl_platform(platform)=="windows"} {
append opts " -DSQLITE_OS_WIN=1"
} elseif {$::tcl_platform(platform)=="os2"} {
append opts " -DSQLITE_OS_OS2=1"
} else {
append opts " -DSQLITE_OS_UNIX=1"
}

95
test/securedel2.test Normal file
View File

@ -0,0 +1,95 @@
# 2012 August 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.
#
#*************************************************************************
#
# Tests for the secure_delete pragma.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix securedel2
# Generate 1000 pseudo-random 64-bit blobs.
#
for {set i 1} {$i <= 1000} {incr i} {
set aBlob($i) [string range [db one {SELECT quote(randomblob(8))}] 2 end-1]
}
proc detect_blob_prepare {zFile} {
set nByte [file size $zFile]
set ::detect_blob_data [hexio_read $zFile 0 $nByte]
}
proc detect_blob {zFile iBlob} {
if {$zFile != ""} { detect_blob_prepare $zFile }
string match "*$::aBlob($iBlob)*" $::detect_blob_data
}
do_test 1.1 {
execsql { PRAGMA secure_delete = 1 }
execsql { PRAGMA auto_vacuum = 0 }
execsql { CREATE TABLE t1(x, y) }
for {set i 1} {$i <= 1000} {incr i} {
set x "X'[string repeat $aBlob($i) 1]'"
set y "X'[string repeat $aBlob($i) 500]'"
execsql "INSERT INTO t1 VALUES($x, $y)"
}
} {}
do_test 1.2 { detect_blob test.db 1 } {1}
forcecopy test.db test.db.bak
do_execsql_test 1.3.1 { PRAGMA secure_delete = 0 } {0}
do_execsql_test 1.3.2 { DELETE FROM t1 WHERE rowid = 1 }
do_test 1.3.3 { detect_blob test.db 1 } {1}
db close
forcecopy test.db.bak test.db
sqlite3 db test.db
do_execsql_test 1.4.1 { PRAGMA secure_delete = 1 } {1}
do_execsql_test 1.4.2 { DELETE FROM t1 WHERE rowid = 1 }
do_test 1.4.3 { detect_blob test.db 1 } {0}
do_execsql_test 1.5.1 { DELETE FROM t1 WHERE rowid>850 } {}
do_test 1.5.2 {
set n 0
detect_blob_prepare test.db
for {set i 851} {$i <= 1000} {incr i 5} {
incr n [detect_blob {} $i]
}
set n
} {0}
db close
sqlite3 db test.db
do_test 1.6.1 {
execsql {
PRAGMA cache_size = 200;
PRAGMA secure_delete = 1;
CREATE TABLE t2(x);
SELECT * FROM t1;
}
for {set i 100} {$i < 5000} {incr i} {
execsql { INSERT INTO t2 VALUES(randomblob($i)) }
}
execsql { DELETE FROM t1 }
} {}
do_test 1.6.2 {
set n 0
detect_blob_prepare test.db
for {set i 2} {$i <= 850} {incr i 5} {
incr n [detect_blob {} $i]
}
set n
} {0}
finish_test

150
test/spellfix.test Normal file
View File

@ -0,0 +1,150 @@
# 2012 July 12
#
# 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 spellfix
ifcapable !vtab { finish_test ; return }
register_spellfix_module db
set vocab {
rabbi rabbit rabbits rabble rabid rabies raccoon raccoons race raced racer
racers races racetrack racial racially racing rack racked racket racketeer
racketeering racketeers rackets racking racks radar radars radial radially
radian radiance radiant radiantly radiate radiated radiates radiating radiation
radiations radiator radiators radical radically radicals radices radii radio
radioactive radioastronomy radioed radiography radioing radiology radios radish
radishes radium radius radix radon raft rafter rafters rafts rag rage raged
rages ragged raggedly raggedness raging rags ragweed raid raided raider raiders
raiding raids rail railed railer railers railing railroad railroaded railroader
railroaders railroading railroads rails railway railways raiment rain rainbow
raincoat raincoats raindrop raindrops rained rainfall rainier rainiest raining
rains rainstorm rainy raise raised raiser raisers raises raisin raising rake
raked rakes raking rallied rallies rally rallying ram ramble rambler rambles
rambling ramblings ramification ramifications ramp rampage rampant rampart
ramps ramrod rams ran ranch ranched rancher ranchers ranches ranching rancid
random randomization randomize randomized randomizes randomly randomness randy
rang range ranged rangeland ranger rangers ranges ranging rangy rank ranked
ranker rankers rankest ranking rankings rankle rankly rankness ranks ransack
ransacked ransacking ransacks ransom ransomer ransoming ransoms rant ranted
ranter ranters ranting rants rap rapacious rape raped raper rapes rapid
rapidity rapidly rapids rapier raping rapport rapprochement raps rapt raptly
rapture raptures rapturous rare rarely rareness rarer rarest rarity rascal
rascally rascals rash rasher rashly rashness rasp raspberry rasped rasping
rasps raster rat rate rated rater raters rates rather ratification ratified
ratifies ratify ratifying rating ratings ratio ration rational rationale
rationales rationalities rationality rationalization rationalizations
rationalize rationalized rationalizes rationalizing rationally rationals
rationing rations ratios rats rattle rattled rattler rattlers rattles
rattlesnake rattlesnakes rattling raucous ravage ravaged ravager ravagers
ravages ravaging rave raved raven ravening ravenous ravenously ravens raves
ravine ravines raving ravings raw rawer rawest rawly rawness ray rays raze
razor razors re reabbreviate reabbreviated reabbreviates reabbreviating reach
reachability reachable reachably reached reacher reaches reaching reacquired
react reacted reacting reaction reactionaries reactionary reactions reactivate
reactivated reactivates reactivating reactivation reactive reactively
reactivity reactor reactors reacts read readability readable reader readers
readied readier readies readiest readily readiness reading readings readjusted
readout readouts reads ready readying real realest realign realigned realigning
realigns realism realist realistic realistically realists realities reality
}
do_test 1.1 {
execsql { CREATE VIRTUAL TABLE t1 USING spellfix1 }
foreach word $vocab {
execsql { INSERT INTO t1(word) VALUES($word) }
}
} {}
foreach {tn word res} {
1 raxpi* {rasping 5 rasped 5 raspberry 6 rasp 4 rasps 4}
2 ril* {rail 4 railway 4 railing 4 rails 4 railways 4}
3 rilis* {realist 6 realistic 6 realistically 6 realists 6 realism 6}
4 reail* {realities 3 reality 3 real 3 realest 3 realist 3}
5 ras* {rasp 3 rash 3 rasped 3 rasping 3 rasps 3}
6 realistss* {realists 8 realigns 8 realistic 9 realistically 9 realest 7}
7 realistss {realists 8 realist 7 realigns 8 realistic 9 realest 7}
8 rllation* {realities 9 reality 7 rallied 7 railed 4}
9 renstom* {rainstorm 8 ransomer 6 ransom 6 ransoming 6 ransoms 6}
} {
do_execsql_test 1.2.$tn {
SELECT word, matchlen FROM t1 WHERE word MATCH $word LIMIT 5
} $res
}
do_execsql_test 2.1 {
CREATE VIRTUAL TABLE t2 USING spellfix1;
INSERT INTO t2 (word, soundslike) VALUES('school', 'skuul');
INSERT INTO t2 (word, soundslike) VALUES('psalm', 'sarm');
SELECT word, matchlen FROM t2 WHERE word MATCH 'sar*' LIMIT 5;
} {psalm 4}
do_execsql_test 2.2 {
SELECT word, matchlen FROM t2 WHERE word MATCH 'skol*' LIMIT 5;
} {school 6}
set vocab {
kangaroo kanji kappa karate keel keeled keeling keels keen keener keenest
keenly keenness keep keeper keepers keeping keeps ken kennel kennels kept
kerchief kerchiefs kern kernel kernels kerosene ketchup kettle
kettles key keyboard keyboards keyed keyhole keying keynote keypad keypads keys
keystroke keystrokes keyword keywords kick kicked kicker kickers kicking
kickoff kicks kid kidded kiddie kidding kidnap kidnapper kidnappers kidnapping
kidnappings kidnaps kidney kidneys kids kill killed killer killers killing
killingly killings killjoy kills kilobit kilobits kiloblock kilobyte kilobytes
kilogram kilograms kilohertz kilohm kilojoule kilometer kilometers kiloton
kilovolt kilowatt kiloword kimono kin kind kinder kindergarten kindest
kindhearted kindle kindled kindles kindling kindly kindness kindred kinds
kinetic king kingdom kingdoms kingly kingpin kings kink kinky kinship kinsman
kiosk kiss kissed kisser kissers kisses kissing kit kitchen kitchenette
kitchens kite kited kites kiting kits kitten kittenish kittens kitty klaxon
kludge kludges klystron knack knapsack knapsacks knave knaves knead kneads knee
kneecap kneed kneeing kneel kneeled kneeling kneels knees knell knells knelt
knew knife knifed knifes knifing knight knighted knighthood knighting knightly
knights knit knits knives knob knobs knock knockdown knocked knocker knockers
knocking knockout knocks knoll knolls knot knots knotted knotting know knowable
knower knowhow knowing knowingly knowledge knowledgeable known knows knuckle
knuckled knuckles koala kosher kudo
}
do_execsql_test 3.1 {
CREATE TABLE costs(iLang, cFrom, cTo, iCost);
INSERT INTO costs VALUES(0, 'a', 'e', 1);
INSERT INTO costs VALUES(0, 'e', 'i', 1);
INSERT INTO costs VALUES(0, 'i', 'o', 1);
INSERT INTO costs VALUES(0, 'o', 'u', 1);
INSERT INTO costs VALUES(0, 'u', 'a', 1);
CREATE VIRTUAL TABLE t3 USING spellfix1(edit_cost_table=costs);
}
do_test 3.2 {
foreach w $vocab {
execsql { INSERT INTO t3(word) VALUES($w) }
}
} {}
breakpoint
foreach {tn word res} {
1 kos* {kosher 3 kiosk 4 kudo 2 kiss 3 kissed 3}
2 kellj* {killjoy 5 kill 4 killed 4 killer 4 killers 4}
3 kellj {kill 4 kills 5 killjoy 7 keel 4 killed 6}
} {
do_execsql_test 1.2.$tn {
SELECT word, matchlen FROM t3 WHERE word MATCH $word
ORDER BY score, word LIMIT 5
} $res
}
finish_test

View File

@ -126,9 +126,11 @@ set RECOVER [list \
{1 7 unlock exclusive} {0 1 unlock exclusive} \
]
set READ [list \
{4 1 lock exclusive} {4 1 unlock exclusive} \
{4 1 lock shared} {4 1 unlock shared} \
]
set INITSLOT [list \
{4 1 lock exclusive} {4 1 unlock exclusive} \
]
foreach {tn iInsert res wal_index_hdr_mod wal_locks} "
2 5 {5 15} 0 {$RECOVER $READ}
@ -141,7 +143,7 @@ foreach {tn iInsert res wal_index_hdr_mod wal_locks} "
9 12 {12 78} 7 {$RECOVER $READ}
10 13 {13 91} 8 {$RECOVER $READ}
11 14 {14 105} 9 {$RECOVER $READ}
12 15 {15 120} -1 {$READ}
12 15 {15 120} -1 {$INITSLOT $READ}
" {
do_test wal2-1.$tn.1 {

View File

@ -655,7 +655,7 @@ T filter xShmLock
T script lock_callback
proc lock_callback {method file handle spec} {
if {$spec == "4 1 unlock exclusive"} {
if {$spec == "1 7 unlock exclusive"} {
T filter {}
set ::r [catchsql { SELECT * FROM b } db2]
}

View File

@ -56,6 +56,7 @@ do_multiclient_test tn {
do_test 1.1.1 {
code2 { sqlite3 db2 test.db }
sql2 {
PRAGMA auto_vacuum = 0;
PRAGMA journal_mode = WAL;
CREATE TABLE t1(x, y);
INSERT INTO t1 VALUES('a', 'b');
@ -163,6 +164,132 @@ do_multiclient_test tn {
do_test 1.3.2.4 {
code1 { sqlite3_extended_errcode db }
} {SQLITE_READONLY_RECOVERY}
#-----------------------------------------------------------------------
# Test cases 1.4.* check that checkpoints and log wraps don't prevent
# read-only connections from reading the database.
do_test 1.4.1 {
code1 { db close }
forcedelete test.db-shm
file exists test.db-shm
} {0}
# Open one read-only and one read-write connection. Write some data
# and then run a checkpoint using the read-write connection. Then
# check the read-only connection can still read.
do_test 1.4.2 {
code1 { sqlite3 db file:test.db?readonly_shm=1 }
code2 { sqlite3 db2 test.db }
csql2 {
INSERT INTO t1 VALUES(1, 2);
INSERT INTO t1 VALUES(3, 4);
INSERT INTO t1 VALUES(5, 6);
PRAGMA wal_checkpoint;
}
} {0 {0 3 3}}
do_test 1.4.3 {
csql1 { SELECT * FROM t1 }
} {0 {a b c d e f g h i j k l 1 2 3 4 5 6}}
# Using the read-write connection, open a transaction and write lots
# of data - causing a cache spill and a log wrap. Then check that the
# read-only connection can still read the database.
do_test 1.4.4.1 {
csql2 {
PRAGMA cache_size = 10;
BEGIN;
CREATE TABLE t2(x, y);
INSERT INTO t2 VALUES('abc', 'xyz');
INSERT INTO t2 SELECT x||y, y||x FROM t2;
INSERT INTO t2 SELECT x||y, y||x FROM t2;
INSERT INTO t2 SELECT x||y, y||x FROM t2;
INSERT INTO t2 SELECT x||y, y||x FROM t2;
INSERT INTO t2 SELECT x||y, y||x FROM t2;
INSERT INTO t2 SELECT x||y, y||x FROM t2;
INSERT INTO t2 SELECT x||y, y||x FROM t2;
INSERT INTO t2 SELECT x||y, y||x FROM t2;
INSERT INTO t2 SELECT x||y, y||x FROM t2;
}
file size test.db-wal
} {147800}
do_test 1.4.4.2 {
csql1 { SELECT * FROM t1 }
} {0 {a b c d e f g h i j k l 1 2 3 4 5 6}}
do_test 1.4.4.3 {
csql2 COMMIT
csql1 { SELECT count(*) FROM t2 }
} {0 512}
do_test 1.4.5 {
code2 { db2 close }
code1 { db close }
} {}
}
forcedelete test.db
#-----------------------------------------------------------------------
# Test cases 2.* check that a read-only connection may read the
# database file while a checkpoint operation is ongoing.
#
do_multiclient_test tn {
# Do not run tests with the connections in the same process.
#
if {$tn==2} continue
# Close all connections and delete the database.
#
code1 { db close }
code2 { db2 close }
code3 { db3 close }
forcedelete test.db
forcedelete walro
foreach c {code1 code2 code3} {
$c {
sqlite3_shutdown
sqlite3_config_uri 1
}
}
proc tv_hook {x file args} {
if {[file tail $file]=="test.db-wal"} {
do_test 2.1.2 {
code2 { sqlite3 db2 file:test.db?readonly_shm=1 }
csql2 { SELECT count(*) FROM t2 }
} {0 4}
do_test 2.1.3 {
code2 { db2 close }
} {}
}
}
do_test 2.1.1 {
testvfs tv -default 1 -fullshm 1
tv script tv_hook
tv filter {}
code1 { sqlite3 db test.db }
csql1 {
PRAGMA auto_vacuum = 0;
PRAGMA journal_mode = WAL;
BEGIN;
CREATE TABLE t2(x, y);
INSERT INTO t2 VALUES('abc', 'xyz');
INSERT INTO t2 SELECT x||y, y||x FROM t2;
INSERT INTO t2 SELECT x||y, y||x FROM t2;
COMMIT;
}
} {0 wal}
tv filter xSync
set res [csql1 { PRAGMA wal_checkpoint }]
do_test 2.1.4 { set res } {0 {0 2 2}}
do_test 2.1.5 {
code1 { db close }
code1 { tv delete }
} {}
}
finish_test

View File

@ -277,8 +277,8 @@ do_thread_test2 walthread-1 -seconds $seconds(walthread-1) -init {
proc write_transaction {} {
db eval {
BEGIN;
INSERT INTO t1 VALUES(randomblob(100));
INSERT INTO t1 VALUES(randomblob(100));
INSERT INTO t1 VALUES(randomblob(101 + $::E(pid)));
INSERT INTO t1 VALUES(randomblob(101 + $::E(pid)));
INSERT INTO t1 SELECT md5sum(x) FROM t1;
COMMIT;
}

394
tool/build-all-msvc.bat Executable file
View File

@ -0,0 +1,394 @@
@ECHO OFF
::
:: build-all-msvc.bat --
::
:: Multi-Platform Build Tool for MSVC
::
SETLOCAL
REM SET __ECHO=ECHO
REM SET __ECHO2=ECHO
IF NOT DEFINED _AECHO (SET _AECHO=REM)
IF NOT DEFINED _CECHO (SET _CECHO=REM)
IF NOT DEFINED _VECHO (SET _VECHO=REM)
%_AECHO% Running %0 %*
REM SET DFLAGS=/L
%_VECHO% DFlags = '%DFLAGS%'
SET FFLAGS=/V /F /G /H /I /R /Y /Z
%_VECHO% FFlags = '%FFLAGS%'
SET ROOT=%~dp0\..
SET ROOT=%ROOT:\\=\%
%_VECHO% Root = '%ROOT%'
REM
REM NOTE: The first and only argument to this batch file should be the output
REM directory where the platform-specific binary directories should be
REM created.
REM
SET BINARYDIRECTORY=%1
IF NOT DEFINED BINARYDIRECTORY (
GOTO usage
)
%_VECHO% BinaryDirectory = '%BINARYDIRECTORY%'
SET DUMMY=%2
IF DEFINED DUMMY (
GOTO usage
)
REM
REM NOTE: From this point, we need a clean error level. Reset it now.
REM
CALL :fn_ResetErrorLevel
REM
REM NOTE: Change the current directory to the root of the source tree, saving
REM the current directory on the directory stack.
REM
%__ECHO2% PUSHD "%ROOT%"
IF ERRORLEVEL 1 (
ECHO Could not change directory to "%ROOT%".
GOTO errors
)
REM
REM NOTE: This batch file requires the ComSpec environment variable to be set,
REM typically to something like "C:\Windows\System32\cmd.exe".
REM
IF NOT DEFINED ComSpec (
ECHO The ComSpec environment variable must be defined.
GOTO errors
)
REM
REM NOTE: This batch file requires the VcInstallDir environment variable to be
REM set. Tyipcally, this means this batch file needs to be run from an
REM MSVC command prompt.
REM
IF NOT DEFINED VCINSTALLDIR (
ECHO The VCINSTALLDIR environment variable must be defined.
GOTO errors
)
REM
REM NOTE: If the list of platforms is not already set, use the default list.
REM
IF NOT DEFINED PLATFORMS (
SET PLATFORMS=x86 x86_amd64 x86_arm
)
%_VECHO% Platforms = '%PLATFORMS%'
REM
REM NOTE: Setup environment variables to translate between the MSVC platform
REM names and the names to be used for the platform-specific binary
REM directories.
REM
SET x86_NAME=x86
SET x86_amd64_NAME=x64
SET x86_arm_NAME=ARM
%_VECHO% x86_Name = '%x86_NAME%'
%_VECHO% x86_amd64_Name = '%x86_amd64_NAME%'
%_VECHO% x86_arm_Name = '%x86_arm_NAME%'
REM
REM NOTE: Check for the external tools needed during the build process ^(i.e.
REM those that do not get compiled as part of the build process itself^)
REM along the PATH.
REM
FOR %%T IN (gawk.exe tclsh85.exe) DO (
SET %%T_PATH=%%~dp$PATH:T
)
REM
REM NOTE: Set the TOOLPATH variable to contain all the directories where the
REM external tools were found in the search above.
REM
SET TOOLPATH=%gawk.exe_PATH%;%tclsh85.exe_PATH%
%_VECHO% ToolPath = '%TOOLPATH%'
REM
REM NOTE: Check for MSVC 2012 because the Windows SDK directory handling is
REM slightly different for that version.
REM
IF "%VisualStudioVersion%" == "11.0" (
SET SET_NSDKLIBPATH=1
) ELSE (
CALL :fn_UnsetVariable SET_NSDKLIBPATH
)
REM
REM NOTE: This is the outer loop. There should be exactly one iteration per
REM platform.
REM
FOR %%P IN (%PLATFORMS%) DO (
REM
REM NOTE: Using the MSVC platform name, lookup the simpler platform name to
REM be used for the name of the platform-specific binary directory via
REM the environment variables setup earlier.
REM
CALL :fn_SetVariable %%P_NAME PLATFORMNAME
REM
REM NOTE: This is the inner loop. There should be exactly one iteration.
REM This loop is necessary because the PlatformName environment
REM variable was set above and that value is needed by some of the
REM commands contained in the inner loop. If these commands were
REM directly contained in the outer loop, the PlatformName environment
REM variable would be stuck with its initial empty value instead.
REM
FOR /F "tokens=2* delims==" %%D IN ('SET PLATFORMNAME') DO (
REM
REM NOTE: Attempt to clean the environment of all variables used by MSVC
REM and/or Visual Studio. This block may need to be updated in the
REM future to account for additional environment variables.
REM
CALL :fn_UnsetVariable DevEnvDir
CALL :fn_UnsetVariable ExtensionSdkDir
CALL :fn_UnsetVariable Framework35Version
CALL :fn_UnsetVariable FrameworkDir
CALL :fn_UnsetVariable FrameworkDir32
CALL :fn_UnsetVariable FrameworkVersion
CALL :fn_UnsetVariable FrameworkVersion32
CALL :fn_UnsetVariable FSHARPINSTALLDIR
CALL :fn_UnsetVariable INCLUDE
CALL :fn_UnsetVariable LIB
CALL :fn_UnsetVariable LIBPATH
CALL :fn_UnsetVariable Platform
REM CALL :fn_UnsetVariable VCINSTALLDIR
CALL :fn_UnsetVariable VSINSTALLDIR
CALL :fn_UnsetVariable WindowsSdkDir
CALL :fn_UnsetVariable WindowsSdkDir_35
CALL :fn_UnsetVariable WindowsSdkDir_old
REM
REM NOTE: Reset the PATH here to the absolute bare minimum required.
REM
SET PATH=%TOOLPATH%;%SystemRoot%\System32;%SystemRoot%
REM
REM NOTE: Launch a nested command shell to perform the following steps:
REM
REM 1. Setup the MSVC environment for this platform using the
REM official batch file.
REM
REM 2. Make sure that no stale build output files are present.
REM
REM 3. Build the "sqlite3.dll" and "sqlite3.lib" binaries for this
REM platform.
REM
REM 4. Copy the "sqlite3.dll" and "sqlite3.lib" binaries for this
REM platform to the platform-specific directory beneath the
REM binary directory.
REM
"%ComSpec%" /C (
REM
REM NOTE: Attempt to setup the MSVC environment for this platform.
REM
%__ECHO% CALL "%VCINSTALLDIR%\vcvarsall.bat" %%P
IF ERRORLEVEL 1 (
ECHO Failed to call "%VCINSTALLDIR%\vcvarsall.bat" for platform %%P.
GOTO errors
)
REM
REM NOTE: If this batch file is not running in "what-if" mode, check to
REM be sure we were actually able to setup the MSVC environment as
REM current versions of their official batch file do not set the
REM exit code upon failure.
REM
IF NOT DEFINED __ECHO (
IF NOT DEFINED WindowsSdkDir (
ECHO Cannot build, Windows SDK not found for platform %%P.
GOTO errors
)
)
REM
REM NOTE: When using MSVC 2012, the native SDK path cannot simply use
REM the "lib" sub-directory beneath the location specified in the
REM WindowsSdkDir environment variable because that location does
REM not actually contain the necessary library files for x86.
REM This must be done for each iteration because it relies upon
REM the WindowsSdkDir environment variable being set by the batch
REM file used to setup the MSVC environment.
REM
IF DEFINED SET_NSDKLIBPATH (
CALL :fn_SetVariable WindowsSdkDir NSDKLIBPATH
CALL :fn_AppendVariable NSDKLIBPATH \lib\win8\um\x86
)
REM
REM NOTE: Unless prevented from doing so, invoke NMAKE with the MSVC
REM makefile to clean any stale build output from previous
REM iterations of this loop and/or previous runs of this batch
REM file, etc.
REM
IF NOT DEFINED NOCLEAN (
%__ECHO% nmake -f Makefile.msc clean
IF ERRORLEVEL 1 (
ECHO Failed to clean for platform %%P.
GOTO errors
)
) ELSE (
REM
REM NOTE: Even when the cleaning step has been disabled, we still need
REM to remove the build output for the files we are specifically
REM wanting to build for each platform.
REM
%__ECHO% DEL /Q sqlite3.dll sqlite3.lib sqlite3.pdb
)
REM
REM NOTE: Invoke NMAKE with the MSVC makefile to build the "sqlite3.dll"
REM binary. The x86 compiler will be used to compile the native
REM command line tools needed during the build process itself.
REM Also, disable looking for and/or linking to the native Tcl
REM runtime library.
REM
%__ECHO% nmake -f Makefile.msc sqlite3.dll "NCC=""%VCINSTALLDIR%\bin\cl.exe""" USE_NATIVE_LIBPATHS=1 NO_TCL=1 %NMAKE_ARGS%
IF ERRORLEVEL 1 (
ECHO Failed to build "sqlite3.dll" for platform %%P.
GOTO errors
)
REM
REM NOTE: Copy the "sqlite3.dll" file to the platform-specific directory
REM beneath the binary directory.
REM
%__ECHO% XCOPY sqlite3.dll "%BINARYDIRECTORY%\%%D\" %FFLAGS% %DFLAGS%
IF ERRORLEVEL 1 (
ECHO Failed to copy "sqlite3.dll" to "%BINARYDIRECTORY%\%%D\".
GOTO errors
)
REM
REM NOTE: Copy the "sqlite3.lib" file to the platform-specific directory
REM beneath the binary directory.
REM
%__ECHO% XCOPY sqlite3.lib "%BINARYDIRECTORY%\%%D\" %FFLAGS% %DFLAGS%
IF ERRORLEVEL 1 (
ECHO Failed to copy "sqlite3.lib" to "%BINARYDIRECTORY%\%%D\".
GOTO errors
)
REM
REM NOTE: Copy the "sqlite3.pdb" file to the platform-specific directory
REM beneath the binary directory unless we are prevented from doing
REM so.
REM
IF NOT DEFINED NOSYMBOLS (
%__ECHO% XCOPY sqlite3.pdb "%BINARYDIRECTORY%\%%D\" %FFLAGS% %DFLAGS%
IF ERRORLEVEL 1 (
ECHO Failed to copy "sqlite3.pdb" to "%BINARYDIRECTORY%\%%D\".
GOTO errors
)
)
)
)
REM
REM NOTE: Handle any errors generated during the nested command shell.
REM
IF ERRORLEVEL 1 (
GOTO errors
)
)
REM
REM NOTE: Restore the saved current directory from the directory stack.
REM
%__ECHO2% POPD
IF ERRORLEVEL 1 (
ECHO Could not restore directory.
GOTO errors
)
REM
REM NOTE: If we get to this point, we have succeeded.
REM
GOTO no_errors
:fn_ResetErrorLevel
VERIFY > NUL
GOTO :EOF
:fn_SetErrorLevel
VERIFY MAYBE 2> NUL
GOTO :EOF
:fn_SetVariable
SETLOCAL
IF NOT DEFINED %1 GOTO :EOF
IF "%2" == "" GOTO :EOF
SET __ECHO_CMD=ECHO %%%1%%
FOR /F "delims=" %%V IN ('%__ECHO_CMD%') DO (
SET VALUE=%%V
)
ENDLOCAL && SET %2=%VALUE%
GOTO :EOF
:fn_UnsetVariable
IF NOT "%1" == "" (
SET %1=
CALL :fn_ResetErrorLevel
)
GOTO :EOF
:fn_AppendVariable
SET __ECHO_CMD=ECHO %%%1%%
IF DEFINED %1 (
FOR /F "delims=" %%V IN ('%__ECHO_CMD%') DO (
SET %1=%%V%~2
)
) ELSE (
SET %1=%~2
)
SET __ECHO_CMD=
CALL :fn_ResetErrorLevel
GOTO :EOF
:usage
ECHO.
ECHO Usage: %~nx0 ^<binaryDirectory^>
ECHO.
GOTO errors
:errors
CALL :fn_SetErrorLevel
ENDLOCAL
ECHO.
ECHO Failure, errors were encountered.
GOTO end_of_file
:no_errors
CALL :fn_ResetErrorLevel
ENDLOCAL
ECHO.
ECHO Success, no errors were encountered.
GOTO end_of_file
:end_of_file
%__ECHO% EXIT /B %ERRORLEVEL%

View File

@ -4021,12 +4021,14 @@ void ReportHeader(struct lemon *lemp)
else prefix = "";
in = file_open(lemp,".h","rb");
if( in ){
int nextChar;
for(i=1; i<lemp->nterminal && fgets(line,LINESIZE,in); i++){
sprintf(pattern,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i);
if( strcmp(line,pattern) ) break;
}
nextChar = fgetc(in);
fclose(in);
if( i==lemp->nterminal ){
if( i==lemp->nterminal && nextChar==EOF ){
/* No change in the file. Don't rewrite it. */
return;
}

View File

@ -100,7 +100,6 @@ foreach hdr {
opcodes.h
os_common.h
os.h
os_os2.h
pager.h
parse.h
pcache.h
@ -233,7 +232,6 @@ foreach file {
mem5.c
mutex.c
mutex_noop.c
mutex_os2.c
mutex_unix.c
mutex_w32.c
malloc.c
@ -244,7 +242,6 @@ foreach file {
hash.c
opcodes.c
os_os2.c
os_unix.c
os_win.c

View File

@ -104,7 +104,6 @@ foreach hdr {
opcodes.h
os_common.h
os.h
os_os2.h
pager.h
parse.h
pcache.h
@ -238,7 +237,6 @@ foreach file {
mem5.c
mutex.c
mutex_noop.c
mutex_os2.c
mutex_unix.c
mutex_w32.c
malloc.c
@ -249,7 +247,6 @@ foreach file {
hash.c
opcodes.c
os_os2.c
os_unix.c
os_win.c

View File

@ -61,7 +61,6 @@ foreach hdr {
opcodes.h
os_common.h
os.h
os_os2.h
pager.h
parse.h
sqlite3ext.h

419
tool/mkvsix.tcl Normal file
View File

@ -0,0 +1,419 @@
#!/usr/bin/tclsh
#
# This script is used to generate a VSIX (Visual Studio Extension) file for
# SQLite usable by Visual Studio.
proc fail { {error ""} {usage false} } {
if {[string length $error] > 0} then {
puts stdout $error
if {!$usage} then {exit 1}
}
puts stdout "usage:\
[file tail [info nameofexecutable]]\
[file tail [info script]] <binaryDirectory> \[sourceDirectory\]"
exit 1
}
proc getEnvironmentVariable { name } {
#
# NOTE: Returns the value of the specified environment variable or an empty
# string for environment variables that do not exist in the current
# process environment.
#
return [expr {[info exists ::env($name)] ? $::env($name) : ""}]
}
proc getTemporaryPath {} {
#
# NOTE: Returns the normalized path to the first temporary directory found
# in the typical set of environment variables used for that purpose
# or an empty string to signal a failure to locate such a directory.
#
set names [list]
foreach name [list TEMP TMP] {
lappend names [string toupper $name] [string tolower $name] \
[string totitle $name]
}
foreach name $names {
set value [getEnvironmentVariable $name]
if {[string length $value] > 0} then {
return [file normalize $value]
}
}
return ""
}
proc appendArgs { args } {
#
# NOTE: Returns all passed arguments joined together as a single string with
# no intervening spaces between arguments.
#
eval append result $args
}
proc readFile { fileName } {
#
# NOTE: Reads and returns the entire contents of the specified file, which
# may contain binary data.
#
set file_id [open $fileName RDONLY]
fconfigure $file_id -encoding binary -translation binary
set result [read $file_id]
close $file_id
return $result
}
proc writeFile { fileName data } {
#
# NOTE: Writes the entire contents of the specified file, which may contain
# binary data.
#
set file_id [open $fileName {WRONLY CREAT TRUNC}]
fconfigure $file_id -encoding binary -translation binary
puts -nonewline $file_id $data
close $file_id
return ""
}
proc substFile { fileName } {
#
# NOTE: Performs all Tcl command, variable, and backslash substitutions in
# the specified file and then re-writes the contents of that same file
# with the substituted data.
#
return [writeFile $fileName [uplevel 1 [list subst [readFile $fileName]]]]
}
proc replacePlatform { fileName platformName } {
#
# NOTE: Returns the specified file name containing the platform name instead
# of platform placeholder tokens.
#
return [string map [list <platform> $platformName] $fileName]
}
set script [file normalize [info script]]
if {[string length $script] == 0} then {
fail "script file currently being evaluated is unknown" true
}
set path [file dirname $script]
set rootName [file rootname [file tail $script]]
###############################################################################
#
# NOTE: Process and verify all the command line arguments.
#
set argc [llength $argv]
if {$argc != 1 && $argc != 2} then {fail}
set binaryDirectory [lindex $argv 0]
if {[string length $binaryDirectory] == 0} then {
fail "invalid binary directory"
}
if {![file exists $binaryDirectory] || \
![file isdirectory $binaryDirectory]} then {
fail "binary directory does not exist"
}
if {$argc == 2} then {
set sourceDirectory [lindex $argv 1]
} else {
#
# NOTE: Assume that the source directory is the parent directory of the one
# that contains this script file.
#
set sourceDirectory [file dirname $path]
}
if {[string length $sourceDirectory] == 0} then {
fail "invalid source directory"
}
if {![file exists $sourceDirectory] || \
![file isdirectory $sourceDirectory]} then {
fail "source directory does not exist"
}
###############################################################################
#
# NOTE: Evaluate the user-specific customizations file, if it exists.
#
set userFile [file join $path [appendArgs \
$rootName . $tcl_platform(user) .tcl]]
if {[file exists $userFile] && \
[file isfile $userFile]} then {
source $userFile
}
###############################################################################
set templateFile [file join $path win sqlite.vsix]
if {![file exists $templateFile] || \
![file isfile $templateFile]} then {
fail [appendArgs "template file \"" $templateFile "\" does not exist"]
}
set currentDirectory [pwd]
set outputFile [file join $currentDirectory sqlite-output.vsix]
if {[file exists $outputFile]} then {
fail [appendArgs "output file \"" $outputFile "\" already exists"]
}
###############################################################################
#
# NOTE: Make sure that a valid temporary directory exists.
#
set temporaryDirectory [getTemporaryPath]
if {[string length $temporaryDirectory] == 0 || \
![file exists $temporaryDirectory] || \
![file isdirectory $temporaryDirectory]} then {
fail "cannot locate a usable temporary directory"
}
#
# NOTE: Setup the staging directory to have a unique name inside of the
# configured temporary directory.
#
set stagingDirectory [file normalize [file join $temporaryDirectory \
[appendArgs $rootName . [pid]]]]
###############################################################################
#
# NOTE: Configure the external zipping tool. First, see if it has already
# been pre-configured. If not, try to query it from the environment.
# Finally, fallback on the default of simply "zip", which will then
# be assumed to exist somewhere along the PATH.
#
if {![info exists zip]} then {
if {[info exists env(ZipTool)]} then {
set zip $env(ZipTool)
}
if {![info exists zip] || ![file exists $zip]} then {
set zip zip
}
}
#
# NOTE: Configure the external unzipping tool. First, see if it has already
# been pre-configured. If not, try to query it from the environment.
# Finally, fallback on the default of simply "unzip", which will then
# be assumed to exist somewhere along the PATH.
#
if {![info exists unzip]} then {
if {[info exists env(UnZipTool)]} then {
set unzip $env(UnZipTool)
}
if {![info exists unzip] || ![file exists $unzip]} then {
set unzip unzip
}
}
###############################################################################
#
# NOTE: Attempt to extract the SQLite version from the "sqlite3.h" header file
# in the source directory. This script assumes that the header file has
# already been generated by the build process.
#
set pattern {^#define\s+SQLITE_VERSION\s+"(.*)"$}
set data [readFile [file join $sourceDirectory sqlite3.h]]
if {![regexp -line -- $pattern $data dummy version]} then {
fail [appendArgs "cannot locate SQLITE_VERSION value in \"" \
[file join $sourceDirectory sqlite3.h] \"]
}
###############################################################################
#
# NOTE: Setup the master file list data, including the necessary flags.
#
if {![info exists fileNames(source)]} then {
set fileNames(source) [list "" "" "" \
[file join $sourceDirectory sqlite3.h] \
[file join $binaryDirectory <platform> sqlite3.lib] \
[file join $binaryDirectory <platform> sqlite3.dll]]
if {![info exists no(symbols)]} then {
lappend fileNames(source) \
[file join $binaryDirectory <platform> sqlite3.pdb]
}
}
if {![info exists fileNames(destination)]} then {
set fileNames(destination) [list \
[file join $stagingDirectory extension.vsixmanifest] \
[file join $stagingDirectory SDKManifest.xml] \
[file join $stagingDirectory DesignTime CommonConfiguration \
<platform> SQLite.WinRT.props] \
[file join $stagingDirectory DesignTime CommonConfiguration \
<platform> sqlite3.h] \
[file join $stagingDirectory DesignTime CommonConfiguration \
<platform> sqlite3.lib] \
[file join $stagingDirectory Redist CommonConfiguration \
<platform> sqlite3.dll]]
if {![info exists no(symbols)]} then {
lappend fileNames(destination) \
[file join $stagingDirectory Redist Debug \
<platform> sqlite3.pdb]
}
}
if {![info exists fileNames(neutral)]} then {
set fileNames(neutral) [list 1 1 1 1 0 0]
if {![info exists no(symbols)]} then {
lappend fileNames(neutral) 0
}
}
if {![info exists fileNames(subst)]} then {
set fileNames(subst) [list 1 1 1 0 0 0]
if {![info exists no(symbols)]} then {
lappend fileNames(subst) 0
}
}
###############################################################################
#
# NOTE: Setup the list of platforms supported by this script.
#
if {![info exists platformNames]} then {
set platformNames [list x86 x64 ARM]
}
###############################################################################
#
# NOTE: Make sure the staging directory exists, creating it if necessary.
#
file mkdir $stagingDirectory
#
# NOTE: Build the Tcl command used to extract the template package to the
# staging directory.
#
set extractCommand [list exec -- $unzip $templateFile -d $stagingDirectory]
#
# NOTE: Extract the template package to the staging directory.
#
eval $extractCommand
###############################################################################
#
# NOTE: Process each file in the master file list. There are actually four
# parallel lists that contain the source file names, destination file
# names, the platform-neutral flags, and the use-subst flags. When the
# platform-neutral flag is non-zero, the file is not platform-specific.
# When the use-subst flag is non-zero, the file is considered to be a
# text file that may contain Tcl variable and/or command replacements,
# to be dynamically replaced during processing. If the source file name
# is an empty string, then the destination file name will be assumed to
# already exist in the staging directory and will not be copied; however,
# dynamic replacements may still be performed on the destination file
# prior to the package being re-zipped.
#
foreach sourceFileName $fileNames(source) \
destinationFileName $fileNames(destination) \
isNeutral $fileNames(neutral) useSubst $fileNames(subst) {
#
# NOTE: If the current file is platform-neutral, then only one platform will
# be processed for it, namely "neutral"; otherwise, each supported
# platform will be processed for it individually.
#
foreach platformName [expr {$isNeutral ? [list neutral] : $platformNames}] {
#
# NOTE: Use the actual platform name in the destination file name.
#
set newDestinationFileName [replacePlatform $destinationFileName \
$platformName]
#
# NOTE: Does the source file need to be copied to the destination file?
#
if {[string length $sourceFileName] > 0} then {
#
# NOTE: First, make sure the destination directory exists.
#
file mkdir [file dirname $newDestinationFileName]
#
# NOTE: Then, copy the source file to the destination file verbatim.
#
file copy [replacePlatform $sourceFileName $platformName] \
$newDestinationFileName
}
#
# NOTE: Does the destination file contain dynamic replacements that must
# be processed now?
#
if {$useSubst} then {
#
# NOTE: Perform any dynamic replacements contained in the destination
# file and then re-write it in-place.
#
substFile $newDestinationFileName
}
}
}
###############################################################################
#
# NOTE: Change the current directory to the staging directory so that the
# external archive building tool can pickup the necessary files using
# relative paths.
#
cd $stagingDirectory
#
# NOTE: Build the Tcl command used to archive the final package in the
# output directory.
#
set archiveCommand [list exec -- $zip -r $outputFile *]
#
# NOTE: Build the final package archive in the output directory.
#
eval $archiveCommand
#
# NOTE: Change back to the previously saved current directory.
#
cd $currentDirectory
#
# NOTE: Cleanup the temporary staging directory.
#
file delete -force $stagingDirectory
###############################################################################
#
# NOTE: Success, emit the fully qualified path of the generated VSIX file.
#
puts stdout $outputFile

View File

@ -53,8 +53,6 @@ proc run_quick_test {dir omit_symbol_list} {
if {$::tcl_platform(platform)=="windows"} {
append opts "OPTS += -DSQLITE_OS_WIN=1\n"
set target "testfixture.exe"
} elseif {$::tcl_platform(platform)=="os2"} {
append opts "OPTS += -DSQLITE_OS_OS2=1\n"
} else {
append opts "OPTS += -DSQLITE_OS_UNIX=1\n"
}
@ -93,7 +91,7 @@ proc run_quick_test {dir omit_symbol_list} {
# of trying to build the sqlite shell. The sqlite shell won't build
# with some of the OMIT options (i.e OMIT_COMPLETE).
set sqlite3_dummy $dir/sqlite3
if {$::tcl_platform(platform)=="windows" || $::tcl_platform(platform)=="os2"} {
if {$::tcl_platform(platform)=="windows"} {
append sqlite3_dummy ".exe"
}
if {![file exists $sqlite3_dummy]} {
@ -127,8 +125,8 @@ proc run_quick_test {dir omit_symbol_list} {
#
proc process_options {argv} {
set ::MAKEBIN make ;# Default value
if {$::tcl_platform(platform)=="windows" || $::tcl_platform(platform)=="os2"} {
set ::MAKEFILE ./Makefile ;# Default value on Windows and OS2
if {$::tcl_platform(platform)=="windows"} {
set ::MAKEFILE ./Makefile ;# Default value on Windows
} else {
set ::MAKEFILE ./Makefile.linux-gcc ;# Default value
}

BIN
tool/win/sqlite.vsix Normal file

Binary file not shown.