Merge all the latest trunk changes into the sessions branch.
FossilOrigin-Name: fc07a4795e027108674d1d41eb4350df629ddc8b
This commit is contained in:
commit
16de7f4d32
14
Makefile.in
14
Makefile.in
@ -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
|
||||
|
178
Makefile.msc
178
Makefile.msc
@ -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)
|
||||
|
@ -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 \
|
||||
|
40
configure
vendored
40
configure
vendored
@ -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
|
||||
|
||||
|
18
configure.ac
18
configure.ac
@ -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
|
||||
|
@ -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{
|
||||
|
@ -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;
|
||||
}
|
||||
|
8
main.mk
8
main.mk
@ -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
151
manifest
@ -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
|
||||
|
@ -1 +1 @@
|
||||
47f8f0711d63ef4166db9115db44b166959df14c
|
||||
fc07a4795e027108674d1d41eb4350df629ddc8b
|
@ -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;
|
||||
|
13
src/backup.c
13
src/backup.c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
30
src/btree.c
30
src/btree.c
@ -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;
|
||||
}
|
||||
|
@ -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*);
|
||||
|
@ -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 */
|
||||
|
@ -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. */
|
||||
|
@ -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;
|
||||
}
|
||||
|
13
src/func.c
13
src/func.c
@ -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;
|
||||
}
|
||||
|
@ -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) );
|
||||
|
12
src/insert.c
12
src/insert.c
@ -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);
|
||||
}
|
||||
|
||||
|
85
src/main.c
85
src/main.c
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
274
src/mutex_os2.c
274
src/mutex_os2.c
@ -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 */
|
@ -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 */
|
||||
|
30
src/os.h
30
src/os.h
@ -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
|
||||
|
1924
src/os_os2.c
1924
src/os_os2.c
File diff suppressed because it is too large
Load Diff
17
src/os_win.c
17
src/os_win.c
@ -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 },
|
||||
|
@ -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;
|
||||
|
16
src/pragma.c
16
src/pragma.c
@ -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);
|
||||
|
16
src/printf.c
16
src/printf.c
@ -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 ){
|
||||
|
117
src/select.c
117
src/select.c
@ -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.
|
||||
|
32
src/shell.c
32
src/shell.c
@ -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:";
|
||||
|
@ -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
|
||||
|
@ -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*);
|
||||
|
28
src/test8.c
28
src/test8.c
@ -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++){
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
1874
src/test_spellfix.c
1874
src/test_spellfix.c
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
|
@ -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; }
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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{
|
||||
|
438
src/vdbesort.c
438
src/vdbesort.c
@ -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 */
|
||||
){
|
||||
|
@ -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;
|
||||
|
11
src/wal.c
11
src/wal.c
@ -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
60
test/atof1.test
Normal 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
|
@ -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}
|
||||
|
@ -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
|
||||
|
@ -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) }
|
||||
} {}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
75
test/index5.test
Normal 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)]
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
95
test/securedel2.test
Normal 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
150
test/spellfix.test
Normal 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
|
@ -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 {
|
||||
|
@ -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]
|
||||
}
|
||||
|
127
test/walro.test
127
test/walro.test
@ -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
|
||||
|
||||
|
||||
|
@ -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
394
tool/build-all-msvc.bat
Executable 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%
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
419
tool/mkvsix.tcl
Normal 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
|
@ -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
BIN
tool/win/sqlite.vsix
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user