Compare commits
137 Commits
fts4-unicode
...
calloc
| Author | SHA1 | Date | |
|---|---|---|---|
| 97bc0873cc | |||
| 32e28c8ab6 | |||
| a785a59fb8 | |||
| cb2b9c8e19 | |||
| 5373b76bdc | |||
| 610b8d8578 | |||
| 206d0b6164 | |||
| 13a2bed309 | |||
| b4a553e7f0 | |||
| 5ad17e5d03 | |||
| 5885e76269 | |||
| 8512752407 | |||
| 2deb165f4b | |||
| bd58d5f7a3 | |||
| 228aeffb86 | |||
| e37f99cbef | |||
| 2f3de3232c | |||
| bbb0be8688 | |||
| 5afbd60a1d | |||
| ed68801b20 | |||
| 567520226a | |||
| 20b1ff0760 | |||
| f1c6bc5cd3 | |||
| c722a2c2e4 | |||
| 42c96dc8ff | |||
| d1b0afc30c | |||
| fe7b2bc9ff | |||
| 83905c905c | |||
| 8d967a90f8 | |||
| 3aaa4cd9ed | |||
| 2b434a7ec0 | |||
| 4aaf1552be | |||
| 4ef9413028 | |||
| 72b3fbc7b5 | |||
| 89f15088f0 | |||
| 2ae26b759d | |||
| 9721c21c41 | |||
| c8bde37d19 | |||
| 8ba0d1cbca | |||
| 4104337270 | |||
| 46daba87d3 | |||
| 4b8213d93c | |||
| 1c30debd41 | |||
| b6a69a66e5 | |||
| 155812d318 | |||
| 0b8dcfa2bd | |||
| 25cdf46ae4 | |||
| a879342b0e | |||
| 4bd6952a77 | |||
| 5e0c493860 | |||
| 617235b1a0 | |||
| cc71645bf7 | |||
| 2c897e3e5f | |||
| 754d3adf7c | |||
| f05305477c | |||
| a19b89627e | |||
| bae591a960 | |||
| 98c78ea63f | |||
| d3babb5220 | |||
| 401e9153e9 | |||
| 167cd6ab78 | |||
| 4245c405ea | |||
| 1e6eea9502 | |||
| ed46682719 | |||
| 1b28b89319 | |||
| 666a1d8d1e | |||
| d3d8c04fd1 | |||
| 51fec64f65 | |||
| 0e3037ac36 | |||
| 391d4bae36 | |||
| c6bff38216 | |||
| 7923863602 | |||
| 9cb7200815 | |||
| d97f3d7ae9 | |||
| 9c67b2aae0 | |||
| a9cfaba95a | |||
| 2bfcce45eb | |||
| d4e0bb0e65 | |||
| 4ab9d254e0 | |||
| 092a1ebd4c | |||
| afc8b7f0c1 | |||
| 86ab48fcfc | |||
| ba67e31752 | |||
| 4ec0100f35 | |||
| ca8b9bac3b | |||
| 5efb314525 | |||
| 81028a455d | |||
| bba02a95d9 | |||
| 882f87d826 | |||
| b60803f4b9 | |||
| fcd2f12fc7 | |||
| 3badf8a96d | |||
| 045f09cbb9 | |||
| c2f2d9280b | |||
| fec360acea | |||
| a749486e31 | |||
| a6ff857437 | |||
| 93416f1c83 | |||
| 05340e3257 | |||
| 46b721a294 | |||
| f39eaf29d0 | |||
| 428bef2e07 | |||
| 9917a71da0 | |||
| ca04d8a9f1 | |||
| 5593b2e653 | |||
| 86f89871b0 | |||
| e4c46aaccd | |||
| 40c471d921 | |||
| 16afb9ee96 | |||
| e8c9a184be | |||
| 0df898e27d | |||
| 25cf4fe988 | |||
| 184997c9a6 | |||
| a112d140ae | |||
| 5ff72401c9 | |||
| f4f327ce07 | |||
| 5cfbeac070 | |||
| df562d5535 | |||
| 776f5c96f4 | |||
| 6aa18c95f1 | |||
| 5483f772b1 | |||
| 4cdb9076d6 | |||
| 4a41f34552 | |||
| c548465435 | |||
| 9668e24e62 | |||
| 287a48d67b | |||
| 62d1924fc5 | |||
| 2a5cfb31fd | |||
| 75b70a2087 | |||
| d52ee7298e | |||
| 24560d16e9 | |||
| ee3a77de45 | |||
| 8045df0a7d | |||
| 7acec68a6e | |||
| cf3d7a4e13 | |||
| 11de93360f | |||
| 815aac8e0f |
+13
-13
@@ -165,14 +165,15 @@ LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
|
||||
backup.lo bitvec.lo btmutex.lo btree.lo build.lo \
|
||||
callback.lo complete.lo ctime.lo date.lo delete.lo \
|
||||
expr.lo fault.lo fkey.lo \
|
||||
fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo fts3_porter.lo \
|
||||
fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo fts3_write.lo \
|
||||
fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \
|
||||
fts3_porter.lo fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo \
|
||||
fts3_unicode.lo fts3_unicode2.lo fts3_write.lo \
|
||||
func.lo global.lo hash.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 \
|
||||
@@ -231,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 \
|
||||
@@ -317,6 +316,8 @@ SRC += \
|
||||
$(TOP)/ext/fts3/fts3_tokenizer.h \
|
||||
$(TOP)/ext/fts3/fts3_tokenizer.c \
|
||||
$(TOP)/ext/fts3/fts3_tokenizer1.c \
|
||||
$(TOP)/ext/fts3/fts3_unicode.c \
|
||||
$(TOP)/ext/fts3/fts3_unicode2.c \
|
||||
$(TOP)/ext/fts3/fts3_write.c
|
||||
SRC += \
|
||||
$(TOP)/ext/icu/sqliteicu.h \
|
||||
@@ -399,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 \
|
||||
@@ -654,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
|
||||
|
||||
@@ -684,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
|
||||
|
||||
@@ -856,6 +850,12 @@ fts3_tokenizer.lo: $(TOP)/ext/fts3/fts3_tokenizer.c $(HDR) $(EXTHDR)
|
||||
fts3_tokenizer1.lo: $(TOP)/ext/fts3/fts3_tokenizer1.c $(HDR) $(EXTHDR)
|
||||
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer1.c
|
||||
|
||||
fts3_unicode.lo: $(TOP)/ext/fts3/fts3_unicode.c $(HDR) $(EXTHDR)
|
||||
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode.c
|
||||
|
||||
fts3_unicode2.lo: $(TOP)/ext/fts3/fts3_unicode2.c $(HDR) $(EXTHDR)
|
||||
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode2.c
|
||||
|
||||
fts3_write.lo: $(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR)
|
||||
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c
|
||||
|
||||
|
||||
+162
-45
@@ -15,6 +15,21 @@ 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 to non-0 to create and use PDBs.
|
||||
#
|
||||
SYMBOLS = 1
|
||||
@@ -32,24 +47,104 @@ SYMBOLS = 1
|
||||
#
|
||||
DEBUG = 0
|
||||
|
||||
# Version numbers and release number for the SQLite being compiled.
|
||||
# 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'.
|
||||
#
|
||||
VERSION = 3.7
|
||||
VERSION_NUMBER = 3007009
|
||||
RELEASE = 3.7.9
|
||||
!IFNDEF CC
|
||||
CC = cl.exe
|
||||
!ENDIF
|
||||
|
||||
# C Compiler and options for use in building executables that
|
||||
# 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
|
||||
#
|
||||
!IFNDEF NCC
|
||||
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
|
||||
|
||||
# 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
|
||||
|
||||
# C compiler and options for use in building executables that
|
||||
# will run on the platform that is doing the build.
|
||||
#
|
||||
BCC = cl.exe
|
||||
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
|
||||
|
||||
# The mksqlite3c.tcl and mksqlite3h.tcl scripts will pull in
|
||||
# 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.
|
||||
#
|
||||
!IF $(FOR_WINRT)!=0
|
||||
TCC = $(TCC) -DSQLITE_OS_WINRT=1
|
||||
!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
|
||||
# any extension header files by default. For non-amalgamation
|
||||
# builds, we need to make sure the compiler can find these.
|
||||
#
|
||||
@@ -64,6 +159,7 @@ TCC = $(TCC) -I$(TOP)\ext\rtree
|
||||
#
|
||||
!IF $(DEBUG)==0
|
||||
TCC = $(TCC) -DNDEBUG
|
||||
BCC = $(BCC) -DNDEBUG
|
||||
!ENDIF
|
||||
|
||||
!IF $(DEBUG)>1
|
||||
@@ -79,9 +175,17 @@ 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?
|
||||
@@ -101,43 +205,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.
|
||||
#
|
||||
@@ -157,9 +261,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
|
||||
#
|
||||
@@ -194,12 +298,15 @@ TCC = $(TCC) $(OPTS)
|
||||
# If debugging is enabled, disable all optimizations and enable PDBs.
|
||||
!IF $(DEBUG)>0
|
||||
TCC = $(TCC) -Od -D_DEBUG
|
||||
BCC = $(BCC) -Od -D_DEBUG
|
||||
!ELSE
|
||||
TCC = $(TCC) -O2
|
||||
BCC = $(BCC) -O2
|
||||
!ENDIF
|
||||
|
||||
!IF $(DEBUG)>0 || $(SYMBOLS)!=0
|
||||
TCC = $(TCC) -Zi
|
||||
BCC = $(BCC) -Zi
|
||||
!ENDIF
|
||||
|
||||
# If ICU support is enabled, add the compiler options for it.
|
||||
@@ -218,14 +325,22 @@ 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
|
||||
|
||||
# If debugging is enabled, enable PDBs.
|
||||
# When compiling for use in the WinRT environment, the following
|
||||
# linker option must be used to mark the executable as runnable
|
||||
# only in the context of an application container.
|
||||
#
|
||||
!IF $(FOR_WINRT)!=0
|
||||
LTLINKOPTS = $(LTLINKOPTS) /APPCONTAINER
|
||||
!ENDIF
|
||||
|
||||
# If either debugging or symbols are enabled, enable PDBs.
|
||||
!IF $(DEBUG)>0 || $(SYMBOLS)!=0
|
||||
LTLINKOPTS = $(LTLINKOPTS) /DEBUG
|
||||
LDFLAGS = /DEBUG
|
||||
!ENDIF
|
||||
|
||||
# Start with the Tcl related linker options.
|
||||
@@ -250,14 +365,15 @@ LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
|
||||
backup.lo bitvec.lo btmutex.lo btree.lo build.lo \
|
||||
callback.lo complete.lo ctime.lo date.lo delete.lo \
|
||||
expr.lo fault.lo fkey.lo \
|
||||
fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo fts3_porter.lo \
|
||||
fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo fts3_write.lo \
|
||||
fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \
|
||||
fts3_porter.lo fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo \
|
||||
fts3_unicode.lo fts3_unicode2.lo fts3_write.lo \
|
||||
func.lo global.lo hash.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 \
|
||||
@@ -319,14 +435,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 \
|
||||
@@ -405,6 +519,8 @@ SRC = $(SRC) \
|
||||
$(TOP)\ext\fts3\fts3_tokenizer.h \
|
||||
$(TOP)\ext\fts3\fts3_tokenizer.c \
|
||||
$(TOP)\ext\fts3\fts3_tokenizer1.c \
|
||||
$(TOP)\ext\fts3\fts3_unicode.c \
|
||||
$(TOP)\ext\fts3\fts3_unicode2.c \
|
||||
$(TOP)\ext\fts3\fts3_write.c
|
||||
SRC = $(SRC) \
|
||||
$(TOP)\ext\icu\sqliteicu.h \
|
||||
@@ -486,7 +602,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 \
|
||||
@@ -512,6 +627,8 @@ TESTSRC2 = \
|
||||
$(TOP)\ext\fts3\fts3_aux.c \
|
||||
$(TOP)\ext\fts3\fts3_expr.c \
|
||||
$(TOP)\ext\fts3\fts3_tokenizer.c \
|
||||
$(TOP)\ext\fts3\fts3_unicode.c \
|
||||
$(TOP)\ext\fts3\fts3_unicode2.c \
|
||||
$(TOP)\ext\fts3\fts3_write.c \
|
||||
$(TOP)\ext\async\sqlite3async.c
|
||||
|
||||
@@ -607,7 +724,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:
|
||||
@@ -725,9 +842,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
|
||||
|
||||
@@ -755,9 +869,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
|
||||
|
||||
@@ -869,7 +980,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
|
||||
@@ -926,6 +1037,12 @@ fts3_tokenizer.lo: $(TOP)\ext\fts3\fts3_tokenizer.c $(HDR) $(EXTHDR)
|
||||
fts3_tokenizer1.lo: $(TOP)\ext\fts3\fts3_tokenizer1.c $(HDR) $(EXTHDR)
|
||||
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_tokenizer1.c
|
||||
|
||||
fts3_unicode.lo: $(TOP)\ext\fts3\fts3_unicode.c $(HDR) $(EXTHDR)
|
||||
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_unicode.c
|
||||
|
||||
fts3_unicode2.lo: $(TOP)\ext\fts3\fts3_unicode2.c $(HDR) $(EXTHDR)
|
||||
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_unicode2.c
|
||||
|
||||
fts3_write.lo: $(TOP)\ext\fts3\fts3_write.c $(HDR) $(EXTHDR)
|
||||
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_write.c
|
||||
|
||||
@@ -1008,4 +1125,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)
|
||||
|
||||
+3
-5
@@ -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 \
|
||||
|
||||
@@ -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.12.1.
|
||||
# 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.12.1'
|
||||
PACKAGE_STRING='sqlite 3.7.12.1'
|
||||
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.12.1 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.12.1:";;
|
||||
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.12.1
|
||||
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.12.1, 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 $@
|
||||
@@ -14032,7 +14032,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.12.1, 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 +14085,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.12.1
|
||||
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'`\\"
|
||||
|
||||
|
||||
+4
-4
@@ -3554,7 +3554,7 @@ static void hashDestroy(void *p){
|
||||
*/
|
||||
void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule);
|
||||
void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule);
|
||||
#ifndef SQLITE_DISABLE_FTS3_UNICODE
|
||||
#ifdef SQLITE_ENABLE_FTS4_UNICODE61
|
||||
void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const**ppModule);
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_ICU
|
||||
@@ -3572,7 +3572,7 @@ int sqlite3Fts3Init(sqlite3 *db){
|
||||
Fts3Hash *pHash = 0;
|
||||
const sqlite3_tokenizer_module *pSimple = 0;
|
||||
const sqlite3_tokenizer_module *pPorter = 0;
|
||||
#ifndef SQLITE_DISABLE_FTS3_UNICODE
|
||||
#ifdef SQLITE_ENABLE_FTS4_UNICODE61
|
||||
const sqlite3_tokenizer_module *pUnicode = 0;
|
||||
#endif
|
||||
|
||||
@@ -3581,7 +3581,7 @@ int sqlite3Fts3Init(sqlite3 *db){
|
||||
sqlite3Fts3IcuTokenizerModule(&pIcu);
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_DISABLE_FTS3_UNICODE
|
||||
#ifdef SQLITE_ENABLE_FTS4_UNICODE61
|
||||
sqlite3Fts3UnicodeTokenizer(&pUnicode);
|
||||
#endif
|
||||
|
||||
@@ -3609,7 +3609,7 @@ int sqlite3Fts3Init(sqlite3 *db){
|
||||
if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple)
|
||||
|| sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter)
|
||||
|
||||
#ifndef SQLITE_DISABLE_FTS3_UNICODE
|
||||
#ifdef SQLITE_ENABLE_FTS4_UNICODE61
|
||||
|| sqlite3Fts3HashInsert(pHash, "unicode61", 10, (void *)pUnicode)
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_ICU
|
||||
|
||||
+4
-1
@@ -542,8 +542,11 @@ int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr);
|
||||
int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *);
|
||||
|
||||
/* fts3_unicode2.c (functions generated by parsing unicode text files) */
|
||||
int sqlite3FtsUnicodeTolower(int);
|
||||
#ifdef SQLITE_ENABLE_FTS4_UNICODE61
|
||||
int sqlite3FtsUnicodeFold(int, int);
|
||||
int sqlite3FtsUnicodeIsalnum(int);
|
||||
int sqlite3FtsUnicodeIsdiacritic(int);
|
||||
#endif
|
||||
|
||||
#endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */
|
||||
#endif /* _FTSINT_H */
|
||||
|
||||
+1
-1
@@ -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{
|
||||
|
||||
+14
-14
@@ -209,10 +209,9 @@ int sqlite3Fts3InitTokenizer(
|
||||
/*
|
||||
** Implementation of a special SQL scalar function for testing tokenizers
|
||||
** designed to be used in concert with the Tcl testing framework. This
|
||||
** function must be called with two arguments:
|
||||
** function must be called with two or more arguments:
|
||||
**
|
||||
** SELECT <function-name>(<key-name>, <input-string>);
|
||||
** SELECT <function-name>(<key-name>, <pointer>);
|
||||
** SELECT <function-name>(<key-name>, ..., <input-string>);
|
||||
**
|
||||
** where <function-name> is the name passed as the second argument
|
||||
** to the sqlite3Fts3InitHashTable() function (e.g. 'fts3_tokenizer')
|
||||
@@ -249,27 +248,27 @@ static void testFunc(
|
||||
const char *zInput;
|
||||
int nInput;
|
||||
|
||||
const char *zArg = 0;
|
||||
const char *azArg[64];
|
||||
|
||||
const char *zToken;
|
||||
int nToken;
|
||||
int iStart;
|
||||
int iEnd;
|
||||
int iPos;
|
||||
int i;
|
||||
|
||||
Tcl_Obj *pRet;
|
||||
|
||||
assert( argc==2 || argc==3 );
|
||||
if( argc<2 ){
|
||||
sqlite3_result_error(context, "insufficient arguments", -1);
|
||||
return;
|
||||
}
|
||||
|
||||
nName = sqlite3_value_bytes(argv[0]);
|
||||
zName = (const char *)sqlite3_value_text(argv[0]);
|
||||
nInput = sqlite3_value_bytes(argv[argc-1]);
|
||||
zInput = (const char *)sqlite3_value_text(argv[argc-1]);
|
||||
|
||||
if( argc==3 ){
|
||||
zArg = (const char *)sqlite3_value_text(argv[1]);
|
||||
}
|
||||
|
||||
pHash = (Fts3Hash *)sqlite3_user_data(context);
|
||||
p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1);
|
||||
|
||||
@@ -283,7 +282,11 @@ static void testFunc(
|
||||
pRet = Tcl_NewObj();
|
||||
Tcl_IncrRefCount(pRet);
|
||||
|
||||
if( SQLITE_OK!=p->xCreate(zArg ? 1 : 0, &zArg, &pTokenizer) ){
|
||||
for(i=1; i<argc-1; i++){
|
||||
azArg[i-1] = (const char *)sqlite3_value_text(argv[i]);
|
||||
}
|
||||
|
||||
if( SQLITE_OK!=p->xCreate(argc-2, azArg, &pTokenizer) ){
|
||||
zErr = "error in xCreate()";
|
||||
goto finish;
|
||||
}
|
||||
@@ -467,10 +470,7 @@ int sqlite3Fts3InitHashTable(
|
||||
}
|
||||
#ifdef SQLITE_TEST
|
||||
if( SQLITE_OK==rc ){
|
||||
rc = sqlite3_create_function(db, zTest, 2, any, p, testFunc, 0, 0);
|
||||
}
|
||||
if( SQLITE_OK==rc ){
|
||||
rc = sqlite3_create_function(db, zTest, 3, any, p, testFunc, 0, 0);
|
||||
rc = sqlite3_create_function(db, zTest, -1, any, p, testFunc, 0, 0);
|
||||
}
|
||||
if( SQLITE_OK==rc ){
|
||||
rc = sqlite3_create_function(db, zTest2, 0, any, pdb, intTestFunc, 0, 0);
|
||||
|
||||
+168
-21
@@ -13,7 +13,7 @@
|
||||
** Implementation of the "unicode" full-text-search tokenizer.
|
||||
*/
|
||||
|
||||
#ifndef SQLITE_DISABLE_FTS3_UNICODE
|
||||
#ifdef SQLITE_ENABLE_FTS4_UNICODE61
|
||||
|
||||
#include "fts3Int.h"
|
||||
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
|
||||
@@ -82,6 +82,9 @@ typedef struct unicode_cursor unicode_cursor;
|
||||
|
||||
struct unicode_tokenizer {
|
||||
sqlite3_tokenizer base;
|
||||
int bRemoveDiacritic;
|
||||
int nException;
|
||||
int *aiException;
|
||||
};
|
||||
|
||||
struct unicode_cursor {
|
||||
@@ -94,6 +97,121 @@ struct unicode_cursor {
|
||||
int nAlloc; /* space allocated at zToken */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** Destroy a tokenizer allocated by unicodeCreate().
|
||||
*/
|
||||
static int unicodeDestroy(sqlite3_tokenizer *pTokenizer){
|
||||
if( pTokenizer ){
|
||||
unicode_tokenizer *p = (unicode_tokenizer *)pTokenizer;
|
||||
sqlite3_free(p->aiException);
|
||||
sqlite3_free(p);
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** As part of a tokenchars= or separators= option, the CREATE VIRTUAL TABLE
|
||||
** statement has specified that the tokenizer for this table shall consider
|
||||
** all characters in string zIn/nIn to be separators (if bAlnum==0) or
|
||||
** token characters (if bAlnum==1).
|
||||
**
|
||||
** For each codepoint in the zIn/nIn string, this function checks if the
|
||||
** sqlite3FtsUnicodeIsalnum() function already returns the desired result.
|
||||
** If so, no action is taken. Otherwise, the codepoint is added to the
|
||||
** unicode_tokenizer.aiException[] array. For the purposes of tokenization,
|
||||
** the return value of sqlite3FtsUnicodeIsalnum() is inverted for all
|
||||
** codepoints in the aiException[] array.
|
||||
**
|
||||
** If a standalone diacritic mark (one that sqlite3FtsUnicodeIsdiacritic()
|
||||
** identifies as a diacritic) occurs in the zIn/nIn string it is ignored.
|
||||
** It is not possible to change the behaviour of the tokenizer with respect
|
||||
** to these codepoints.
|
||||
*/
|
||||
static int unicodeAddExceptions(
|
||||
unicode_tokenizer *p, /* Tokenizer to add exceptions to */
|
||||
int bAlnum, /* Replace Isalnum() return value with this */
|
||||
const char *zIn, /* Array of characters to make exceptions */
|
||||
int nIn /* Length of z in bytes */
|
||||
){
|
||||
const unsigned char *z = (const unsigned char *)zIn;
|
||||
const unsigned char *zTerm = &z[nIn];
|
||||
int iCode;
|
||||
int nEntry = 0;
|
||||
|
||||
assert( bAlnum==0 || bAlnum==1 );
|
||||
|
||||
while( z<zTerm ){
|
||||
READ_UTF8(z, zTerm, iCode);
|
||||
assert( (sqlite3FtsUnicodeIsalnum(iCode) & 0xFFFFFFFE)==0 );
|
||||
if( sqlite3FtsUnicodeIsalnum(iCode)!=bAlnum
|
||||
&& sqlite3FtsUnicodeIsdiacritic(iCode)==0
|
||||
){
|
||||
nEntry++;
|
||||
}
|
||||
}
|
||||
|
||||
if( nEntry ){
|
||||
int *aNew; /* New aiException[] array */
|
||||
int nNew; /* Number of valid entries in array aNew[] */
|
||||
|
||||
aNew = sqlite3_realloc(p->aiException, (p->nException+nEntry)*sizeof(int));
|
||||
if( aNew==0 ) return SQLITE_NOMEM;
|
||||
nNew = p->nException;
|
||||
|
||||
z = (const unsigned char *)zIn;
|
||||
while( z<zTerm ){
|
||||
READ_UTF8(z, zTerm, iCode);
|
||||
if( sqlite3FtsUnicodeIsalnum(iCode)!=bAlnum
|
||||
&& sqlite3FtsUnicodeIsdiacritic(iCode)==0
|
||||
){
|
||||
int i, j;
|
||||
for(i=0; i<nNew && aNew[i]<iCode; i++);
|
||||
for(j=nNew; j>i; j--) aNew[j] = aNew[j-1];
|
||||
aNew[i] = iCode;
|
||||
nNew++;
|
||||
}
|
||||
}
|
||||
p->aiException = aNew;
|
||||
p->nException = nNew;
|
||||
}
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return true if the p->aiException[] array contains the value iCode.
|
||||
*/
|
||||
static int unicodeIsException(unicode_tokenizer *p, int iCode){
|
||||
if( p->nException>0 ){
|
||||
int *a = p->aiException;
|
||||
int iLo = 0;
|
||||
int iHi = p->nException-1;
|
||||
|
||||
while( iHi>=iLo ){
|
||||
int iTest = (iHi + iLo) / 2;
|
||||
if( iCode==a[iTest] ){
|
||||
return 1;
|
||||
}else if( iCode>a[iTest] ){
|
||||
iLo = iTest+1;
|
||||
}else{
|
||||
iHi = iTest-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return true if, for the purposes of tokenization, codepoint iCode is
|
||||
** considered a token character (not a separator).
|
||||
*/
|
||||
static int unicodeIsAlnum(unicode_tokenizer *p, int iCode){
|
||||
assert( (sqlite3FtsUnicodeIsalnum(iCode) & 0xFFFFFFFE)==0 );
|
||||
return sqlite3FtsUnicodeIsalnum(iCode) ^ unicodeIsException(p, iCode);
|
||||
}
|
||||
|
||||
/*
|
||||
** Create a new tokenizer instance.
|
||||
*/
|
||||
@@ -103,21 +221,42 @@ static int unicodeCreate(
|
||||
sqlite3_tokenizer **pp /* OUT: New tokenizer handle */
|
||||
){
|
||||
unicode_tokenizer *pNew; /* New tokenizer object */
|
||||
pNew = (unicode_tokenizer *) sqlite3_malloc(sizeof(unicode_tokenizer));
|
||||
if( pNew==NULL ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
memset(pNew, 0, sizeof(unicode_tokenizer));
|
||||
*pp = &pNew->base;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
int i;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
/*
|
||||
** Destroy a tokenizer allocated by unicodeCreate().
|
||||
*/
|
||||
static int unicodeDestroy(sqlite3_tokenizer *pTokenizer){
|
||||
sqlite3_free(pTokenizer);
|
||||
return SQLITE_OK;
|
||||
pNew = (unicode_tokenizer *) sqlite3_malloc(sizeof(unicode_tokenizer));
|
||||
if( pNew==NULL ) return SQLITE_NOMEM;
|
||||
memset(pNew, 0, sizeof(unicode_tokenizer));
|
||||
pNew->bRemoveDiacritic = 1;
|
||||
|
||||
for(i=0; rc==SQLITE_OK && i<nArg; i++){
|
||||
const char *z = azArg[i];
|
||||
int n = strlen(z);
|
||||
|
||||
if( n==19 && memcmp("remove_diacritics=1", z, 19)==0 ){
|
||||
pNew->bRemoveDiacritic = 1;
|
||||
}
|
||||
else if( n==19 && memcmp("remove_diacritics=0", z, 19)==0 ){
|
||||
pNew->bRemoveDiacritic = 0;
|
||||
}
|
||||
else if( n>=11 && memcmp("tokenchars=", z, 11)==0 ){
|
||||
rc = unicodeAddExceptions(pNew, 1, &z[11], n-11);
|
||||
}
|
||||
else if( n>=11 && memcmp("separators=", z, 11)==0 ){
|
||||
rc = unicodeAddExceptions(pNew, 0, &z[11], n-11);
|
||||
}
|
||||
else{
|
||||
/* Unrecognized argument */
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if( rc!=SQLITE_OK ){
|
||||
unicodeDestroy((sqlite3_tokenizer *)pNew);
|
||||
pNew = 0;
|
||||
}
|
||||
*pp = (sqlite3_tokenizer *)pNew;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -170,14 +309,15 @@ static int unicodeClose(sqlite3_tokenizer_cursor *pCursor){
|
||||
** have been opened by a prior call to simpleOpen().
|
||||
*/
|
||||
static int unicodeNext(
|
||||
sqlite3_tokenizer_cursor *p, /* Cursor returned by simpleOpen */
|
||||
sqlite3_tokenizer_cursor *pC, /* Cursor returned by simpleOpen */
|
||||
const char **paToken, /* OUT: Token text */
|
||||
int *pnToken, /* OUT: Number of bytes at *paToken */
|
||||
int *piStart, /* OUT: Starting offset of token */
|
||||
int *piEnd, /* OUT: Ending offset of token */
|
||||
int *piPos /* OUT: Position integer of token */
|
||||
){
|
||||
unicode_cursor *pCsr = (unicode_cursor *)p;
|
||||
unicode_cursor *pCsr = (unicode_cursor *)pC;
|
||||
unicode_tokenizer *p = ((unicode_tokenizer *)pCsr->base.pTokenizer);
|
||||
int iCode;
|
||||
char *zOut;
|
||||
const unsigned char *z = &pCsr->aInput[pCsr->iOff];
|
||||
@@ -190,13 +330,15 @@ static int unicodeNext(
|
||||
** the input. */
|
||||
while( z<zTerm ){
|
||||
READ_UTF8(z, zTerm, iCode);
|
||||
if( sqlite3FtsUnicodeIsalnum(iCode) ) break;
|
||||
if( unicodeIsAlnum(p, iCode) ) break;
|
||||
zStart = z;
|
||||
}
|
||||
if( zStart>=zTerm ) return SQLITE_DONE;
|
||||
|
||||
zOut = pCsr->zToken;
|
||||
do {
|
||||
int iOut;
|
||||
|
||||
/* Grow the output buffer if required. */
|
||||
if( (zOut-pCsr->zToken)>=(pCsr->nAlloc-4) ){
|
||||
char *zNew = sqlite3_realloc(pCsr->zToken, pCsr->nAlloc+64);
|
||||
@@ -208,12 +350,17 @@ static int unicodeNext(
|
||||
|
||||
/* Write the folded case of the last character read to the output */
|
||||
zEnd = z;
|
||||
WRITE_UTF8(zOut, sqlite3FtsUnicodeTolower(iCode));
|
||||
iOut = sqlite3FtsUnicodeFold(iCode, p->bRemoveDiacritic);
|
||||
if( iOut ){
|
||||
WRITE_UTF8(zOut, iOut);
|
||||
}
|
||||
|
||||
/* If the cursor is not at EOF, read the next character */
|
||||
if( z>=zTerm ) break;
|
||||
READ_UTF8(z, zTerm, iCode);
|
||||
}while( sqlite3FtsUnicodeIsalnum(iCode) );
|
||||
}while( unicodeIsAlnum(p, iCode)
|
||||
|| sqlite3FtsUnicodeIsdiacritic(iCode)
|
||||
);
|
||||
|
||||
/* Set the output variables and return. */
|
||||
pCsr->iOff = (z - pCsr->aInput);
|
||||
@@ -243,4 +390,4 @@ void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const **ppModule){
|
||||
}
|
||||
|
||||
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
|
||||
#endif /* ifndef SQLITE_DISABLE_FTS3_UNICODE */
|
||||
#endif /* ifndef SQLITE_ENABLE_FTS4_UNICODE61 */
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
** DO NOT EDIT THIS MACHINE GENERATED FILE.
|
||||
*/
|
||||
|
||||
#ifndef SQLITE_DISABLE_FTS3_UNICODE
|
||||
#if defined(SQLITE_ENABLE_FTS4_UNICODE61)
|
||||
#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
@@ -145,12 +146,80 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** If the argument is a codepoint corresponding to a lowercase letter
|
||||
** in the ASCII range with a diacritic added, return the codepoint
|
||||
** of the ASCII letter only. For example, if passed 235 - "LATIN
|
||||
** SMALL LETTER E WITH DIAERESIS" - return 65 ("LATIN SMALL LETTER
|
||||
** E"). The resuls of passing a codepoint that corresponds to an
|
||||
** uppercase letter are undefined.
|
||||
*/
|
||||
static int remove_diacritic(int c){
|
||||
unsigned short aDia[] = {
|
||||
0, 1797, 1848, 1859, 1891, 1928, 1940, 1995,
|
||||
2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286,
|
||||
2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732,
|
||||
2782, 2842, 2894, 2954, 2984, 3000, 3028, 3336,
|
||||
3456, 3696, 3712, 3728, 3744, 3896, 3912, 3928,
|
||||
3968, 4008, 4040, 4106, 4138, 4170, 4202, 4234,
|
||||
4266, 4296, 4312, 4344, 4408, 4424, 4472, 4504,
|
||||
6148, 6198, 6264, 6280, 6360, 6429, 6505, 6529,
|
||||
61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726,
|
||||
61784, 61800, 61836, 61880, 61914, 61948, 61998, 62122,
|
||||
62154, 62200, 62218, 62302, 62364, 62442, 62478, 62536,
|
||||
62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730,
|
||||
62924, 63050, 63082, 63274, 63390,
|
||||
};
|
||||
char aChar[] = {
|
||||
'\0', 'a', 'c', 'e', 'i', 'n', 'o', 'u', 'y', 'y', 'a', 'c',
|
||||
'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r',
|
||||
's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o',
|
||||
'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r',
|
||||
'u', 's', 't', 'h', 'a', 'e', 'o', 'y', '\0', '\0', '\0', '\0',
|
||||
'\0', '\0', '\0', '\0', 'a', 'b', 'd', 'd', 'e', 'f', 'g', 'h',
|
||||
'h', 'i', 'k', 'l', 'l', 'm', 'n', 'p', 'r', 'r', 's', 't',
|
||||
'u', 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a',
|
||||
'e', 'i', 'o', 'u', 'y',
|
||||
};
|
||||
|
||||
unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
|
||||
int iRes = 0;
|
||||
int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1;
|
||||
int iLo = 0;
|
||||
while( iHi>=iLo ){
|
||||
int iTest = (iHi + iLo) / 2;
|
||||
if( key >= aDia[iTest] ){
|
||||
iRes = iTest;
|
||||
iLo = iTest+1;
|
||||
}else{
|
||||
iHi = iTest-1;
|
||||
}
|
||||
}
|
||||
assert( key>=aDia[iRes] );
|
||||
return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** Return true if the argument interpreted as a unicode codepoint
|
||||
** is a diacritical modifier character.
|
||||
*/
|
||||
int sqlite3FtsUnicodeIsdiacritic(int c){
|
||||
unsigned int mask0 = 0x08029FDF;
|
||||
unsigned int mask1 = 0x000361F8;
|
||||
if( c<768 || c>817 ) return 0;
|
||||
return (c < 768+32) ?
|
||||
(mask0 & (1 << (c-768))) :
|
||||
(mask1 & (1 << (c-768-32)));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Interpret the argument as a unicode codepoint. If the codepoint
|
||||
** is an upper case character that has a lower case equivalent,
|
||||
@@ -160,7 +229,7 @@ int sqlite3FtsUnicodeIsalnum(int c){
|
||||
** The results are undefined if the value passed to this function
|
||||
** is less than zero.
|
||||
*/
|
||||
int sqlite3FtsUnicodeTolower(int c){
|
||||
int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
|
||||
/* Each entry in the following array defines a rule for folding a range
|
||||
** of codepoints to lower case. The rule applies to a range of nRange
|
||||
** codepoints starting at codepoint iCode.
|
||||
@@ -283,6 +352,8 @@ int sqlite3FtsUnicodeTolower(int c){
|
||||
assert( ret>0 );
|
||||
}
|
||||
}
|
||||
|
||||
if( bRemoveDiacritic ) ret = remove_diacritic(ret);
|
||||
}
|
||||
|
||||
else if( c>=66560 && c<66600 ){
|
||||
@@ -291,4 +362,5 @@ int sqlite3FtsUnicodeTolower(int c){
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* ifndef SQLITE_DISABLE_FTS3_UNICODE */
|
||||
#endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */
|
||||
#endif /* !defined(SQLITE_ENABLE_FTS4_UNICODE61) */
|
||||
|
||||
@@ -136,7 +136,8 @@ struct Fts3DeferredToken {
|
||||
*/
|
||||
struct Fts3SegReader {
|
||||
int iIdx; /* Index within level, or 0x7FFFFFFF for PT */
|
||||
int bLookup; /* True for a lookup only */
|
||||
u8 bLookup; /* True for a lookup only */
|
||||
u8 rootOnly; /* True for a root-only reader */
|
||||
|
||||
sqlite3_int64 iStartBlock; /* Rowid of first leaf block to traverse */
|
||||
sqlite3_int64 iLeafEndBlock; /* Rowid of final leaf block to traverse */
|
||||
@@ -170,7 +171,7 @@ struct Fts3SegReader {
|
||||
};
|
||||
|
||||
#define fts3SegReaderIsPending(p) ((p)->ppNextElem!=0)
|
||||
#define fts3SegReaderIsRootOnly(p) ((p)->aNode==(char *)&(p)[1])
|
||||
#define fts3SegReaderIsRootOnly(p) ((p)->rootOnly!=0)
|
||||
|
||||
/*
|
||||
** An instance of this structure is used to create a segment b-tree in the
|
||||
@@ -1581,7 +1582,7 @@ int sqlite3Fts3SegReaderNew(
|
||||
}
|
||||
memset(pReader, 0, sizeof(Fts3SegReader));
|
||||
pReader->iIdx = iAge;
|
||||
pReader->bLookup = bLookup;
|
||||
pReader->bLookup = bLookup!=0;
|
||||
pReader->iStartBlock = iStartLeaf;
|
||||
pReader->iLeafEndBlock = iEndLeaf;
|
||||
pReader->iEndBlock = iEndBlock;
|
||||
@@ -1589,6 +1590,7 @@ int sqlite3Fts3SegReaderNew(
|
||||
if( nExtra ){
|
||||
/* The entire segment is stored in the root node. */
|
||||
pReader->aNode = (char *)&pReader[1];
|
||||
pReader->rootOnly = 1;
|
||||
pReader->nNode = nRoot;
|
||||
memcpy(pReader->aNode, zRoot, nRoot);
|
||||
memset(&pReader->aNode[nRoot], 0, FTS3_NODE_PADDING);
|
||||
|
||||
+255
-20
@@ -1,4 +1,208 @@
|
||||
|
||||
#
|
||||
# Parameter $zName must be a path to the file UnicodeData.txt. This command
|
||||
# reads the file and returns a list of mappings required to remove all
|
||||
# diacritical marks from a unicode string. Each mapping is itself a list
|
||||
# consisting of two elements - the unicode codepoint and the single ASCII
|
||||
# character that it should be replaced with, or an empty string if the
|
||||
# codepoint should simply be removed from the input. Examples:
|
||||
#
|
||||
# { 224 a } (replace codepoint 224 to "a")
|
||||
# { 769 "" } (remove codepoint 769 from input)
|
||||
#
|
||||
# Mappings are only returned for non-upper case codepoints. It is assumed
|
||||
# that the input has already been folded to lower case.
|
||||
#
|
||||
proc rd_load_unicodedata_text {zName} {
|
||||
global tl_lookup_table
|
||||
|
||||
set fd [open $zName]
|
||||
set lField {
|
||||
code
|
||||
character_name
|
||||
general_category
|
||||
canonical_combining_classes
|
||||
bidirectional_category
|
||||
character_decomposition_mapping
|
||||
decimal_digit_value
|
||||
digit_value
|
||||
numeric_value
|
||||
mirrored
|
||||
unicode_1_name
|
||||
iso10646_comment_field
|
||||
uppercase_mapping
|
||||
lowercase_mapping
|
||||
titlecase_mapping
|
||||
}
|
||||
set lRet [list]
|
||||
|
||||
while { ![eof $fd] } {
|
||||
set line [gets $fd]
|
||||
if {$line == ""} continue
|
||||
|
||||
set fields [split $line ";"]
|
||||
if {[llength $fields] != [llength $lField]} { error "parse error: $line" }
|
||||
foreach $lField $fields {}
|
||||
if { [llength $character_decomposition_mapping]!=2
|
||||
|| [string is xdigit [lindex $character_decomposition_mapping 0]]==0
|
||||
} {
|
||||
continue
|
||||
}
|
||||
|
||||
set iCode [expr "0x$code"]
|
||||
set iAscii [expr "0x[lindex $character_decomposition_mapping 0]"]
|
||||
set iDia [expr "0x[lindex $character_decomposition_mapping 1]"]
|
||||
|
||||
if {[info exists tl_lookup_table($iCode)]} continue
|
||||
|
||||
if { ($iAscii >= 97 && $iAscii <= 122)
|
||||
|| ($iAscii >= 65 && $iAscii <= 90)
|
||||
} {
|
||||
lappend lRet [list $iCode [string tolower [format %c $iAscii]]]
|
||||
set dia($iDia) 1
|
||||
}
|
||||
}
|
||||
|
||||
foreach d [array names dia] {
|
||||
lappend lRet [list $d ""]
|
||||
}
|
||||
set lRet [lsort -integer -index 0 $lRet]
|
||||
|
||||
close $fd
|
||||
set lRet
|
||||
}
|
||||
|
||||
|
||||
proc print_rd {map} {
|
||||
global tl_lookup_table
|
||||
set aChar [list]
|
||||
set lRange [list]
|
||||
|
||||
set nRange 1
|
||||
set iFirst [lindex $map 0 0]
|
||||
set cPrev [lindex $map 0 1]
|
||||
|
||||
foreach m [lrange $map 1 end] {
|
||||
foreach {i c} $m {}
|
||||
|
||||
if {$cPrev == $c} {
|
||||
for {set j [expr $iFirst+$nRange]} {$j<$i} {incr j} {
|
||||
if {[info exists tl_lookup_table($j)]==0} break
|
||||
}
|
||||
|
||||
if {$j==$i} {
|
||||
set nNew [expr {(1 + $i - $iFirst)}]
|
||||
if {$nNew<=8} {
|
||||
set nRange $nNew
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lappend lRange [list $iFirst $nRange]
|
||||
lappend aChar $cPrev
|
||||
|
||||
set iFirst $i
|
||||
set cPrev $c
|
||||
set nRange 1
|
||||
}
|
||||
lappend lRange [list $iFirst $nRange]
|
||||
lappend aChar $cPrev
|
||||
|
||||
puts "/*"
|
||||
puts "** If the argument is a codepoint corresponding to a lowercase letter"
|
||||
puts "** in the ASCII range with a diacritic added, return the codepoint"
|
||||
puts "** of the ASCII letter only. For example, if passed 235 - \"LATIN"
|
||||
puts "** SMALL LETTER E WITH DIAERESIS\" - return 65 (\"LATIN SMALL LETTER"
|
||||
puts "** E\"). The resuls of passing a codepoint that corresponds to an"
|
||||
puts "** uppercase letter are undefined."
|
||||
puts "*/"
|
||||
puts "static int remove_diacritic(int c)\{"
|
||||
puts " unsigned short aDia\[\] = \{"
|
||||
puts -nonewline " 0, "
|
||||
set i 1
|
||||
foreach r $lRange {
|
||||
foreach {iCode nRange} $r {}
|
||||
if {($i % 8)==0} {puts "" ; puts -nonewline " " }
|
||||
incr i
|
||||
|
||||
puts -nonewline [format "%5d" [expr ($iCode<<3) + $nRange-1]]
|
||||
puts -nonewline ", "
|
||||
}
|
||||
puts ""
|
||||
puts " \};"
|
||||
puts " char aChar\[\] = \{"
|
||||
puts -nonewline " '\\0', "
|
||||
set i 1
|
||||
foreach c $aChar {
|
||||
set str "'$c', "
|
||||
if {$c == ""} { set str "'\\0', " }
|
||||
|
||||
if {($i % 12)==0} {puts "" ; puts -nonewline " " }
|
||||
incr i
|
||||
puts -nonewline "$str"
|
||||
}
|
||||
puts ""
|
||||
puts " \};"
|
||||
puts {
|
||||
unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
|
||||
int iRes = 0;
|
||||
int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1;
|
||||
int iLo = 0;
|
||||
while( iHi>=iLo ){
|
||||
int iTest = (iHi + iLo) / 2;
|
||||
if( key >= aDia[iTest] ){
|
||||
iRes = iTest;
|
||||
iLo = iTest+1;
|
||||
}else{
|
||||
iHi = iTest-1;
|
||||
}
|
||||
}
|
||||
assert( key>=aDia[iRes] );
|
||||
return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]);}
|
||||
puts "\};"
|
||||
}
|
||||
|
||||
proc print_isdiacritic {zFunc map} {
|
||||
|
||||
set lCode [list]
|
||||
foreach m $map {
|
||||
foreach {code char} $m {}
|
||||
if {$code && $char == ""} { lappend lCode $code }
|
||||
}
|
||||
set lCode [lsort -integer $lCode]
|
||||
set iFirst [lindex $lCode 0]
|
||||
set iLast [lindex $lCode end]
|
||||
|
||||
set i1 0
|
||||
set i2 0
|
||||
|
||||
foreach c $lCode {
|
||||
set i [expr $c - $iFirst]
|
||||
if {$i < 32} {
|
||||
set i1 [expr {$i1 | (1<<$i)}]
|
||||
} else {
|
||||
set i2 [expr {$i2 | (1<<($i-32))}]
|
||||
}
|
||||
}
|
||||
|
||||
puts "/*"
|
||||
puts "** Return true if the argument interpreted as a unicode codepoint"
|
||||
puts "** is a diacritical modifier character."
|
||||
puts "*/"
|
||||
puts "int ${zFunc}\(int c)\{"
|
||||
puts " unsigned int mask0 = [format "0x%08X" $i1];"
|
||||
puts " unsigned int mask1 = [format "0x%08X" $i2];"
|
||||
|
||||
puts " if( c<$iFirst || c>$iLast ) return 0;"
|
||||
puts " return (c < $iFirst+32) ?"
|
||||
puts " (mask0 & (1 << (c-$iFirst))) :"
|
||||
puts " (mask1 & (1 << (c-$iFirst-32)));"
|
||||
puts "\}"
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
# Parameter $zName must be a path to the file UnicodeData.txt. This command
|
||||
# reads the file and returns a list of codepoints (integers). The list
|
||||
@@ -393,7 +597,7 @@ proc tl_print_ioff_table {liOff} {
|
||||
|
||||
}
|
||||
|
||||
proc print_tolower {zFunc} {
|
||||
proc print_fold {zFunc} {
|
||||
|
||||
set lRecord [tl_create_records]
|
||||
|
||||
@@ -407,7 +611,7 @@ proc print_tolower {zFunc} {
|
||||
puts "** The results are undefined if the value passed to this function"
|
||||
puts "** is less than zero."
|
||||
puts "*/"
|
||||
puts "int ${zFunc}\(int c)\{"
|
||||
puts "int ${zFunc}\(int c, int bRemoveDiacritic)\{"
|
||||
|
||||
set liOff [tl_generate_ioff_table $lRecord]
|
||||
tl_print_table_header
|
||||
@@ -451,6 +655,8 @@ proc print_tolower {zFunc} {
|
||||
assert( ret>0 );
|
||||
}
|
||||
}
|
||||
|
||||
if( bRemoveDiacritic ) ret = remove_diacritic(ret);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,22 +669,38 @@ proc print_tolower {zFunc} {
|
||||
puts "\}"
|
||||
}
|
||||
|
||||
proc print_tolower_test {zFunc} {
|
||||
proc print_fold_test {zFunc mappings} {
|
||||
global tl_lookup_table
|
||||
|
||||
puts "static int tolower_test(int *piCode)\{"
|
||||
foreach m $mappings {
|
||||
set c [lindex $m 1]
|
||||
if {$c == ""} {
|
||||
set extra([lindex $m 0]) 0
|
||||
} else {
|
||||
scan $c %c i
|
||||
set extra([lindex $m 0]) $i
|
||||
}
|
||||
}
|
||||
|
||||
puts "static int fold_test(int *piCode)\{"
|
||||
puts -nonewline " static int aLookup\[\] = \{"
|
||||
for {set i 0} {$i < 70000} {incr i} {
|
||||
|
||||
set expected $i
|
||||
catch { set expected $tl_lookup_table($i) }
|
||||
if {($i % 8)==0} { puts "" ; puts -nonewline " " }
|
||||
puts -nonewline "$expected, "
|
||||
set expected2 $expected
|
||||
catch { set expected2 $extra($expected2) }
|
||||
|
||||
if {($i % 4)==0} { puts "" ; puts -nonewline " " }
|
||||
puts -nonewline "$expected, $expected2, "
|
||||
}
|
||||
puts " \};"
|
||||
puts " int i;"
|
||||
puts " for(i=0; i<sizeof(aLookup)/sizeof(aLookup\[0\]); i++)\{"
|
||||
puts " if( ${zFunc}\(i)!=aLookup\[i\] )\{"
|
||||
puts " *piCode = i;"
|
||||
puts " int iCode = (i/2);"
|
||||
puts " int bFlag = i & 0x0001;"
|
||||
puts " if( ${zFunc}\(iCode, bFlag)!=aLookup\[i\] )\{"
|
||||
puts " *piCode = iCode;"
|
||||
puts " return 1;"
|
||||
puts " \}"
|
||||
puts " \}"
|
||||
@@ -507,7 +729,8 @@ proc print_fileheader {} {
|
||||
*/
|
||||
}]
|
||||
puts ""
|
||||
puts "#ifndef SQLITE_DISABLE_FTS3_UNICODE"
|
||||
puts "#if !defined(SQLITE_DISABLE_FTS3_UNICODE)"
|
||||
puts "#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)"
|
||||
puts ""
|
||||
puts "#include <assert.h>"
|
||||
puts ""
|
||||
@@ -523,9 +746,9 @@ proc print_test_main {} {
|
||||
puts " r1 = isalnum_test(&code);"
|
||||
puts " if( r1 ) printf(\"isalnum(): Problem with code %d\\n\",code);"
|
||||
puts " else printf(\"isalnum(): test passed\\n\");"
|
||||
puts " r2 = tolower_test(&code);"
|
||||
puts " if( r2 ) printf(\"tolower(): Problem with code %d\\n\",code);"
|
||||
puts " else printf(\"tolower(): test passed\\n\");"
|
||||
puts " r2 = fold_test(&code);"
|
||||
puts " if( r2 ) printf(\"fold(): Problem with code %d\\n\",code);"
|
||||
puts " else printf(\"fold(): test passed\\n\");"
|
||||
puts " return (r1 || r2);"
|
||||
puts "\}"
|
||||
}
|
||||
@@ -534,7 +757,7 @@ proc print_test_main {} {
|
||||
# our liking.
|
||||
#
|
||||
proc usage {} {
|
||||
puts -nonewline stderr "Usage: $::argv0 ?-test? i"
|
||||
puts -nonewline stderr "Usage: $::argv0 ?-test? "
|
||||
puts stderr "<CaseFolding.txt file> <UnicodeData.txt file>"
|
||||
exit 1
|
||||
}
|
||||
@@ -544,9 +767,10 @@ set unicodedata.txt [lindex $argv end]
|
||||
set casefolding.txt [lindex $argv end-1]
|
||||
set generate_test_code [expr {[llength $argv]==3}]
|
||||
|
||||
print_fileheader
|
||||
|
||||
# Print the isalnum() function to stdout.
|
||||
#
|
||||
print_fileheader
|
||||
set lRange [an_load_separator_ranges]
|
||||
print_isalnum sqlite3FtsUnicodeIsalnum $lRange
|
||||
|
||||
@@ -555,19 +779,30 @@ print_isalnum sqlite3FtsUnicodeIsalnum $lRange
|
||||
puts ""
|
||||
puts ""
|
||||
|
||||
# Print the tolower() function to stdout.
|
||||
#
|
||||
# Load the fold data. This is used by the [rd_XXX] commands
|
||||
# as well as [print_fold].
|
||||
tl_load_casefolding_txt ${casefolding.txt}
|
||||
print_tolower sqlite3FtsUnicodeTolower
|
||||
|
||||
set mappings [rd_load_unicodedata_text ${unicodedata.txt}]
|
||||
print_rd $mappings
|
||||
puts ""
|
||||
puts ""
|
||||
print_isdiacritic sqlite3FtsUnicodeIsdiacritic $mappings
|
||||
puts ""
|
||||
puts ""
|
||||
|
||||
# Print the fold() function to stdout.
|
||||
#
|
||||
print_fold sqlite3FtsUnicodeFold
|
||||
|
||||
# Print the test routines and main() function to stdout, if -test
|
||||
# was specified.
|
||||
#
|
||||
if {$::generate_test_code} {
|
||||
print_test_isalnum sqlite3FtsUnicodeIsalnum $lRange
|
||||
print_tolower_test sqlite3FtsUnicodeTolower
|
||||
print_fold_test sqlite3FtsUnicodeFold $mappings
|
||||
print_test_main
|
||||
}
|
||||
|
||||
puts "#endif /* ifndef SQLITE_DISABLE_FTS3_UNICODE */"
|
||||
|
||||
puts "#endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */"
|
||||
puts "#endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */"
|
||||
|
||||
+32
-2
@@ -2739,6 +2739,36 @@ static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Rounding constants for float->double conversion.
|
||||
*/
|
||||
#define RNDTOWARDS (1.0 - 1.0/8388608.0) /* Round towards zero */
|
||||
#define RNDAWAY (1.0 + 1.0/8388608.0) /* Round away from zero */
|
||||
|
||||
#if !defined(SQLITE_RTREE_INT_ONLY)
|
||||
/*
|
||||
** Convert an sqlite3_value into an RtreeValue (presumably a float)
|
||||
** while taking care to round toward negative or positive, respectively.
|
||||
*/
|
||||
static RtreeValue rtreeValueDown(sqlite3_value *v){
|
||||
double d = sqlite3_value_double(v);
|
||||
float f = (float)d;
|
||||
if( f>d ){
|
||||
f = (float)(d*(d<0 ? RNDAWAY : RNDTOWARDS));
|
||||
}
|
||||
return f;
|
||||
}
|
||||
static RtreeValue rtreeValueUp(sqlite3_value *v){
|
||||
double d = sqlite3_value_double(v);
|
||||
float f = (float)d;
|
||||
if( f<d ){
|
||||
f = (float)(d*(d<0 ? RNDTOWARDS : RNDAWAY));
|
||||
}
|
||||
return f;
|
||||
}
|
||||
#endif /* !defined(SQLITE_RTREE_INT_ONLY) */
|
||||
|
||||
|
||||
/*
|
||||
** The xUpdate method for rtree module virtual tables.
|
||||
*/
|
||||
@@ -2775,8 +2805,8 @@ static int rtreeUpdate(
|
||||
#ifndef SQLITE_RTREE_INT_ONLY
|
||||
if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
|
||||
for(ii=0; ii<(pRtree->nDim*2); ii+=2){
|
||||
cell.aCoord[ii].f = (RtreeValue)sqlite3_value_double(azData[ii+3]);
|
||||
cell.aCoord[ii+1].f = (RtreeValue)sqlite3_value_double(azData[ii+4]);
|
||||
cell.aCoord[ii].f = rtreeValueDown(azData[ii+3]);
|
||||
cell.aCoord[ii+1].f = rtreeValueUp(azData[ii+4]);
|
||||
if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){
|
||||
rc = SQLITE_CONSTRAINT;
|
||||
goto constraint;
|
||||
|
||||
@@ -60,8 +60,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 \
|
||||
@@ -113,14 +113,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 \
|
||||
@@ -282,7 +280,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 \
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
C If\sSQLITE_DISABLE_FTS3_UNICODE\sis\sdefined,\sdo\snot\sbuild\sthe\s"unicode61"\stokenizer.
|
||||
D 2012-05-26T18:28:14.350
|
||||
C Further\stweaks\sto\smalloc\spaths.
|
||||
D 2012-07-19T20:27:14.139
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 2f37e468503dbe79d35c9f6dffcf3fae1ae9ec20
|
||||
F Makefile.in 8f6d858bf3df9978ba43df19985146a1173025e4
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
F Makefile.msc 7849a871b6cdb20fd51baee6bbe5965a03326be4
|
||||
F Makefile.vxworks 3b7fe7a0571fdadc61363ebc1b23732d2d6363ca
|
||||
F Makefile.msc 56ff0fcc3fc3b275aec7f6acb34b3c0526c684bc
|
||||
F Makefile.vxworks 879f034a64062a364b21000266bbd5bc6e0c19b9
|
||||
F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6
|
||||
F VERSION 1e25ebddd2ed5811c10bdabe914cd46d2dc38af8
|
||||
F VERSION a71848df48082f1d6585d4b0819d530fc455485d
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
F addopcodes.awk 17dc593f791f874d2c23a0f9360850ded0286531
|
||||
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
|
||||
@@ -15,7 +15,7 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
|
||||
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
|
||||
F config.h.in 0921066a13130082764ab4ab6456f7b5bebe56de
|
||||
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
|
||||
F configure faa04198b719ec9cb2166aa0b163558e9b8ddd77 x
|
||||
F configure 8f973617dbc3fca46d26104070b75c17ef70beb7 x
|
||||
F configure.ac 9ee886c21c095b3272137b1553ae416c8b8c8557
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/lemon.html 3091574143dd3415669b6745843ff8d011d33549
|
||||
@@ -55,35 +55,35 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
|
||||
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
|
||||
F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314
|
||||
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
|
||||
F ext/fts3/fts3.c 41824d0db7d244ca335ce98162df1244863a05c4
|
||||
F ext/fts3/fts3.c bb3107c0e420ea2e26e57050e84cdf0aeaafcd4f
|
||||
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
|
||||
F ext/fts3/fts3Int.h 7b163fa22e7a625c404c424f2779a4d7b14c14ad
|
||||
F ext/fts3/fts3Int.h 81115435f79248ac09017bc665aae27b410d651f
|
||||
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
|
||||
F ext/fts3/fts3_test.c 348f7d08cae05285794e23dc4fe8b8fdf66e264a
|
||||
F ext/fts3/fts3_tokenizer.c 3da7254a9881f7e270ab28e2004e0d22b3212bce
|
||||
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 76b6f6fe6e86acd75b08272502fae74a13cef310
|
||||
F ext/fts3/fts3_unicode2.c 46ff2289f52e661ef030b4aed4c9e5b6132b6ea9
|
||||
F ext/fts3/fts3_write.c 6a6391d6b01114f885e24e1f66bbc11ffba0e9e2
|
||||
F ext/fts3/fts3_unicode.c 49e36e6ba59f79e6bd6a8bfe434570fe48d20559
|
||||
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
|
||||
F ext/fts3/tool/fts3view.c 6cfc5b67a5f0e09c0d698f9fd012c784bfaa9197
|
||||
F ext/fts3/unicode/CaseFolding.txt 8c678ca52ecc95e16bc7afc2dbf6fc9ffa05db8c
|
||||
F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7
|
||||
F ext/fts3/unicode/mkunicode.tcl de64862abd50307c6e40622970eb9c8f2f14ed0e
|
||||
F ext/fts3/unicode/mkunicode.tcl 7a9bc018e2962abb79563c5a39fe581fcbf2f675
|
||||
F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9
|
||||
F ext/icu/icu.c eb9ae1d79046bd7871aa97ee6da51eb770134b5a
|
||||
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
|
||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||
F ext/rtree/rtree.c 73502e5336162fdc8f5d1c4bdd4ec6b1299c2f2a
|
||||
F ext/rtree/rtree.c d17aecb7a92762efa7b1f5d5fd7c88fd77d70827
|
||||
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
|
||||
F ext/rtree/rtree1.test e474a2b5eff231496dbd073fe67e5fbaf7f444c9
|
||||
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
|
||||
@@ -103,7 +103,7 @@ F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
|
||||
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F main.mk 84ed9c324cf0b8f4eb6f276553d1fd092b5ae0f4
|
||||
F main.mk d109a9342d1fe135d3900aca9f5563f9480a991d
|
||||
F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
|
||||
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
|
||||
F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac
|
||||
@@ -117,25 +117,25 @@ 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/attach.c 12c6957996908edc31c96d7c68d4942c2474405f
|
||||
F src/analyze.c 1f05d25f1fb11ba60f95b793e0922757f35355fd
|
||||
F src/attach.c 577bf5675b0c50495fc28549f2fcbdb1bac71143
|
||||
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
|
||||
F src/backup.c 6be23a344d3301ae38e92fddb3a33b91c309fce4
|
||||
F src/backup.c 5524df36810668b3b5a6de2d7e3910b98e721e33
|
||||
F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef
|
||||
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
|
||||
F src/btree.c df800f10896bc2ddaa1125c532d6e7a7b9efc532
|
||||
F src/btree.c f0b71054103cb77eb5e782088c16998ec4f06624
|
||||
F src/btree.h 48a013f8964f12d944d90e4700df47b72dd6d923
|
||||
F src/btreeInt.h 38a639c0542c29fe8331a221c4aed0cb8686249e
|
||||
F src/build.c 2bb2163bb1e69f59e9f36a9413079ead42fa1d2c
|
||||
F src/build.c 4357149e38f95d8034f58ee2c7013423321fa877
|
||||
F src/callback.c 0cb4228cdcd827dcc5def98fb099edcc9142dbcd
|
||||
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
||||
F src/ctime.c a9c26822515f81ec21588cbb482ca6724be02e33
|
||||
F src/ctime.c 500d019da966631ad957c37705642be87524463b
|
||||
F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
|
||||
F src/delete.c 4c20ea4f6213b3bc1c6a510586864b679946e05e
|
||||
F src/expr.c 06a7733d19dc725dc46ba51afd9feadb4b85d991
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5
|
||||
F src/func.c c6b3c94320253a35bda43fb69cc292618e3285d6
|
||||
F src/fkey.c 7d1ec22d7278486c7fe42da43cabfc2a5ed33647
|
||||
F src/func.c 18dfedfb857e100b05755a1b12e88b389f957879
|
||||
F src/global.c 4cfdca5cb0edd33c4d021baec4ede958cb2c793b
|
||||
F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af
|
||||
F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
|
||||
@@ -145,65 +145,63 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e
|
||||
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
|
||||
F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416
|
||||
F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d
|
||||
F src/main.c 91458c713e9b7f8dbc98d79e78f1150f0ca9c2a1
|
||||
F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6
|
||||
F src/main.c 6241183d894ff51a2049bd6bf246aea877d648b5
|
||||
F src/malloc.c 57121e3ef46431b95a73651f9b5653f96867e358
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c b3677415e69603d6a0e7c5410a1b3731d55beda1
|
||||
F src/mem1.c 7ed7d5cd9a6ec97cc881ea80d996f6a16e8b7426
|
||||
F src/mem2.c e307323e86b5da1853d7111b68fd6b84ad6f09cf
|
||||
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 5e54f3ba275bcb5d00248b8c23107df2e2f73e33
|
||||
F src/mutex_w32.c 32a9b3841e2d757355f0012b860b1bc5e01eafa0
|
||||
F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
|
||||
F src/os.c e1acdc09ff3ac2412945cca9766e2dcf4675f31c
|
||||
F src/os.h 59beba555b65a450bd1d804220532971d4299f60
|
||||
F src/os.h c2ebd26a68a4223fe170b003852b97d9e7211498
|
||||
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
||||
F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440
|
||||
F src/os_unix.c 424d46e0edab969293c2223f09923b2178171f47
|
||||
F src/os_win.c 412d6434133c7c81dc48b7702f3ea5e61c309e5c
|
||||
F src/pager.c bb5635dde0b152797836d1c72275284724bb563c
|
||||
F src/pager.h ef1eaf8593e78f73885c1dfac27ad83bee23bdc5
|
||||
F src/parse.y f29df90bd3adc64b33114ab1de9fb7768fcf2099
|
||||
F src/os_unix.c d7c96b5d140f550f07345870112fae5d7ef99757
|
||||
F src/os_win.c e3d3d3e26b65a35d4293d753137a58510bd3299b
|
||||
F src/pager.c e381c118b77dc22021a1a59d3fec24815e91df78
|
||||
F src/pager.h 8b8c9bc065a3c66769df8724dfdf492ee1aab3c5
|
||||
F src/parse.y 6548920e5a3ee92c6efc7007e30b03105850ca4c
|
||||
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
|
||||
F src/pcache.h 1b5dcc3dc8103d03e625b177023ee67764fa6b7c
|
||||
F src/pcache1.c b30b1c35908346ecc43d8d9d17f2ddf6817f8f60
|
||||
F src/pragma.c e708b3bb5704605816f617e0b1d63a5488060715
|
||||
F src/prepare.c 9a00a9612ebf80203fbb41f8a29ab8cb27a05f40
|
||||
F src/printf.c 7ffb4ebb8b341f67e049695ba031da717b3d2699
|
||||
F src/pcache1.c 2234d84f9c003d800a57f00f8535c91667fa4f6c
|
||||
F src/pragma.c 97f9357f0e7e5fb46a2519f14539550aa07db49f
|
||||
F src/prepare.c 33291b83cca285718048d219c67b8298501fa3a5
|
||||
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 4f4d4792f6fb00387c877af013cb09d955643f12
|
||||
F src/select.c 5c9f09de4ca3e12da17d1c5215b851ce3356891c
|
||||
F src/shell.c 076e1c90d594644f36027c8ecff9a392cf2d3a06
|
||||
F src/sqlite.h.in c660e2c8c5b5412d1ce51d58807353fa1dfdbee0
|
||||
F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
|
||||
F src/sqliteInt.h 97ccae71ae0a4e924dcb9fab14eb4fc4839790da
|
||||
F src/sqliteInt.h 42082771dfad5ccc5b46ad97bddfe2829a61eaef
|
||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||
F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208
|
||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||
F src/tclsqlite.c fe5406573e1527957e00dcaf51edd9d8bd31b918
|
||||
F src/test1.c a808bfa548a501b513579bdbaf83901c98e059c9
|
||||
F src/test1.c fc2acf0a2db517c8d19e5e55bda8e1237db77378
|
||||
F src/test2.c 4178056dd1e7d70f954ad8a1e3edb71a2a784daf
|
||||
F src/test3.c 3c3c2407fa6ec7a19e24ae23f7cb439d0275a60d
|
||||
F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7
|
||||
F src/test5.c a6d1ac55ac054d0b2b8f37b5e655b6c92645a013
|
||||
F src/test6.c 417e1e214734393c24a8ee80b41485a9c4169123
|
||||
F src/test7.c 2e0781754905c8adc3268d8f0967e7633af58843
|
||||
F src/test8.c 5ecbffe6712da81d5d10454e9d77d6c5bac95fe8
|
||||
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 47cd771250f09cdc6e12dda5bc71bc0b3abc96e2
|
||||
F src/test_config.c d2da9f1490c38d9b9cb52f399b6adb81d538273a
|
||||
F src/test_btree.c 5b89601dcb42a33ba8b820a6b763cc9cb48bac16
|
||||
F src/test_config.c 9b37587750f247186ebeb02a02e8f17c611d1866
|
||||
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
|
||||
@@ -218,38 +216,38 @@ 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 47cb7b606160ce8f603a7d47143dd1f74de09058
|
||||
F src/test_quota.h ee5da2ae7f84d1c8e0e0e2ab33f01d69f10259b5
|
||||
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 5ed989693d4040f4d343316c338e25c5a6a1f05d
|
||||
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 da6d0d982b11756c94c1760196355d33d03ff745
|
||||
F src/test_vfstrace.c 6b28adb2a0e8ecd0f2e3581482e1f658b11b4067
|
||||
F src/test_wholenumber.c 3d2b9ed1505c40ad5c5ca2ad16ae7a289d6cc251
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/tokenize.c 1e86210d3976717a19238ea7b047fac481fe8c12
|
||||
F src/tokenize.c a054f58de63c2d7f5ba69439ef7fc75e7f22c158
|
||||
F src/trigger.c ee7e178fb9188f44b532cebd449a7c1df90fb684
|
||||
F src/update.c d3076782c887c10e882996550345da9c4c9f9dea
|
||||
F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84
|
||||
F src/util.c 4f6cfad661b2e3454b0cdd5b1b9d39a54942d0e3
|
||||
F src/vacuum.c bfd53f9bd20a8fdb70b0fa8e77182b866875c0d8
|
||||
F src/vdbe.c e1d26b98288889c22f00cf4851ec351ee67ad8b9
|
||||
F src/util.c 0af2e515dc0dabacec931bca39525f6c3f1c5455
|
||||
F src/vacuum.c 587a52bb8833d7ac15af8916f25437e2575028bd
|
||||
F src/vdbe.c f5ad3c06dc3fe647097065829c013f3f1b9eadca
|
||||
F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb
|
||||
F src/vdbeInt.h 6ff4180a05683566a8835d12f7ec504b22932c82
|
||||
F src/vdbeapi.c 3662b6a468a2a4605a15dfab313baa6dff81ad91
|
||||
F src/vdbeaux.c d52c8a424fdd4b1d5cf1ac93cc7cd20da023ec5c
|
||||
F src/vdbeapi.c 88ea823bbcb4320f5a6607f39cd7c2d3cc4c26b1
|
||||
F src/vdbeaux.c dce80038c3c41f2680e5ab4dd0f7e0d8b7ff9071
|
||||
F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb
|
||||
F src/vdbemem.c cb55e84b8e2c15704968ee05f0fae25883299b74
|
||||
F src/vdbesort.c b25814d385895544ebc8118245c8311ded7f81c9
|
||||
F src/vdbetrace.c 79059ebd17b3c8545fab2a24253713e77e4ab392
|
||||
F src/vtab.c ae657b1c22cff43863458e768a44f915c07bc0e4
|
||||
F src/wal.c 7bb3ad807afc7973406c805d5157ec7a2f65e146
|
||||
F src/vtab.c bb8ea3a26608bb1357538a5d2fc72beba6638998
|
||||
F src/wal.c 9294df6f96aae5909ae1a9b733fd1e1b4736978b
|
||||
F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6
|
||||
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
|
||||
F src/where.c 24c7494d8875ead994b4dfe5461340c27fd424ca
|
||||
@@ -274,6 +272,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
|
||||
@@ -288,7 +287,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
|
||||
@@ -296,8 +295,8 @@ F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f
|
||||
F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f
|
||||
F test/bc_common.tcl 5c8689cc6d2fb44b7c0968ae4f85eb26d50022fa
|
||||
F test/between.test 16b1776c6323faadb097a52d673e8e3d8be7d070
|
||||
F test/bigfile.test 82dfe93ee7eb9e2e05641afa2b39ffd947a92ff1
|
||||
F test/bigfile2.test 852f948cb492aadab45b58f4d2f3b0832a115cb0
|
||||
F test/bigfile.test 8f88b5ef065e31c615c49d725ede94155fbe9609
|
||||
F test/bigfile2.test 8a3c242c3c3481e7cde5a6ef2a66fdc367a095f7
|
||||
F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747
|
||||
F test/bind.test 3c7b320969000c441a70952b0b15938fbb66237c
|
||||
F test/bindxfer.test efecd12c580c14df5f4ad3b3e83c667744a4f7e0
|
||||
@@ -314,9 +313,9 @@ F test/boundary4.test 89e02fa66397b8a325d5eb102b5806f961f8ec4b
|
||||
F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0
|
||||
F test/cache.test f64136b0893c293d0b910ed057b3b711249099a7
|
||||
F test/capi2.test 835d4cee9f542ea50fa8d01f3fe6de80b0627360
|
||||
F test/capi3.test 8dedb0050610e9ff95cd9d487beb0ce5f33a31ee
|
||||
F test/capi3.test 56ab450125ead38846cbae7e5b6a216686c3cffa
|
||||
F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
|
||||
F test/capi3c.test 01f197d73f4d4d66316483662f475cab7ab5bd60
|
||||
F test/capi3c.test 93d24621c9ff84da9da060f30431e0453db1cdb0
|
||||
F test/capi3d.test 17b57ca28be3e37e14c2ba8f787d292d84b724a1
|
||||
F test/capi3e.test f7408dda65c92b9056199fdc180f893015f83dde
|
||||
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
|
||||
@@ -363,7 +362,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
|
||||
@@ -389,7 +388,7 @@ F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
|
||||
F test/e_select.test f5d4b81205701deacfae42051ae200969c41d2c0
|
||||
F test/e_select2.test 5c3d3da19c7b3e90ae444579db2b70098599ab92
|
||||
F test/e_update.test 161d5dc6a3ed9dd08f5264d13e20735d7a89f00c
|
||||
F test/e_uri.test e8b894474fdfe7b18b0c9cb2d911270de2ad64ce
|
||||
F test/e_uri.test 9e190ca799d9190eec6e43f2aadf1d10c06a57a3
|
||||
F test/e_vacuum.test 331da289ae186656cf5f2eb27f577a89c0c221af
|
||||
F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
|
||||
F test/enc2.test 796c59832e2b9a52842f382ffda8f3e989db03ad
|
||||
@@ -464,7 +463,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
|
||||
@@ -501,8 +500,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 c812e9cf843e26ba633f58b36a2629f878af20fd
|
||||
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
|
||||
@@ -567,7 +566,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
|
||||
@@ -611,13 +610,13 @@ F test/minmax.test 722d80816f7e096bf2c04f4111f1a6c1ba65453d
|
||||
F test/minmax2.test 33504c01a03bd99226144e4b03f7631a274d66e0
|
||||
F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354
|
||||
F test/minmax4.test 536a3360470633a177e42fbc19660d146b51daef
|
||||
F test/misc1.test 55cb2bfbf4a8cd61f4be1effc30426ad41696bff
|
||||
F test/misc1.test 889b40722442380a2f6575f30831b32b2372d70e
|
||||
F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d
|
||||
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
|
||||
@@ -632,7 +631,7 @@ F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347
|
||||
F test/null.test a8b09b8ed87852742343b33441a9240022108993
|
||||
F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394
|
||||
F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3
|
||||
F test/pager1.test 31fef8ff6d5cbb4643f430e31756312d361ecfdf
|
||||
F test/pager1.test 2163c6ef119f497a71a84137c957c63763e640ab
|
||||
F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1
|
||||
F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
|
||||
F test/pagerfault.test 452f2cc23e3bfcfa935f4442aec1da4fe1dc0442
|
||||
@@ -642,23 +641,23 @@ F test/pageropt.test 9191867ed19a2b3db6c42d1b36b6fbc657cd1ab0
|
||||
F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0
|
||||
F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16
|
||||
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
|
||||
F test/permutations.test ea7b6948eaa22993fcfa662eb704ce29ddb24b2a
|
||||
F test/pragma.test c51c148defe32bf4a419a522f95d26838d5cf677
|
||||
F test/permutations.test 2af90e00cea9e7e7c0a6b16d34727cb5bbae14dd
|
||||
F test/pragma.test a62f73293b0f0d79b0c87f8dd32d46fe53b0bd17
|
||||
F test/pragma2.test 3a55f82b954242c642f8342b17dffc8b47472947
|
||||
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
|
||||
F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301
|
||||
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
|
||||
F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
|
||||
F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26
|
||||
F test/quota.test c2f778dab4c7fb07bcfa962cc5c762f36d8061dc
|
||||
F test/quota2.test bc9fdb2e46aace691c1a01a9cc8d097bd4d7c1ab
|
||||
F test/quota.test b5b3eec55a059e0fe493c66c6e27bd2c07676cfd
|
||||
F test/quota2.test 6d2bd57e8a4da28817f46db9da18551211cd325f
|
||||
F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6
|
||||
F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459
|
||||
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
|
||||
@@ -689,15 +688,16 @@ F test/selectA.test 06d1032fa9009314c95394f2ca2e60d9f7ae8532
|
||||
F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25
|
||||
F test/selectC.test 871fb55d884d3de5943c4057ebd22c2459e71977
|
||||
F test/server1.test 46803bd3fe8b99b30dbc5ff38ffc756f5c13a118
|
||||
F test/shared.test 34945a516532b11182c3eb26e31247eee3c9ae48
|
||||
F test/shared.test 1da9dbad400cee0d93f252ccf76e1ae007a63746
|
||||
F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879
|
||||
F test/shared3.test ebf77f023f4bdaa8f74f65822b559e86ce5c6257
|
||||
F test/shared4.test 72d90821e8d2fc918a08f16d32880868d8ee8e9d
|
||||
F test/shared6.test 866bb4982c45ce216c61ded5e8fde4e7e2f3ffa9
|
||||
F test/shared7.test 960760bc8d03e1419e70dea69cf41db62853616e
|
||||
F test/shared8.test b27befbefbe7f4517f1d6b7ff8f64a41ec74165d
|
||||
F test/shared_err.test 91e26ec4f3fbe07951967955585137e2f18993de
|
||||
F test/sharedlock.test ffa0a3c4ac192145b310f1254f8afca4d553eabf
|
||||
F test/shell1.test 6e3013bc50e2b73f00d17e491f776decc82a71c8
|
||||
F test/shell1.test 9895ee3013742a02e5afd8d77793729967ffd195
|
||||
F test/shell2.test 037d6ad16e873354195d30bb2dc4b5321788154a
|
||||
F test/shell3.test 9196c42772d575685e722c92b4b39053c6ebba59
|
||||
F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9
|
||||
@@ -716,6 +716,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 936be6f7ba1c4d096adb280c68b32f4848af8d2e
|
||||
F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298
|
||||
F test/stat.test 08e8185b3fd5b010c90d7ad82b9dd4ea1cbf14b0
|
||||
F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
|
||||
@@ -733,7 +734,7 @@ F test/tclsqlite.test 1597d353308531527583481d14d9da52ea8ed0af
|
||||
F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
|
||||
F test/temptable.test 51edd31c65ed1560dd600b1796e8325df96318e2
|
||||
F test/temptrigger.test 26670ed7a39cf2296a7f0a9e0a1d7bdb7abe936d
|
||||
F test/tester.tcl a55e066251bc05e26f9da00e76644ab649b26f3c
|
||||
F test/tester.tcl 2665f64c9ce71944b4d41269114e658fb81bda05
|
||||
F test/thread001.test 7cc2ce08f9cde95964736d11e91f9ab610f82f91
|
||||
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
|
||||
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
|
||||
@@ -897,7 +898,7 @@ F test/unique.test 083c7fff74695bcc27a71d75699deba3595bc9c2
|
||||
F test/unixexcl.test a9870e46cc6f8390a494513d4f2bf55b5a8b3e46
|
||||
F test/unordered.test f53095cee37851bf30130fa1bf299a8845e837bb
|
||||
F test/update.test 8bc86fd7ef1a00014f76dc6a6a7c974df4aef172
|
||||
F test/uri.test 78e869db1ff6331157b08ef089b1b3e65819c74c
|
||||
F test/uri.test 63e03df051620a18f794b4f4adcdefb3c23b6751
|
||||
F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae
|
||||
F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d
|
||||
F test/vacuum2.test af432e6e3bfc0ea20a80cb86a03c7d9876d38324
|
||||
@@ -906,7 +907,7 @@ F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
|
||||
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
||||
F test/veryquick.test 7701bb609fe8bf6535514e8b849a309e8f00573b
|
||||
F test/view.test b182a67ec43f490b156b5a710827a341be83dd17
|
||||
F test/vtab1.test e429a6835faa3870016c55d1178dcfead85f936a
|
||||
F test/vtab1.test 10fb9e656fe4b318cd82ff1616a340acc01aac4b
|
||||
F test/vtab2.test 7bcffc050da5c68f4f312e49e443063e2d391c0d
|
||||
F test/vtab3.test baad99fd27217f5d6db10660522e0b7192446de1
|
||||
F test/vtab4.test 942f8b8280b3ea8a41dae20e7822d065ca1cb275
|
||||
@@ -924,9 +925,9 @@ F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e
|
||||
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
|
||||
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
|
||||
F test/vtab_shared.test 82f463886e18d7f8395a4b6167c91815efe54839
|
||||
F test/wal.test b3d28d655371bf3f6500c679f526e9860544fe70
|
||||
F test/wal2.test d5021064bebfc717fe2bf4db2536ea030b76a773
|
||||
F test/wal3.test 6504bbf348b2d6dfade64a064f1050fd617e8706
|
||||
F test/wal.test a040047d7f2b9f34bc4d597964e5e7c09609c635
|
||||
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
|
||||
@@ -944,7 +945,7 @@ 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 f183c0003060a64793f9bfafef4c479418ed7fa8
|
||||
F test/walshared.test 6dda2293880c300baf5d791c307f653094585761
|
||||
F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
|
||||
F test/walthread.test a2ed5270eb695284d4ad27d252517bdc3317ee2a
|
||||
@@ -972,17 +973,17 @@ 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/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
|
||||
@@ -1002,9 +1003,9 @@ F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
|
||||
F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f
|
||||
F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
|
||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||
F tool/warnings-clang.sh a8a0a3babda96dfb1ff51adda3cbbf3dfb7266c2
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||
P b89d3834f6690073fca0fc22c18afa1fb280ea7d
|
||||
R 721b18aaca6e897933f70f12a0639abb
|
||||
P defd828e90a5494e58cc2cd14c8f4cce7fd2bb2b
|
||||
R 62a7b8739dbc0504b7043c6629065afd
|
||||
U dan
|
||||
Z f1ca3c8a69800dd8f2afaacbafb654ad
|
||||
Z f8c7a516451a2fad10c61fa887e0e873
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
e71495a817b479bc23c5403d99255e3f098eb054
|
||||
0a33444105e29d79475e267021d33c1a006b85a3
|
||||
+4
-4
@@ -932,7 +932,7 @@ static int loadStat3(sqlite3 *db, const char *zDb){
|
||||
int eType; /* Datatype of a sample */
|
||||
IndexSample *pSample; /* A slot in pIdx->aSample[] */
|
||||
|
||||
assert( db->lookaside.bEnabled==0 );
|
||||
assert( db->lookaside.sz==0 );
|
||||
if( !sqlite3FindTable(db, "sqlite_stat3", zDb) ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@@ -1108,10 +1108,10 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
|
||||
/* Load the statistics from the sqlite_stat3 table. */
|
||||
#ifdef SQLITE_ENABLE_STAT3
|
||||
if( rc==SQLITE_OK ){
|
||||
int lookasideEnabled = db->lookaside.bEnabled;
|
||||
db->lookaside.bEnabled = 0;
|
||||
int lookasideSz = db->lookaside.sz;
|
||||
db->lookaside.sz = 0;
|
||||
rc = loadStat3(db, sInfo.zDatabase);
|
||||
db->lookaside.bEnabled = lookasideEnabled;
|
||||
db->lookaside.sz = lookasideSz;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+2
-2
@@ -216,7 +216,7 @@ static void attachFunc(
|
||||
db->aDb[iDb].pBt = 0;
|
||||
db->aDb[iDb].pSchema = 0;
|
||||
}
|
||||
sqlite3ResetInternalSchema(db, -1);
|
||||
sqlite3ResetAllSchemasOfConnection(db);
|
||||
db->nDb = iDb;
|
||||
if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
|
||||
db->mallocFailed = 1;
|
||||
@@ -288,7 +288,7 @@ static void detachFunc(
|
||||
sqlite3BtreeClose(pDb->pBt);
|
||||
pDb->pBt = 0;
|
||||
pDb->pSchema = 0;
|
||||
sqlite3ResetInternalSchema(db, -1);
|
||||
sqlite3ResetAllSchemasOfConnection(db);
|
||||
return;
|
||||
|
||||
detach_error:
|
||||
|
||||
+6
-6
@@ -414,7 +414,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1);
|
||||
if( rc==SQLITE_OK ){
|
||||
if( p->pDestDb ){
|
||||
sqlite3ResetInternalSchema(p->pDestDb, -1);
|
||||
sqlite3ResetAllSchemasOfConnection(p->pDestDb);
|
||||
}
|
||||
if( destMode==PAGER_JOURNALMODE_WAL ){
|
||||
rc = sqlite3BtreeSetVersion(p->pDest, 2);
|
||||
@@ -543,14 +543,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 +576,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 +585,7 @@ int sqlite3_backup_finish(sqlite3_backup *p){
|
||||
** sqlite3_backup_finish(). */
|
||||
sqlite3_free(p);
|
||||
}
|
||||
sqlite3_mutex_leave(mutex);
|
||||
sqlite3LeaveMutexAndCloseZombie(pSrcDb);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
+17
-10
@@ -1721,7 +1721,8 @@ int sqlite3BtreeOpen(
|
||||
const int isMemdb = 0;
|
||||
#else
|
||||
const int isMemdb = (zFilename && strcmp(zFilename, ":memory:")==0)
|
||||
|| (isTempDb && sqlite3TempInMemory(db));
|
||||
|| (isTempDb && sqlite3TempInMemory(db))
|
||||
|| (vfsFlags & SQLITE_OPEN_MEMORY)!=0;
|
||||
#endif
|
||||
|
||||
assert( db!=0 );
|
||||
@@ -1757,7 +1758,7 @@ int sqlite3BtreeOpen(
|
||||
** If this Btree is a candidate for shared cache, try to find an
|
||||
** existing BtShared object that we can share with
|
||||
*/
|
||||
if( isMemdb==0 && isTempDb==0 ){
|
||||
if( isTempDb==0 && (isMemdb==0 || (vfsFlags&SQLITE_OPEN_URI)!=0) ){
|
||||
if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){
|
||||
int nFullPathname = pVfs->mxPathname+1;
|
||||
char *zFullPathname = sqlite3Malloc(nFullPathname);
|
||||
@@ -1767,11 +1768,16 @@ int sqlite3BtreeOpen(
|
||||
sqlite3_free(p);
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
rc = sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname);
|
||||
if( rc ){
|
||||
sqlite3_free(zFullPathname);
|
||||
sqlite3_free(p);
|
||||
return rc;
|
||||
if( isMemdb ){
|
||||
memcpy(zFullPathname, zFilename, sqlite3Strlen30(zFilename)+1);
|
||||
}else{
|
||||
rc = sqlite3OsFullPathname(pVfs, zFilename,
|
||||
nFullPathname, zFullPathname);
|
||||
if( rc ){
|
||||
sqlite3_free(zFullPathname);
|
||||
sqlite3_free(p);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
#if SQLITE_THREADSAFE
|
||||
mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN);
|
||||
@@ -1781,7 +1787,7 @@ int sqlite3BtreeOpen(
|
||||
#endif
|
||||
for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){
|
||||
assert( pBt->nRef>0 );
|
||||
if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager))
|
||||
if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager, 0))
|
||||
&& sqlite3PagerVfs(pBt->pPager)==pVfs ){
|
||||
int iDb;
|
||||
for(iDb=db->nDb-1; iDb>=0; iDb--){
|
||||
@@ -8046,14 +8052,15 @@ char *sqlite3BtreeIntegrityCheck(
|
||||
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
|
||||
|
||||
/*
|
||||
** Return the full pathname of the underlying database file.
|
||||
** Return the full pathname of the underlying database file. Return
|
||||
** an empty string if the database is in-memory or a TEMP database.
|
||||
**
|
||||
** The pager filename is invariant as long as the pager is
|
||||
** open so it is safe to access without the BtShared mutex.
|
||||
*/
|
||||
const char *sqlite3BtreeGetFilename(Btree *p){
|
||||
assert( p->pBt->pPager!=0 );
|
||||
return sqlite3PagerFilename(p->pBt->pPager);
|
||||
return sqlite3PagerFilename(p->pBt->pPager, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+55
-53
@@ -394,58 +394,15 @@ void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){
|
||||
}
|
||||
|
||||
/*
|
||||
** Erase all schema information from the in-memory hash tables of
|
||||
** a single database. This routine is called to reclaim memory
|
||||
** before the database closes. It is also called during a rollback
|
||||
** if there were schema changes during the transaction or if a
|
||||
** schema-cookie mismatch occurs.
|
||||
** Look through the list of open database files in db->aDb[] and if
|
||||
** any have been closed, remove them from the list. Reallocate the
|
||||
** db->aDb[] structure to a smaller size, if possible.
|
||||
**
|
||||
** If iDb<0 then reset the internal schema tables for all database
|
||||
** files. If iDb>=0 then reset the internal schema for only the
|
||||
** single file indicated.
|
||||
** Entry 0 (the "main" database) and entry 1 (the "temp" database)
|
||||
** are never candidates for being collapsed.
|
||||
*/
|
||||
void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){
|
||||
void sqlite3CollapseDatabaseArray(sqlite3 *db){
|
||||
int i, j;
|
||||
assert( iDb<db->nDb );
|
||||
|
||||
if( iDb>=0 ){
|
||||
/* Case 1: Reset the single schema identified by iDb */
|
||||
Db *pDb = &db->aDb[iDb];
|
||||
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
|
||||
assert( pDb->pSchema!=0 );
|
||||
sqlite3SchemaClear(pDb->pSchema);
|
||||
|
||||
/* If any database other than TEMP is reset, then also reset TEMP
|
||||
** since TEMP might be holding triggers that reference tables in the
|
||||
** other database.
|
||||
*/
|
||||
if( iDb!=1 ){
|
||||
pDb = &db->aDb[1];
|
||||
assert( pDb->pSchema!=0 );
|
||||
sqlite3SchemaClear(pDb->pSchema);
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* Case 2 (from here to the end): Reset all schemas for all attached
|
||||
** databases. */
|
||||
assert( iDb<0 );
|
||||
sqlite3BtreeEnterAll(db);
|
||||
for(i=0; i<db->nDb; i++){
|
||||
Db *pDb = &db->aDb[i];
|
||||
if( pDb->pSchema ){
|
||||
sqlite3SchemaClear(pDb->pSchema);
|
||||
}
|
||||
}
|
||||
db->flags &= ~SQLITE_InternChanges;
|
||||
sqlite3VtabUnlockList(db);
|
||||
sqlite3BtreeLeaveAll(db);
|
||||
|
||||
/* If one or more of the auxiliary database files has been closed,
|
||||
** then remove them from the auxiliary database list. We take the
|
||||
** opportunity to do this here since we have just deleted all of the
|
||||
** schema hash tables and therefore do not have to make any changes
|
||||
** to any of those tables.
|
||||
*/
|
||||
for(i=j=2; i<db->nDb; i++){
|
||||
struct Db *pDb = &db->aDb[i];
|
||||
if( pDb->pBt==0 ){
|
||||
@@ -467,6 +424,51 @@ void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Reset the schema for the database at index iDb. Also reset the
|
||||
** TEMP schema.
|
||||
*/
|
||||
void sqlite3ResetOneSchema(sqlite3 *db, int iDb){
|
||||
Db *pDb;
|
||||
assert( iDb<db->nDb );
|
||||
|
||||
/* Case 1: Reset the single schema identified by iDb */
|
||||
pDb = &db->aDb[iDb];
|
||||
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
|
||||
assert( pDb->pSchema!=0 );
|
||||
sqlite3SchemaClear(pDb->pSchema);
|
||||
|
||||
/* If any database other than TEMP is reset, then also reset TEMP
|
||||
** since TEMP might be holding triggers that reference tables in the
|
||||
** other database.
|
||||
*/
|
||||
if( iDb!=1 ){
|
||||
pDb = &db->aDb[1];
|
||||
assert( pDb->pSchema!=0 );
|
||||
sqlite3SchemaClear(pDb->pSchema);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
** Erase all schema information from all attached databases (including
|
||||
** "main" and "temp") for a single database connection.
|
||||
*/
|
||||
void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){
|
||||
int i;
|
||||
sqlite3BtreeEnterAll(db);
|
||||
for(i=0; i<db->nDb; i++){
|
||||
Db *pDb = &db->aDb[i];
|
||||
if( pDb->pSchema ){
|
||||
sqlite3SchemaClear(pDb->pSchema);
|
||||
}
|
||||
}
|
||||
db->flags &= ~SQLITE_InternChanges;
|
||||
sqlite3VtabUnlockList(db);
|
||||
sqlite3BtreeLeaveAll(db);
|
||||
sqlite3CollapseDatabaseArray(db);
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine is called when a commit occurs.
|
||||
*/
|
||||
@@ -1814,11 +1816,11 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
|
||||
assert( pTable->pSelect );
|
||||
pSel = sqlite3SelectDup(db, pTable->pSelect, 0);
|
||||
if( pSel ){
|
||||
u8 enableLookaside = db->lookaside.bEnabled;
|
||||
u16 lookasideSz = db->lookaside.sz;
|
||||
n = pParse->nTab;
|
||||
sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
|
||||
pTable->nCol = -1;
|
||||
db->lookaside.bEnabled = 0;
|
||||
db->lookaside.sz = 0;
|
||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||
xAuth = db->xAuth;
|
||||
db->xAuth = 0;
|
||||
@@ -1827,7 +1829,7 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
|
||||
#else
|
||||
pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
|
||||
#endif
|
||||
db->lookaside.bEnabled = enableLookaside;
|
||||
db->lookaside.sz = lookasideSz;
|
||||
pParse->nTab = n;
|
||||
if( pSelTab ){
|
||||
assert( pTable->aCol==0 );
|
||||
@@ -2763,7 +2765,7 @@ Index *sqlite3CreateIndex(
|
||||
}else{
|
||||
zColl = pTab->aCol[j].zColl;
|
||||
if( !zColl ){
|
||||
zColl = db->pDfltColl->zName;
|
||||
zColl = "BINARY";
|
||||
}
|
||||
}
|
||||
if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){
|
||||
|
||||
@@ -48,6 +48,9 @@ static const char * const azCompileOpt[] = {
|
||||
#ifdef SQLITE_COVERAGE_TEST
|
||||
"COVERAGE_TEST",
|
||||
#endif
|
||||
#ifdef SQLITE_CURDIR
|
||||
"CURDIR",
|
||||
#endif
|
||||
#ifdef SQLITE_DEBUG
|
||||
"DEBUG",
|
||||
#endif
|
||||
|
||||
+4
-4
@@ -981,7 +981,7 @@ static Trigger *fkActionTrigger(
|
||||
pTrigger = pFKey->apTrigger[iAction];
|
||||
|
||||
if( action!=OE_None && !pTrigger ){
|
||||
u8 enableLookaside; /* Copy of db->lookaside.bEnabled */
|
||||
u16 lookasideSz; /* Copy of db->lookaside.sz */
|
||||
char const *zFrom; /* Name of child table */
|
||||
int nFrom; /* Length in bytes of zFrom */
|
||||
Index *pIdx = 0; /* Parent key index for this FK */
|
||||
@@ -1090,8 +1090,8 @@ static Trigger *fkActionTrigger(
|
||||
}
|
||||
|
||||
/* Disable lookaside memory allocation */
|
||||
enableLookaside = db->lookaside.bEnabled;
|
||||
db->lookaside.bEnabled = 0;
|
||||
lookasideSz = db->lookaside.sz;
|
||||
db->lookaside.sz = 0;
|
||||
|
||||
pTrigger = (Trigger *)sqlite3DbMallocZero(db,
|
||||
sizeof(Trigger) + /* struct Trigger */
|
||||
@@ -1114,7 +1114,7 @@ static Trigger *fkActionTrigger(
|
||||
}
|
||||
|
||||
/* Re-enable the lookaside buffer, if it was disabled earlier. */
|
||||
db->lookaside.bEnabled = enableLookaside;
|
||||
db->lookaside.sz = lookasideSz;
|
||||
|
||||
sqlite3ExprDelete(db, pWhere);
|
||||
sqlite3ExprDelete(db, pWhen);
|
||||
|
||||
+12
-1
@@ -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;
|
||||
}
|
||||
|
||||
+163
-32
@@ -74,6 +74,15 @@ void (*sqlite3IoTrace)(const char*, ...) = 0;
|
||||
*/
|
||||
char *sqlite3_temp_directory = 0;
|
||||
|
||||
/*
|
||||
** If the following global variable points to a string which is the
|
||||
** name of a directory, then that directory will be used to store
|
||||
** all database files specified with a relative pathname.
|
||||
**
|
||||
** See also the "PRAGMA data_store_directory" SQL command.
|
||||
*/
|
||||
char *sqlite3_data_directory = 0;
|
||||
|
||||
/*
|
||||
** Initialize SQLite.
|
||||
**
|
||||
@@ -272,6 +281,18 @@ int sqlite3_shutdown(void){
|
||||
if( sqlite3GlobalConfig.isMallocInit ){
|
||||
sqlite3MallocEnd();
|
||||
sqlite3GlobalConfig.isMallocInit = 0;
|
||||
|
||||
#ifndef SQLITE_OMIT_SHUTDOWN_DIRECTORIES
|
||||
/* The heap subsystem has now been shutdown and these values are supposed
|
||||
** to be NULL or point to memory that was obtained from sqlite3_malloc(),
|
||||
** which would rely on that heap subsystem; therefore, make sure these
|
||||
** values cannot refer to heap memory that was just invalidated when the
|
||||
** heap subsystem was shutdown. This is only done if the current call to
|
||||
** this function resulted in the heap subsystem actually being shutdown.
|
||||
*/
|
||||
sqlite3_data_directory = 0;
|
||||
sqlite3_temp_directory = 0;
|
||||
#endif
|
||||
}
|
||||
if( sqlite3GlobalConfig.isMutexInit ){
|
||||
sqlite3MutexEnd();
|
||||
@@ -281,6 +302,17 @@ int sqlite3_shutdown(void){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** If a custom memory allocator is configured using the legacy
|
||||
** SQLITE_CONFIG_MALLOC interface, this function is used as the xCalloc()
|
||||
** method.
|
||||
*/
|
||||
static void *syntheticCalloc(int nByte){
|
||||
void *pRet = sqlite3GlobalConfig.m.xMalloc(nByte);
|
||||
if( pRet ) memset(pRet, 0, nByte);
|
||||
return pRet;
|
||||
}
|
||||
|
||||
/*
|
||||
** This API allows applications to modify the global configuration of
|
||||
** the SQLite library at run-time.
|
||||
@@ -336,18 +368,33 @@ int sqlite3_config(int op, ...){
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
case SQLITE_CONFIG_MALLOC: {
|
||||
/* Specify an alternative malloc implementation */
|
||||
int nCopy = offsetof(sqlite3_mem_methods, xCalloc);
|
||||
memcpy(&sqlite3GlobalConfig.m, va_arg(ap, sqlite3_mem_methods*), nCopy);
|
||||
sqlite3GlobalConfig.m.xCalloc = syntheticCalloc;
|
||||
break;
|
||||
}
|
||||
case SQLITE_CONFIG_GETMALLOC: {
|
||||
/* Retrieve the current malloc() implementation */
|
||||
int nCopy = offsetof(sqlite3_mem_methods, xCalloc);
|
||||
if( sqlite3GlobalConfig.m.xMalloc==0 ) sqlite3MemSetDefault();
|
||||
memcpy(va_arg(ap, sqlite3_mem_methods*), &sqlite3GlobalConfig.m, nCopy);
|
||||
break;
|
||||
}
|
||||
|
||||
case SQLITE_CONFIG_MALLOC2: {
|
||||
/* Specify an alternative malloc implementation */
|
||||
sqlite3GlobalConfig.m = *va_arg(ap, sqlite3_mem_methods*);
|
||||
break;
|
||||
}
|
||||
case SQLITE_CONFIG_GETMALLOC: {
|
||||
case SQLITE_CONFIG_GETMALLOC2: {
|
||||
/* Retrieve the current malloc() implementation */
|
||||
if( sqlite3GlobalConfig.m.xMalloc==0 ) sqlite3MemSetDefault();
|
||||
*va_arg(ap, sqlite3_mem_methods*) = sqlite3GlobalConfig.m;
|
||||
break;
|
||||
}
|
||||
|
||||
case SQLITE_CONFIG_MEMSTATUS: {
|
||||
/* Enable or disable the malloc status collection */
|
||||
sqlite3GlobalConfig.bMemstat = va_arg(ap, int);
|
||||
@@ -505,7 +552,7 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
|
||||
}
|
||||
db->lookaside.pStart = pStart;
|
||||
db->lookaside.pFree = 0;
|
||||
db->lookaside.sz = (u16)sz;
|
||||
db->lookaside.szEnabled = db->lookaside.sz = (u16)sz;
|
||||
if( pStart ){
|
||||
int i;
|
||||
LookasideSlot *p;
|
||||
@@ -517,12 +564,12 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
|
||||
p = (LookasideSlot*)&((u8*)p)[sz];
|
||||
}
|
||||
db->lookaside.pEnd = p;
|
||||
db->lookaside.bEnabled = 1;
|
||||
db->lookaside.bMalloced = pBuf==0 ?1:0;
|
||||
assert( db->lookaside.sz>0 );
|
||||
}else{
|
||||
db->lookaside.pEnd = 0;
|
||||
db->lookaside.bEnabled = 0;
|
||||
db->lookaside.bMalloced = 0;
|
||||
db->lookaside.sz = 0;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@@ -720,13 +767,49 @@ static void functionDestroy(sqlite3 *db, FuncDef *p){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Disconnect all sqlite3_vtab objects that belong to database connection
|
||||
** db. This is called when db is being closed.
|
||||
*/
|
||||
static void disconnectAllVtab(sqlite3 *db){
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
int i;
|
||||
sqlite3BtreeEnterAll(db);
|
||||
for(i=0; i<db->nDb; i++){
|
||||
Schema *pSchema = db->aDb[i].pSchema;
|
||||
if( db->aDb[i].pSchema ){
|
||||
HashElem *p;
|
||||
for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){
|
||||
Table *pTab = (Table *)sqliteHashData(p);
|
||||
if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab);
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlite3BtreeLeaveAll(db);
|
||||
#else
|
||||
UNUSED_PARAMETER(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;
|
||||
}
|
||||
@@ -735,10 +818,10 @@ int sqlite3_close(sqlite3 *db){
|
||||
}
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
|
||||
/* Force xDestroy calls on all virtual tables */
|
||||
sqlite3ResetInternalSchema(db, -1);
|
||||
/* Force xDisconnect calls on all virtual tables */
|
||||
disconnectAllVtab(db);
|
||||
|
||||
/* If a transaction is open, the ResetInternalSchema() call above
|
||||
/* If a transaction is open, the disconnectAllVtab() call above
|
||||
** will not have called the xDisconnect() method on any virtual
|
||||
** tables in the db->aVTrans[] array. The following sqlite3VtabRollback()
|
||||
** call will do so. We need to do this before the check for active
|
||||
@@ -747,28 +830,67 @@ 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);
|
||||
|
||||
/* Close all database connections */
|
||||
for(j=0; j<db->nDb; j++){
|
||||
struct Db *pDb = &db->aDb[j];
|
||||
if( pDb->pBt ){
|
||||
@@ -779,15 +901,22 @@ int sqlite3_close(sqlite3 *db){
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlite3ResetInternalSchema(db, -1);
|
||||
/* Clear the TEMP schema separately and last */
|
||||
if( db->aDb[1].pSchema ){
|
||||
sqlite3SchemaClear(db->aDb[1].pSchema);
|
||||
}
|
||||
sqlite3VtabUnlockList(db);
|
||||
|
||||
/* Free up the array of auxiliary databases */
|
||||
sqlite3CollapseDatabaseArray(db);
|
||||
assert( db->nDb<=2 );
|
||||
assert( db->aDb==db->aDbStatic );
|
||||
|
||||
/* Tell the code in notify.c that the connection no longer holds any
|
||||
** locks and does not require any further unlock-notify callbacks.
|
||||
*/
|
||||
sqlite3ConnectionClosed(db);
|
||||
|
||||
assert( db->nDb<=2 );
|
||||
assert( db->aDb==db->aDbStatic );
|
||||
for(j=0; j<ArraySize(db->aFunc.a); j++){
|
||||
FuncDef *pNext, *pHash, *p;
|
||||
for(p=db->aFunc.a[j]; p; p=pHash){
|
||||
@@ -845,7 +974,6 @@ int sqlite3_close(sqlite3 *db){
|
||||
sqlite3_free(db->lookaside.pStart);
|
||||
}
|
||||
sqlite3_free(db);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -874,7 +1002,7 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){
|
||||
|
||||
if( db->flags&SQLITE_InternChanges ){
|
||||
sqlite3ExpirePreparedStatements(db);
|
||||
sqlite3ResetInternalSchema(db, -1);
|
||||
sqlite3ResetAllSchemasOfConnection(db);
|
||||
}
|
||||
|
||||
/* Any deferred constraint violations have now been resolved. */
|
||||
@@ -2012,10 +2140,12 @@ int sqlite3ParseUri(
|
||||
{ "ro", SQLITE_OPEN_READONLY },
|
||||
{ "rw", SQLITE_OPEN_READWRITE },
|
||||
{ "rwc", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE },
|
||||
{ "memory", SQLITE_OPEN_MEMORY },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
mask = SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
|
||||
mask = SQLITE_OPEN_READONLY | SQLITE_OPEN_READWRITE
|
||||
| SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY;
|
||||
aMode = aOpenMode;
|
||||
limit = mask & flags;
|
||||
zModeType = "access";
|
||||
@@ -2036,7 +2166,7 @@ int sqlite3ParseUri(
|
||||
rc = SQLITE_ERROR;
|
||||
goto parse_uri_out;
|
||||
}
|
||||
if( mode>limit ){
|
||||
if( (mode & ~SQLITE_OPEN_MEMORY)>limit ){
|
||||
*pzErrMsg = sqlite3_mprintf("%s mode not allowed: %s",
|
||||
zModeType, zVal);
|
||||
rc = SQLITE_PERM;
|
||||
@@ -2055,6 +2185,7 @@ int sqlite3ParseUri(
|
||||
memcpy(zFile, zUri, nUri);
|
||||
zFile[nUri] = '\0';
|
||||
zFile[nUri+1] = '\0';
|
||||
flags &= ~SQLITE_OPEN_URI;
|
||||
}
|
||||
|
||||
*ppVfs = sqlite3_vfs_find(zVfs);
|
||||
|
||||
+127
-78
@@ -259,14 +259,27 @@ static void sqlite3MallocAlarm(int nByte){
|
||||
** Do a memory allocation with statistics and alarms. Assume the
|
||||
** lock is already held.
|
||||
*/
|
||||
static int mallocWithAlarm(int n, void **pp){
|
||||
int nFull;
|
||||
void *p;
|
||||
static void *mallocWithAlarm(
|
||||
void *(*xAlloc)(int), /* Memory allocation function */
|
||||
int n /* Bytes of memory to allocate */
|
||||
){
|
||||
void *p; /* Pointer to allocated memory */
|
||||
int nFull; /* Value returned by xRoundup (if required) */
|
||||
|
||||
assert( sqlite3_mutex_held(mem0.mutex) );
|
||||
nFull = sqlite3GlobalConfig.m.xRoundup(n);
|
||||
assert( xAlloc==sqlite3GlobalConfig.m.xMalloc
|
||||
|| xAlloc==sqlite3GlobalConfig.m.xCalloc
|
||||
);
|
||||
|
||||
/* Note: At one point this function would call xRoundup() and use the
|
||||
** resulting value as the argument to xAlloc(). However, this is not
|
||||
** required. And it is a (small) drag on performance. */
|
||||
/* nFull = sqlite3GlobalConfig.m.xRoundup(n); */
|
||||
|
||||
sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n);
|
||||
if( mem0.alarmCallback!=0 ){
|
||||
if( mem0.alarmCallback ){
|
||||
int nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
|
||||
nFull = sqlite3GlobalConfig.m.xRoundup(n);
|
||||
if( nUsed >= mem0.alarmThreshold - nFull ){
|
||||
mem0.nearlyFull = 1;
|
||||
sqlite3MallocAlarm(nFull);
|
||||
@@ -274,27 +287,33 @@ static int mallocWithAlarm(int n, void **pp){
|
||||
mem0.nearlyFull = 0;
|
||||
}
|
||||
}
|
||||
p = sqlite3GlobalConfig.m.xMalloc(nFull);
|
||||
|
||||
p = xAlloc(n);
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
if( p==0 && mem0.alarmCallback ){
|
||||
sqlite3MallocAlarm(nFull);
|
||||
p = sqlite3GlobalConfig.m.xMalloc(nFull);
|
||||
p = xAlloc(nFull);
|
||||
}
|
||||
#endif
|
||||
if( p ){
|
||||
nFull = sqlite3MallocSize(p);
|
||||
sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nFull);
|
||||
sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, sqlite3MallocSize(p));
|
||||
sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, 1);
|
||||
}else{
|
||||
testcase( sqlite3GlobalConfig.xLog!=0 );
|
||||
sqlite3_log(SQLITE_NOMEM, "failed to allocate %d bytes of memory", n);
|
||||
}
|
||||
*pp = p;
|
||||
return nFull;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
** Allocate memory. This routine is like sqlite3_malloc() except that it
|
||||
** assumes the memory subsystem has already been initialized.
|
||||
** Use allocator function xAlloc to allocate n bytes of memory.
|
||||
*/
|
||||
void *sqlite3Malloc(int n){
|
||||
static void *memAllocate(
|
||||
sqlite3 *db,
|
||||
void *(*xAlloc)(int), /* Memory allocation function */
|
||||
int n /* Bytes of space to allocate */
|
||||
){
|
||||
void *p;
|
||||
if( n<=0 /* IMP: R-65312-04917 */
|
||||
|| n>=0x7fffff00
|
||||
@@ -305,17 +324,42 @@ void *sqlite3Malloc(int n){
|
||||
** 255 bytes of overhead. SQLite itself will never use anything near
|
||||
** this amount. The only way to reach the limit is with sqlite3_malloc() */
|
||||
p = 0;
|
||||
}else if( sqlite3GlobalConfig.bMemstat ){
|
||||
sqlite3_mutex_enter(mem0.mutex);
|
||||
mallocWithAlarm(n, &p);
|
||||
sqlite3_mutex_leave(mem0.mutex);
|
||||
}else{
|
||||
p = sqlite3GlobalConfig.m.xMalloc(n);
|
||||
if( sqlite3GlobalConfig.bMemstat ){
|
||||
sqlite3_mutex_enter(mem0.mutex);
|
||||
p = mallocWithAlarm(xAlloc, n);
|
||||
sqlite3_mutex_leave(mem0.mutex);
|
||||
}else{
|
||||
p = xAlloc(n);
|
||||
}
|
||||
if( !p && db ) db->mallocFailed = 1;
|
||||
}
|
||||
|
||||
assert( EIGHT_BYTE_ALIGNMENT(p) ); /* IMP: R-04675-44850 */
|
||||
if( db ){
|
||||
sqlite3MemdebugSetType(p, MEMTYPE_DB |
|
||||
((db && db->lookaside.sz) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP)
|
||||
);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Allocate memory. This routine is like sqlite3_malloc() except that it
|
||||
** assumes the memory subsystem has already been initialized.
|
||||
*/
|
||||
void *sqlite3Malloc(int n){
|
||||
return memAllocate(0, sqlite3GlobalConfig.m.xMalloc, n);
|
||||
}
|
||||
|
||||
/*
|
||||
** Allocate and zero memory.
|
||||
*/
|
||||
void *sqlite3MallocZero(int n){
|
||||
return memAllocate(0, sqlite3GlobalConfig.m.xCalloc, n);
|
||||
}
|
||||
|
||||
/*
|
||||
** This version of the memory allocation is for use by the application.
|
||||
** First make sure the memory subsystem is initialized, then do the
|
||||
@@ -362,8 +406,11 @@ void *sqlite3ScratchMalloc(int n){
|
||||
}else{
|
||||
if( sqlite3GlobalConfig.bMemstat ){
|
||||
sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n);
|
||||
n = mallocWithAlarm(n, &p);
|
||||
if( p ) sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, n);
|
||||
p = mallocWithAlarm(sqlite3GlobalConfig.m.xMalloc, n);
|
||||
if( p ){
|
||||
n = sqlite3MallocSize(p);
|
||||
sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, n);
|
||||
}
|
||||
sqlite3_mutex_leave(mem0.mutex);
|
||||
}else{
|
||||
sqlite3_mutex_leave(mem0.mutex);
|
||||
@@ -570,33 +617,42 @@ void *sqlite3_realloc(void *pOld, int n){
|
||||
return sqlite3Realloc(pOld, n);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Allocate and zero memory.
|
||||
*/
|
||||
void *sqlite3MallocZero(int n){
|
||||
void *p = sqlite3Malloc(n);
|
||||
if( p ){
|
||||
memset(p, 0, n);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
** Allocate and zero memory. If the allocation fails, make
|
||||
** the mallocFailed flag in the connection pointer.
|
||||
** Attempt to allocate an n byte block from the lookaside buffer of
|
||||
** connection db. If successful, return a pointer to the new allocation.
|
||||
** Otherwise, return a NULL pointer.
|
||||
*/
|
||||
void *sqlite3DbMallocZero(sqlite3 *db, int n){
|
||||
void *p = sqlite3DbMallocRaw(db, n);
|
||||
if( p ){
|
||||
memset(p, 0, n);
|
||||
#ifndef SQLITE_OMIT_LOOKASIDE
|
||||
static void *lookasideAlloc(sqlite3 *db, int n){
|
||||
assert( db->lookaside.sz==0 || db->lookaside.sz==db->lookaside.szEnabled );
|
||||
if( n>db->lookaside.sz ){
|
||||
/* If db->lookaside.sz is 0, then the lookaside buffer is currently
|
||||
** disabled. In this case do not increment the "size misses" stat. */
|
||||
if( db->lookaside.sz ) db->lookaside.anStat[1]++;
|
||||
}else{
|
||||
LookasideSlot *pBuf;
|
||||
if( (pBuf = db->lookaside.pFree)==0 ){
|
||||
db->lookaside.anStat[2]++;
|
||||
}else{
|
||||
db->lookaside.pFree = pBuf->pNext;
|
||||
db->lookaside.nOut++;
|
||||
db->lookaside.anStat[0]++;
|
||||
if( db->lookaside.nOut>db->lookaside.mxOut ){
|
||||
db->lookaside.mxOut = db->lookaside.nOut;
|
||||
}
|
||||
}
|
||||
sqlite3MemdebugSetType((void *)pBuf, MEMTYPE_DB | MEMTYPE_LOOKASIDE);
|
||||
return (void*)pBuf;
|
||||
}
|
||||
return p;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
# define lookasideAlloc(x,y) 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Allocate and zero memory. If the allocation fails, make
|
||||
** the mallocFailed flag in the connection pointer.
|
||||
** Allocate and zero memory. If the allocation fails, set the
|
||||
** mallocFailed flag in the connection pointer.
|
||||
**
|
||||
** If db!=0 and db->mallocFailed is true (indicating a prior malloc
|
||||
** failure on the same database connection) then always return 0.
|
||||
@@ -612,44 +668,37 @@ void *sqlite3DbMallocZero(sqlite3 *db, int n){
|
||||
** In other words, if a subsequent malloc (ex: "b") worked, it is assumed
|
||||
** that all prior mallocs (ex: "a") worked too.
|
||||
*/
|
||||
void *sqlite3DbMallocZero(sqlite3 *db, int n){
|
||||
void *p;
|
||||
if( db ){
|
||||
if( db->mallocFailed ) return 0;
|
||||
if( (p = lookasideAlloc(db, n)) ){
|
||||
memset(p, 0, n);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
return memAllocate(db, sqlite3GlobalConfig.m.xCalloc, n);
|
||||
}
|
||||
|
||||
/*
|
||||
** Allocate memory. If the allocation fails, make the mallocFailed
|
||||
** flag in the connection pointer.
|
||||
**
|
||||
** If db!=0 and db->mallocFailed is true (indicating a prior malloc
|
||||
** failure on the same database connection) then always return 0.
|
||||
** See also comments above sqlite3DbMallocZero() for details.
|
||||
*/
|
||||
void *sqlite3DbMallocRaw(sqlite3 *db, int n){
|
||||
void *p;
|
||||
assert( db==0 || sqlite3_mutex_held(db->mutex) );
|
||||
assert( db==0 || db->pnBytesFreed==0 );
|
||||
#ifndef SQLITE_OMIT_LOOKASIDE
|
||||
if( db ){
|
||||
LookasideSlot *pBuf;
|
||||
if( db->mallocFailed ){
|
||||
return 0;
|
||||
}
|
||||
if( db->lookaside.bEnabled ){
|
||||
if( n>db->lookaside.sz ){
|
||||
db->lookaside.anStat[1]++;
|
||||
}else if( (pBuf = db->lookaside.pFree)==0 ){
|
||||
db->lookaside.anStat[2]++;
|
||||
}else{
|
||||
db->lookaside.pFree = pBuf->pNext;
|
||||
db->lookaside.nOut++;
|
||||
db->lookaside.anStat[0]++;
|
||||
if( db->lookaside.nOut>db->lookaside.mxOut ){
|
||||
db->lookaside.mxOut = db->lookaside.nOut;
|
||||
}
|
||||
return (void*)pBuf;
|
||||
}
|
||||
if( db->mallocFailed ) return 0;
|
||||
if( (p = lookasideAlloc(db, n)) ){
|
||||
return p;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if( db && db->mallocFailed ){
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
p = sqlite3Malloc(n);
|
||||
if( !p && db ){
|
||||
db->mallocFailed = 1;
|
||||
}
|
||||
sqlite3MemdebugSetType(p, MEMTYPE_DB |
|
||||
((db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
|
||||
return p;
|
||||
|
||||
return memAllocate(db, sqlite3GlobalConfig.m.xMalloc, n);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -665,12 +714,12 @@ void *sqlite3DbRealloc(sqlite3 *db, void *p, int n){
|
||||
return sqlite3DbMallocRaw(db, n);
|
||||
}
|
||||
if( isLookaside(db, p) ){
|
||||
if( n<=db->lookaside.sz ){
|
||||
if( n<=db->lookaside.szEnabled ){
|
||||
return p;
|
||||
}
|
||||
pNew = sqlite3DbMallocRaw(db, n);
|
||||
if( pNew ){
|
||||
memcpy(pNew, p, db->lookaside.sz);
|
||||
memcpy(pNew, p, db->lookaside.szEnabled);
|
||||
sqlite3DbFree(db, p);
|
||||
}
|
||||
}else{
|
||||
@@ -683,7 +732,7 @@ void *sqlite3DbRealloc(sqlite3 *db, void *p, int n){
|
||||
db->mallocFailed = 1;
|
||||
}
|
||||
sqlite3MemdebugSetType(pNew, MEMTYPE_DB |
|
||||
(db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
|
||||
(db->lookaside.sz ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
|
||||
}
|
||||
}
|
||||
return pNew;
|
||||
|
||||
+28
-19
@@ -70,6 +70,7 @@
|
||||
#include <libkern/OSAtomic.h>
|
||||
static malloc_zone_t* _sqliteZone_;
|
||||
#define SQLITE_MALLOC(x) malloc_zone_malloc(_sqliteZone_, (x))
|
||||
#define SQLITE_CALLOC(x) malloc_zone_calloc(_sqliteZone_, (x), 1)
|
||||
#define SQLITE_FREE(x) malloc_zone_free(_sqliteZone_, (x));
|
||||
#define SQLITE_REALLOC(x,y) malloc_zone_realloc(_sqliteZone_, (x), (y))
|
||||
#define SQLITE_MALLOCSIZE(x) \
|
||||
@@ -82,6 +83,7 @@ static malloc_zone_t* _sqliteZone_;
|
||||
** Also used by Apple systems if SQLITE_WITHOUT_ZONEMALLOC is defined.
|
||||
*/
|
||||
#define SQLITE_MALLOC(x) malloc(x)
|
||||
#define SQLITE_CALLOC(x) calloc((x), 1)
|
||||
#define SQLITE_FREE(x) free(x)
|
||||
#define SQLITE_REALLOC(x,y) realloc((x),(y))
|
||||
|
||||
@@ -100,8 +102,7 @@ static malloc_zone_t* _sqliteZone_;
|
||||
#endif /* __APPLE__ or not __APPLE__ */
|
||||
|
||||
/*
|
||||
** Like malloc(), but remember the size of the allocation
|
||||
** so that we can find it later using sqlite3MemSize().
|
||||
** Allocate nByte bytes of memory.
|
||||
**
|
||||
** For this low-level routine, we are guaranteed that nByte>0 because
|
||||
** cases of nByte<=0 will be intercepted and dealt with by higher level
|
||||
@@ -109,24 +110,31 @@ static malloc_zone_t* _sqliteZone_;
|
||||
*/
|
||||
static void *sqlite3MemMalloc(int nByte){
|
||||
#ifdef SQLITE_MALLOCSIZE
|
||||
void *p = SQLITE_MALLOC( nByte );
|
||||
if( p==0 ){
|
||||
testcase( sqlite3GlobalConfig.xLog!=0 );
|
||||
sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
|
||||
}
|
||||
return p;
|
||||
return SQLITE_MALLOC( ROUND8(nByte) );
|
||||
#else
|
||||
sqlite3_int64 *p;
|
||||
assert( nByte>0 );
|
||||
i64 *p;
|
||||
nByte = ROUND8(nByte);
|
||||
p = SQLITE_MALLOC( nByte+8 );
|
||||
if( p ){
|
||||
p[0] = nByte;
|
||||
p++;
|
||||
}else{
|
||||
testcase( sqlite3GlobalConfig.xLog!=0 );
|
||||
sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
|
||||
}
|
||||
p = SQLITE_MALLOC(nByte+8);
|
||||
if( p ) *(p++) = (i64)nByte;
|
||||
return (void *)p;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** Allocate and zero nByte bytes of memory.
|
||||
**
|
||||
** For this low-level routine, we are guaranteed that nByte>0 because
|
||||
** cases of nByte<=0 will be intercepted and dealt with by higher level
|
||||
** routines.
|
||||
*/
|
||||
static void *sqlite3MemCalloc(int nByte){
|
||||
#ifdef SQLITE_MALLOCSIZE
|
||||
return SQLITE_CALLOC( ROUND8(nByte) );
|
||||
#else
|
||||
i64 *p;
|
||||
nByte = ROUND8(nByte);
|
||||
p = SQLITE_CALLOC(nByte+8);
|
||||
if( p ) *(p++) = (i64)nByte;
|
||||
return (void *)p;
|
||||
#endif
|
||||
}
|
||||
@@ -271,7 +279,8 @@ void sqlite3MemSetDefault(void){
|
||||
sqlite3MemRoundup,
|
||||
sqlite3MemInit,
|
||||
sqlite3MemShutdown,
|
||||
0
|
||||
0,
|
||||
sqlite3MemCalloc
|
||||
};
|
||||
sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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 */
|
||||
+12
-2
@@ -56,7 +56,7 @@ struct sqlite3_mutex {
|
||||
** this out as well.
|
||||
*/
|
||||
#if 0
|
||||
#if SQLITE_OS_WINCE
|
||||
#if SQLITE_OS_WINCE || SQLITE_OS_WINRT
|
||||
# define mutexIsNT() (1)
|
||||
#else
|
||||
static int mutexIsNT(void){
|
||||
@@ -109,18 +109,24 @@ static int winMutex_isInit = 0;
|
||||
*/
|
||||
static long winMutex_lock = 0;
|
||||
|
||||
void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
|
||||
|
||||
static int winMutexInit(void){
|
||||
/* The first to increment to 1 does actual initialization */
|
||||
if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){
|
||||
int i;
|
||||
for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
|
||||
#if SQLITE_OS_WINRT
|
||||
InitializeCriticalSectionEx(&winMutex_staticMutexes[i].mutex, 0, 0);
|
||||
#else
|
||||
InitializeCriticalSection(&winMutex_staticMutexes[i].mutex);
|
||||
#endif
|
||||
}
|
||||
winMutex_isInit = 1;
|
||||
}else{
|
||||
/* Someone else is in the process of initing the static mutexes */
|
||||
while( !winMutex_isInit ){
|
||||
Sleep(1);
|
||||
sqlite3_win32_sleep(1);
|
||||
}
|
||||
}
|
||||
return SQLITE_OK;
|
||||
@@ -194,7 +200,11 @@ static sqlite3_mutex *winMutexAlloc(int iType){
|
||||
#ifdef SQLITE_DEBUG
|
||||
p->id = iType;
|
||||
#endif
|
||||
#if SQLITE_OS_WINRT
|
||||
InitializeCriticalSectionEx(&p->mutex, 0, 0);
|
||||
#else
|
||||
InitializeCriticalSection(&p->mutex);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -65,28 +56,8 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Define the maximum size of a temporary filename
|
||||
*/
|
||||
#if SQLITE_OS_WIN
|
||||
# include <windows.h>
|
||||
# define SQLITE_TEMPNAME_SIZE (MAX_PATH+50)
|
||||
#elif 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>
|
||||
# define SQLITE_TEMPNAME_SIZE (CCHMAXPATHCOMP)
|
||||
#else
|
||||
# define SQLITE_TEMPNAME_SIZE 200
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -120,6 +91,22 @@
|
||||
# define SQLITE_OS_WINCE 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Determine if we are dealing with WindowsRT (Metro) as this has a different and
|
||||
** incompatible API from win32.
|
||||
*/
|
||||
#if !defined(SQLITE_OS_WINRT)
|
||||
# define SQLITE_OS_WINRT 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
** When compiled for WinCE or WinRT, there is no concept of the current
|
||||
** directory.
|
||||
*/
|
||||
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
|
||||
# define SQLITE_CURDIR 1
|
||||
#endif
|
||||
|
||||
/* If the SET_FULLSYNC macro is not defined above, then make it
|
||||
** a no-op
|
||||
*/
|
||||
|
||||
-1924
File diff suppressed because it is too large
Load Diff
+21
-21
@@ -227,7 +227,7 @@ struct unixFile {
|
||||
#if OS_VXWORKS
|
||||
struct vxworksFileId *pId; /* Unique file ID */
|
||||
#endif
|
||||
#ifndef NDEBUG
|
||||
#ifdef SQLITE_DEBUG
|
||||
/* The next group of variables are used to track whether or not the
|
||||
** transaction counter in bytes 24-27 of database files are updated
|
||||
** whenever any part of the database changes. An assertion fault will
|
||||
@@ -262,7 +262,6 @@ struct unixFile {
|
||||
#define UNIXFILE_DELETE 0x20 /* Delete on close */
|
||||
#define UNIXFILE_URI 0x40 /* Filename might have query parameters */
|
||||
#define UNIXFILE_NOLOCK 0x80 /* Do no file locking */
|
||||
#define UNIXFILE_CHOWN 0x100 /* File ownership was changed */
|
||||
|
||||
/*
|
||||
** Include code that is common to all os_*.c files
|
||||
@@ -308,6 +307,15 @@ static int posixOpen(const char *zFile, int flags, int mode){
|
||||
return open(zFile, flags, mode);
|
||||
}
|
||||
|
||||
/*
|
||||
** On some systems, calls to fchown() will trigger a message in a security
|
||||
** log if they come from non-root processes. So avoid calling fchown() if
|
||||
** we are not running as root.
|
||||
*/
|
||||
static int posixFchown(int fd, uid_t uid, gid_t gid){
|
||||
return geteuid() ? 0 : fchown(fd,uid,gid);
|
||||
}
|
||||
|
||||
/* Forward reference */
|
||||
static int openDirectory(const char*, int*);
|
||||
|
||||
@@ -419,7 +427,7 @@ static struct unix_syscall {
|
||||
{ "rmdir", (sqlite3_syscall_ptr)rmdir, 0 },
|
||||
#define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent)
|
||||
|
||||
{ "fchown", (sqlite3_syscall_ptr)fchown, 0 },
|
||||
{ "fchown", (sqlite3_syscall_ptr)posixFchown, 0 },
|
||||
#define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
|
||||
|
||||
{ "umask", (sqlite3_syscall_ptr)umask, 0 },
|
||||
@@ -1563,7 +1571,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
|
||||
}
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
#ifdef SQLITE_DEBUG
|
||||
/* Set up the transaction-counter change checking flags when
|
||||
** transitioning from a SHARED to a RESERVED lock. The change
|
||||
** from SHARED to RESERVED marks the beginning of a normal
|
||||
@@ -1642,7 +1650,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
|
||||
if( pFile->eFileLock>SHARED_LOCK ){
|
||||
assert( pInode->eFileLock==pFile->eFileLock );
|
||||
|
||||
#ifndef NDEBUG
|
||||
#ifdef SQLITE_DEBUG
|
||||
/* When reducing a lock such that other processes can start
|
||||
** reading the database file again, make sure that the
|
||||
** transaction counter was updated if any part of the database
|
||||
@@ -2841,7 +2849,7 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) {
|
||||
SimulateIOError( h=(-1) )
|
||||
SimulateIOErrorBenign(0);
|
||||
|
||||
#ifndef NDEBUG
|
||||
#ifdef SQLITE_DEBUG
|
||||
/* When reducing a lock such that other processes can start
|
||||
** reading the database file again, make sure that the
|
||||
** transaction counter was updated if any part of the database
|
||||
@@ -3145,7 +3153,7 @@ static int unixWrite(
|
||||
);
|
||||
#endif
|
||||
|
||||
#ifndef NDEBUG
|
||||
#ifdef SQLITE_DEBUG
|
||||
/* If we are doing a normal write to a database file (as opposed to
|
||||
** doing a hot-journal rollback or a write to some file other than a
|
||||
** normal database file) then record the fact that the database
|
||||
@@ -3436,7 +3444,7 @@ static int unixTruncate(sqlite3_file *id, i64 nByte){
|
||||
pFile->lastErrno = errno;
|
||||
return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
|
||||
}else{
|
||||
#ifndef NDEBUG
|
||||
#ifdef SQLITE_DEBUG
|
||||
/* If we are doing a normal write to a database file (as opposed to
|
||||
** doing a hot-journal rollback or a write to some file other than a
|
||||
** normal database file) and we truncate the file to zero length,
|
||||
@@ -3593,7 +3601,7 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
|
||||
*(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
#ifdef SQLITE_DEBUG
|
||||
/* The pager calls this method to signal that it has done
|
||||
** a rollback and that the database is therefore unchanged and
|
||||
** it hence it is OK for the transaction change counter to be
|
||||
@@ -3944,14 +3952,9 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
|
||||
|
||||
/* If this process is running as root, make sure that the SHM file
|
||||
** is owned by the same user that owns the original database. Otherwise,
|
||||
** the original owner will not be able to connect. If this process is
|
||||
** not root, the following fchown() will fail, but we don't care. The
|
||||
** if(){..} and the UNIXFILE_CHOWN flag are purely to silence compiler
|
||||
** warnings.
|
||||
** the original owner will not be able to connect.
|
||||
*/
|
||||
if( osFchown(pShmNode->h, sStat.st_uid, sStat.st_gid)==0 ){
|
||||
pDbFd->ctrlFlags |= UNIXFILE_CHOWN;
|
||||
}
|
||||
osFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
|
||||
|
||||
/* Check to see if another process is holding the dead-man switch.
|
||||
** If not, truncate the file to zero length.
|
||||
@@ -5157,13 +5160,10 @@ static int unixOpen(
|
||||
|
||||
/* If this process is running as root and if creating a new rollback
|
||||
** journal or WAL file, set the ownership of the journal or WAL to be
|
||||
** the same as the original database. If we are not running as root,
|
||||
** then the fchown() call will fail, but that's ok. The "if(){}" and
|
||||
** the setting of the UNIXFILE_CHOWN flag are purely to silence compiler
|
||||
** warnings from gcc.
|
||||
** the same as the original database.
|
||||
*/
|
||||
if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
|
||||
if( osFchown(fd, uid, gid)==0 ){ p->ctrlFlags |= UNIXFILE_CHOWN; }
|
||||
osFchown(fd, uid, gid);
|
||||
}
|
||||
}
|
||||
assert( fd>=0 );
|
||||
|
||||
+770
-262
File diff suppressed because it is too large
Load Diff
+20
-8
@@ -4360,7 +4360,12 @@ int sqlite3PagerOpen(
|
||||
#ifndef SQLITE_OMIT_MEMORYDB
|
||||
if( flags & PAGER_MEMORY ){
|
||||
memDb = 1;
|
||||
zFilename = 0;
|
||||
if( zFilename && zFilename[0] ){
|
||||
zPathname = sqlite3DbStrDup(0, zFilename);
|
||||
if( zPathname==0 ) return SQLITE_NOMEM;
|
||||
nPathname = sqlite3Strlen30(zPathname);
|
||||
zFilename = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -4371,7 +4376,7 @@ int sqlite3PagerOpen(
|
||||
if( zFilename && zFilename[0] ){
|
||||
const char *z;
|
||||
nPathname = pVfs->mxPathname+1;
|
||||
zPathname = sqlite3Malloc(nPathname*2);
|
||||
zPathname = sqlite3DbMallocRaw(0, nPathname*2);
|
||||
if( zPathname==0 ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@@ -4395,7 +4400,7 @@ int sqlite3PagerOpen(
|
||||
rc = SQLITE_CANTOPEN_BKPT;
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3_free(zPathname);
|
||||
sqlite3DbFree(0, zPathname);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
@@ -4425,7 +4430,7 @@ int sqlite3PagerOpen(
|
||||
);
|
||||
assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
|
||||
if( !pPtr ){
|
||||
sqlite3_free(zPathname);
|
||||
sqlite3DbFree(0, zPathname);
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
pPager = (Pager*)(pPtr);
|
||||
@@ -4441,7 +4446,7 @@ int sqlite3PagerOpen(
|
||||
assert( nPathname>0 );
|
||||
pPager->zJournal = (char*)(pPtr += nPathname + 1 + nUri);
|
||||
memcpy(pPager->zFilename, zPathname, nPathname);
|
||||
memcpy(&pPager->zFilename[nPathname+1], zUri, nUri);
|
||||
if( nUri ) memcpy(&pPager->zFilename[nPathname+1], zUri, nUri);
|
||||
memcpy(pPager->zJournal, zPathname, nPathname);
|
||||
memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+1);
|
||||
sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal);
|
||||
@@ -4451,7 +4456,7 @@ int sqlite3PagerOpen(
|
||||
memcpy(&pPager->zWal[nPathname], "-wal\000", 4+1);
|
||||
sqlite3FileSuffix3(pPager->zFilename, pPager->zWal);
|
||||
#endif
|
||||
sqlite3_free(zPathname);
|
||||
sqlite3DbFree(0, zPathname);
|
||||
}
|
||||
pPager->pVfs = pVfs;
|
||||
pPager->vfsFlags = vfsFlags;
|
||||
@@ -6296,9 +6301,16 @@ int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){
|
||||
|
||||
/*
|
||||
** Return the full pathname of the database file.
|
||||
**
|
||||
** Except, if the pager is in-memory only, then return an empty string if
|
||||
** nullIfMemDb is true. This routine is called with nullIfMemDb==1 when
|
||||
** used to report the filename to the user, for compatibility with legacy
|
||||
** behavior. But when the Btree needs to know the filename for matching to
|
||||
** shared cache, it uses nullIfMemDb==0 so that in-memory databases can
|
||||
** participate in shared-cache.
|
||||
*/
|
||||
const char *sqlite3PagerFilename(Pager *pPager){
|
||||
return pPager->zFilename;
|
||||
const char *sqlite3PagerFilename(Pager *pPager, int nullIfMemDb){
|
||||
return (nullIfMemDb && pPager->memDb) ? "" : pPager->zFilename;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -151,7 +151,7 @@ int sqlite3PagerCloseWal(Pager *pPager);
|
||||
u8 sqlite3PagerIsreadonly(Pager*);
|
||||
int sqlite3PagerRefcount(Pager*);
|
||||
int sqlite3PagerMemUsed(Pager*);
|
||||
const char *sqlite3PagerFilename(Pager*);
|
||||
const char *sqlite3PagerFilename(Pager*, int);
|
||||
const sqlite3_vfs *sqlite3PagerVfs(Pager*);
|
||||
sqlite3_file *sqlite3PagerFile(Pager*);
|
||||
const char *sqlite3PagerJournalname(Pager*);
|
||||
|
||||
+2
-2
@@ -152,7 +152,7 @@ create_table ::= createkw temp(T) TABLE ifnotexists(E) nm(Y) dbnm(Z). {
|
||||
sqlite3StartTable(pParse,&Y,&Z,T,0,0,E);
|
||||
}
|
||||
createkw(A) ::= CREATE(X). {
|
||||
pParse->db->lookaside.bEnabled = 0;
|
||||
pParse->db->lookaside.sz = 0;
|
||||
A = X;
|
||||
}
|
||||
%type ifnotexists {int}
|
||||
@@ -1378,7 +1378,7 @@ cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column(Y). {
|
||||
sqlite3AlterFinishAddColumn(pParse, &Y);
|
||||
}
|
||||
add_column_fullname ::= fullname(X). {
|
||||
pParse->db->lookaside.bEnabled = 0;
|
||||
pParse->db->lookaside.sz = 0;
|
||||
sqlite3AlterBeginAddColumn(pParse, X);
|
||||
}
|
||||
kwcolumn_opt ::= .
|
||||
|
||||
@@ -212,12 +212,14 @@ static void *pcache1Alloc(int nByte){
|
||||
** it from sqlite3Malloc instead.
|
||||
*/
|
||||
p = sqlite3Malloc(nByte);
|
||||
#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
|
||||
if( p ){
|
||||
int sz = sqlite3MallocSize(p);
|
||||
sqlite3_mutex_enter(pcache1.mutex);
|
||||
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
|
||||
sqlite3_mutex_leave(pcache1.mutex);
|
||||
}
|
||||
#endif
|
||||
sqlite3MemdebugSetType(p, MEMTYPE_PCACHE);
|
||||
}
|
||||
return p;
|
||||
@@ -244,9 +246,11 @@ static int pcache1Free(void *p){
|
||||
assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
|
||||
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
|
||||
nFreed = sqlite3MallocSize(p);
|
||||
#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
|
||||
sqlite3_mutex_enter(pcache1.mutex);
|
||||
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -nFreed);
|
||||
sqlite3_mutex_leave(pcache1.mutex);
|
||||
#endif
|
||||
sqlite3_free(p);
|
||||
}
|
||||
return nFreed;
|
||||
|
||||
+60
-2
@@ -118,7 +118,7 @@ static int invalidateTempStorage(Parse *pParse){
|
||||
}
|
||||
sqlite3BtreeClose(db->aDb[1].pBt);
|
||||
db->aDb[1].pBt = 0;
|
||||
sqlite3ResetInternalSchema(db, -1);
|
||||
sqlite3ResetAllSchemasOfConnection(db);
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@@ -804,6 +804,50 @@ void sqlite3Pragma(
|
||||
}
|
||||
}else
|
||||
|
||||
#if SQLITE_OS_WIN
|
||||
/*
|
||||
** PRAGMA data_store_directory
|
||||
** PRAGMA data_store_directory = ""|"directory_name"
|
||||
**
|
||||
** Return or set the local value of the data_store_directory flag. Changing
|
||||
** the value sets a specific directory to be used for database files that
|
||||
** were specified with a relative pathname. Setting to a null string reverts
|
||||
** to the default database directory, which for database files specified with
|
||||
** a relative path will probably be based on the current directory for the
|
||||
** process. Database file specified with an absolute path are not impacted
|
||||
** by this setting, regardless of its value.
|
||||
**
|
||||
*/
|
||||
if( sqlite3StrICmp(zLeft, "data_store_directory")==0 ){
|
||||
if( !zRight ){
|
||||
if( sqlite3_data_directory ){
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME,
|
||||
"data_store_directory", SQLITE_STATIC);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, sqlite3_data_directory, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
|
||||
}
|
||||
}else{
|
||||
#ifndef SQLITE_OMIT_WSD
|
||||
if( zRight[0] ){
|
||||
int res;
|
||||
rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res);
|
||||
if( rc!=SQLITE_OK || res==0 ){
|
||||
sqlite3ErrorMsg(pParse, "not a writable directory");
|
||||
goto pragma_out;
|
||||
}
|
||||
}
|
||||
sqlite3_free(sqlite3_data_directory);
|
||||
if( zRight[0] ){
|
||||
sqlite3_data_directory = sqlite3_mprintf("%s", zRight);
|
||||
}else{
|
||||
sqlite3_data_directory = 0;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_WSD */
|
||||
}
|
||||
}else
|
||||
#endif
|
||||
|
||||
#if !defined(SQLITE_ENABLE_LOCKING_STYLE)
|
||||
# if defined(__APPLE__)
|
||||
# define SQLITE_ENABLE_LOCKING_STYLE 1
|
||||
@@ -1116,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;
|
||||
@@ -1139,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 */
|
||||
@@ -1150,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);
|
||||
|
||||
+4
-5
@@ -262,7 +262,6 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
|
||||
encoding = (u8)meta[BTREE_TEXT_ENCODING-1] & 3;
|
||||
if( encoding==0 ) encoding = SQLITE_UTF8;
|
||||
ENC(db) = encoding;
|
||||
db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0);
|
||||
}else{
|
||||
/* If opening an attached database, the encoding much match ENC(db) */
|
||||
if( meta[BTREE_TEXT_ENCODING-1]!=ENC(db) ){
|
||||
@@ -342,7 +341,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
|
||||
}
|
||||
if( db->mallocFailed ){
|
||||
rc = SQLITE_NOMEM;
|
||||
sqlite3ResetInternalSchema(db, -1);
|
||||
sqlite3ResetAllSchemasOfConnection(db);
|
||||
}
|
||||
if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){
|
||||
/* Black magic: If the SQLITE_RecoveryMode flag is set, then consider
|
||||
@@ -395,7 +394,7 @@ int sqlite3Init(sqlite3 *db, char **pzErrMsg){
|
||||
if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
|
||||
rc = sqlite3InitOne(db, i, pzErrMsg);
|
||||
if( rc ){
|
||||
sqlite3ResetInternalSchema(db, i);
|
||||
sqlite3ResetOneSchema(db, i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -408,7 +407,7 @@ int sqlite3Init(sqlite3 *db, char **pzErrMsg){
|
||||
&& !DbHasProperty(db, 1, DB_SchemaLoaded) ){
|
||||
rc = sqlite3InitOne(db, 1, pzErrMsg);
|
||||
if( rc ){
|
||||
sqlite3ResetInternalSchema(db, 1);
|
||||
sqlite3ResetOneSchema(db, 1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -476,7 +475,7 @@ static void schemaIsValid(Parse *pParse){
|
||||
sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie);
|
||||
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
|
||||
if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){
|
||||
sqlite3ResetInternalSchema(db, iDb);
|
||||
sqlite3ResetOneSchema(db, iDb);
|
||||
pParse->rc = SQLITE_SCHEMA;
|
||||
}
|
||||
|
||||
|
||||
+10
-6
@@ -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 ){
|
||||
|
||||
+3
-3
@@ -1398,9 +1398,9 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
|
||||
if( pTab==0 ){
|
||||
return 0;
|
||||
}
|
||||
/* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside
|
||||
** is disabled */
|
||||
assert( db->lookaside.bEnabled==0 );
|
||||
/* The sqlite3ResultSetOfSelect() should only used in contexts where the
|
||||
** lookaside buffer is disabled. */
|
||||
assert( db->lookaside.sz==0 );
|
||||
pTab->nRef = 1;
|
||||
pTab->zName = 0;
|
||||
pTab->nRowEst = 1000000;
|
||||
|
||||
+14
-18
@@ -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:";
|
||||
|
||||
+90
-30
@@ -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.
|
||||
@@ -473,6 +492,7 @@ int sqlite3_exec(
|
||||
#define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */
|
||||
#define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */
|
||||
#define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */
|
||||
#define SQLITE_OPEN_MEMORY 0x00000080 /* Ok for sqlite3_open_v2() */
|
||||
#define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */
|
||||
#define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */
|
||||
#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */
|
||||
@@ -1321,6 +1341,7 @@ struct sqlite3_mem_methods {
|
||||
int (*xInit)(void*); /* Initialize the memory allocator */
|
||||
void (*xShutdown)(void*); /* Deinitialize the memory allocator */
|
||||
void *pAppData; /* Argument to xInit() and xShutdown() */
|
||||
void *(*xCalloc)(int); /* Zeroed memory allocation function */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1557,8 +1578,8 @@ struct sqlite3_mem_methods {
|
||||
#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */
|
||||
#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */
|
||||
#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */
|
||||
#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */
|
||||
#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */
|
||||
#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* no xCalloc() */
|
||||
#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* no xCalloc() */
|
||||
/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */
|
||||
#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */
|
||||
#define SQLITE_CONFIG_PCACHE 14 /* no-op */
|
||||
@@ -1567,6 +1588,8 @@ struct sqlite3_mem_methods {
|
||||
#define SQLITE_CONFIG_URI 17 /* int */
|
||||
#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */
|
||||
#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */
|
||||
#define SQLITE_CONFIG_MALLOC2 20 /* sqlite3_mem_methods* incl xCalloc() */
|
||||
#define SQLITE_CONFIG_GETMALLOC2 21 /* sqlite3_mem_methods* incl xCalloc() */
|
||||
|
||||
/*
|
||||
** CAPI3REF: Database Connection Configuration Options
|
||||
@@ -2164,12 +2187,12 @@ char *sqlite3_vsnprintf(int,char*,const char*, va_list);
|
||||
** implementation of these routines to be omitted. That capability
|
||||
** is no longer provided. Only built-in memory allocators can be used.
|
||||
**
|
||||
** The Windows OS interface layer calls
|
||||
** Prior to SQLite version 3.7.10, the Windows OS interface layer called
|
||||
** the system malloc() and free() directly when converting
|
||||
** filenames between the UTF-8 encoding used by SQLite
|
||||
** and whatever filename encoding is used by the particular Windows
|
||||
** installation. Memory allocation errors are detected, but
|
||||
** they are reported back as [SQLITE_CANTOPEN] or
|
||||
** installation. Memory allocation errors were detected, but
|
||||
** they were reported back as [SQLITE_CANTOPEN] or
|
||||
** [SQLITE_IOERR] rather than [SQLITE_NOMEM].
|
||||
**
|
||||
** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()]
|
||||
@@ -2570,18 +2593,20 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
|
||||
** present, then the VFS specified by the option takes precedence over
|
||||
** the value passed as the fourth parameter to sqlite3_open_v2().
|
||||
**
|
||||
** <li> <b>mode</b>: ^(The mode parameter may be set to either "ro", "rw" or
|
||||
** "rwc". Attempting to set it to any other value is an error)^.
|
||||
** <li> <b>mode</b>: ^(The mode parameter may be set to either "ro", "rw",
|
||||
** "rwc", or "memory". Attempting to set it to any other value is
|
||||
** an error)^.
|
||||
** ^If "ro" is specified, then the database is opened for read-only
|
||||
** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the
|
||||
** third argument to sqlite3_prepare_v2(). ^If the mode option is set to
|
||||
** "rw", then the database is opened for read-write (but not create)
|
||||
** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had
|
||||
** been set. ^Value "rwc" is equivalent to setting both
|
||||
** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If sqlite3_open_v2() is
|
||||
** used, it is an error to specify a value for the mode parameter that is
|
||||
** less restrictive than that specified by the flags passed as the third
|
||||
** parameter.
|
||||
** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If the mode option is
|
||||
** set to "memory" then a pure [in-memory database] that never reads
|
||||
** or writes from disk is used. ^It is an error to specify a value for
|
||||
** the mode parameter that is less restrictive than that specified by
|
||||
** the flags passed in the third parameter to sqlite3_open_v2().
|
||||
**
|
||||
** <li> <b>cache</b>: ^The cache parameter may be set to either "shared" or
|
||||
** "private". ^Setting it to "shared" is equivalent to setting the
|
||||
@@ -4444,6 +4469,43 @@ int sqlite3_sleep(int);
|
||||
*/
|
||||
SQLITE_EXTERN char *sqlite3_temp_directory;
|
||||
|
||||
/*
|
||||
** CAPI3REF: Name Of The Folder Holding Database Files
|
||||
**
|
||||
** ^(If this global variable is made to point to a string which is
|
||||
** the name of a folder (a.k.a. directory), then all database files
|
||||
** specified with a relative pathname and created or accessed by
|
||||
** SQLite when using a built-in windows [sqlite3_vfs | VFS] will be assumed
|
||||
** to be relative to that directory.)^ ^If this variable is a NULL
|
||||
** pointer, then SQLite assumes that all database files specified
|
||||
** with a relative pathname are relative to the current directory
|
||||
** for the process. Only the windows VFS makes use of this global
|
||||
** variable; it is ignored by the unix VFS.
|
||||
**
|
||||
** Changing the value of this variable while a database connection is
|
||||
** open can result in a corrupt database.
|
||||
**
|
||||
** It is not safe to read or modify this variable in more than one
|
||||
** thread at a time. It is not safe to read or modify this variable
|
||||
** if a [database connection] is being used at the same time in a separate
|
||||
** thread.
|
||||
** It is intended that this variable be set once
|
||||
** as part of process initialization and before any SQLite interface
|
||||
** routines have been called and that this variable remain unchanged
|
||||
** thereafter.
|
||||
**
|
||||
** ^The [data_store_directory pragma] may modify this variable and cause
|
||||
** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore,
|
||||
** the [data_store_directory pragma] always assumes that any string
|
||||
** that this variable points to is held in memory obtained from
|
||||
** [sqlite3_malloc] and the pragma may attempt to free that memory
|
||||
** using [sqlite3_free].
|
||||
** Hence, if this variable is modified directly, either it should be
|
||||
** made NULL or made to point to memory obtained from [sqlite3_malloc]
|
||||
** or else the use of the [data_store_directory pragma] should be avoided.
|
||||
*/
|
||||
SQLITE_EXTERN char *sqlite3_data_directory;
|
||||
|
||||
/*
|
||||
** CAPI3REF: Test For Auto-Commit Mode
|
||||
** KEYWORDS: {autocommit mode}
|
||||
@@ -4622,7 +4684,6 @@ void *sqlite3_update_hook(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Enable Or Disable Shared Pager Cache
|
||||
** KEYWORDS: {shared cache}
|
||||
**
|
||||
** ^(This routine enables or disables the sharing of the database cache
|
||||
** and schema data structures between [database connection | connections]
|
||||
@@ -5450,7 +5511,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
|
||||
@@ -5458,9 +5518,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
|
||||
|
||||
+35
-12
@@ -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
|
||||
|
||||
@@ -203,15 +212,22 @@
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Many people are failing to set -DNDEBUG=1 when compiling SQLite.
|
||||
** Setting NDEBUG makes the code smaller and run faster. So the following
|
||||
** lines are added to automatically set NDEBUG unless the -DSQLITE_DEBUG=1
|
||||
** option is set. Thus NDEBUG becomes an opt-in rather than an opt-out
|
||||
** NDEBUG and SQLITE_DEBUG are opposites. It should always be true that
|
||||
** defined(NDEBUG)==!defined(SQLITE_DEBUG). If this is not currently true,
|
||||
** make it true by defining or undefining NDEBUG.
|
||||
**
|
||||
** Setting NDEBUG makes the code smaller and run faster by disabling the
|
||||
** number assert() statements in the code. So we want the default action
|
||||
** to be for NDEBUG to be set and NDEBUG to be undefined only if SQLITE_DEBUG
|
||||
** is set. Thus NDEBUG becomes an opt-in rather than an opt-out
|
||||
** feature.
|
||||
*/
|
||||
#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
|
||||
# define NDEBUG 1
|
||||
#endif
|
||||
#if defined(NDEBUG) && defined(SQLITE_DEBUG)
|
||||
# undef NDEBUG
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The testcase() macro is used to aid in coverage testing. When
|
||||
@@ -767,12 +783,14 @@ struct Schema {
|
||||
** with a particular database connection. Hence, schema information cannot
|
||||
** be stored in lookaside because in shared cache mode the schema information
|
||||
** is shared by multiple database connections. Therefore, while parsing
|
||||
** schema information, the Lookaside.bEnabled flag is cleared so that
|
||||
** lookaside allocations are not used to construct the schema objects.
|
||||
** schema information, the Lookaside.sz variable is temporarily set to
|
||||
** zero so that lookaside allocations are not used to construct the schema
|
||||
** objects. Lookaside.szEnabled always contains the allocation size that
|
||||
** Lookaside.sz is set to when the buffer is enabled.
|
||||
*/
|
||||
struct Lookaside {
|
||||
u16 sz; /* Size of each buffer in bytes */
|
||||
u8 bEnabled; /* False to disable new lookaside allocations */
|
||||
u16 szEnabled; /* Value of 'sz' when buffer is enabled. */
|
||||
u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */
|
||||
int nOut; /* Number of buffers currently checked out */
|
||||
int mxOut; /* Highwater mark for nOut */
|
||||
@@ -967,6 +985,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
|
||||
@@ -2702,7 +2721,9 @@ void sqlite3ExprListDelete(sqlite3*, ExprList*);
|
||||
int sqlite3Init(sqlite3*, char**);
|
||||
int sqlite3InitCallback(void*, int, char**, char**);
|
||||
void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
|
||||
void sqlite3ResetInternalSchema(sqlite3*, int);
|
||||
void sqlite3ResetAllSchemasOfConnection(sqlite3*);
|
||||
void sqlite3ResetOneSchema(sqlite3*,int);
|
||||
void sqlite3CollapseDatabaseArray(sqlite3*);
|
||||
void sqlite3BeginParse(Parse*,int);
|
||||
void sqlite3CommitInternalChanges(sqlite3*);
|
||||
Table *sqlite3ResultSetOfSelect(Parse*,Select*);
|
||||
@@ -2826,6 +2847,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*);
|
||||
@@ -3107,6 +3129,7 @@ void sqlite3AutoLoadExtensions(sqlite3*);
|
||||
# define sqlite3GetVTable(X,Y) ((VTable*)0)
|
||||
#else
|
||||
void sqlite3VtabClear(sqlite3 *db, Table*);
|
||||
void sqlite3VtabDisconnect(sqlite3 *db, Table *p);
|
||||
int sqlite3VtabSync(sqlite3 *db, char **);
|
||||
int sqlite3VtabRollback(sqlite3 *db);
|
||||
int sqlite3VtabCommit(sqlite3 *db);
|
||||
|
||||
@@ -6287,6 +6287,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
(char*)&sqlite_static_bind_nbyte, TCL_LINK_INT);
|
||||
Tcl_LinkVar(interp, "sqlite_temp_directory",
|
||||
(char*)&sqlite3_temp_directory, TCL_LINK_STRING);
|
||||
Tcl_LinkVar(interp, "sqlite_data_directory",
|
||||
(char*)&sqlite3_data_directory, TCL_LINK_STRING);
|
||||
Tcl_LinkVar(interp, "bitmask_size",
|
||||
(char*)&bitmask_size, TCL_LINK_INT|TCL_LINK_READ_ONLY);
|
||||
Tcl_LinkVar(interp, "sqlite_sync_count",
|
||||
|
||||
+40
-8
@@ -1300,6 +1300,7 @@ static sqlite3_module echoModuleV2 = {
|
||||
** Decode a pointer to an sqlite3 object.
|
||||
*/
|
||||
extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb);
|
||||
extern const char *sqlite3TestErrorName(int rc);
|
||||
|
||||
static void moduleDestroy(void *p){
|
||||
sqlite3_free(p);
|
||||
@@ -1314,6 +1315,7 @@ static int register_echo_module(
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
int rc;
|
||||
sqlite3 *db;
|
||||
EchoModule *pMod;
|
||||
if( objc!=2 ){
|
||||
@@ -1325,14 +1327,20 @@ static int register_echo_module(
|
||||
/* Virtual table module "echo" */
|
||||
pMod = sqlite3_malloc(sizeof(EchoModule));
|
||||
pMod->interp = interp;
|
||||
sqlite3_create_module_v2(db, "echo", &echoModule, (void*)pMod, moduleDestroy);
|
||||
rc = sqlite3_create_module_v2(
|
||||
db, "echo", &echoModule, (void*)pMod, moduleDestroy
|
||||
);
|
||||
|
||||
/* Virtual table module "echo_v2" */
|
||||
pMod = sqlite3_malloc(sizeof(EchoModule));
|
||||
pMod->interp = interp;
|
||||
sqlite3_create_module_v2(db, "echo_v2",
|
||||
&echoModuleV2, (void*)pMod, moduleDestroy
|
||||
);
|
||||
if( rc==SQLITE_OK ){
|
||||
pMod = sqlite3_malloc(sizeof(EchoModule));
|
||||
pMod->interp = interp;
|
||||
rc = sqlite3_create_module_v2(db, "echo_v2",
|
||||
&echoModuleV2, (void*)pMod, moduleDestroy
|
||||
);
|
||||
}
|
||||
|
||||
Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_STATIC);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -1362,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 */
|
||||
|
||||
/*
|
||||
@@ -1374,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++){
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ int sqlite3BtreeSharedCacheReport(
|
||||
BtShared *pBt;
|
||||
Tcl_Obj *pRet = Tcl_NewObj();
|
||||
for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){
|
||||
const char *zFile = sqlite3PagerFilename(pBt->pPager);
|
||||
const char *zFile = sqlite3PagerFilename(pBt->pPager, 1);
|
||||
Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(zFile, -1));
|
||||
Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(pBt->nRef));
|
||||
}
|
||||
|
||||
+24
-3
@@ -57,6 +57,12 @@ static void set_options(Tcl_Interp *interp){
|
||||
Tcl_SetVar2(interp, "sqlite_options","casesensitivelike","0",TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_CURDIR
|
||||
Tcl_SetVar2(interp, "sqlite_options", "curdir", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "curdir", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
Tcl_SetVar2(interp, "sqlite_options", "debug", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
@@ -307,10 +313,10 @@ static void set_options(Tcl_Interp *interp){
|
||||
Tcl_SetVar2(interp, "sqlite_options", "fts3", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#if !defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_DISABLE_FTS3_UNICODE)
|
||||
Tcl_SetVar2(interp, "sqlite_options", "fts3_unicode", "0", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
#if defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_ENABLE_FTS4_UNICODE61)
|
||||
Tcl_SetVar2(interp, "sqlite_options", "fts3_unicode", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "fts3_unicode", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_OMIT_GET_TABLE
|
||||
@@ -610,6 +616,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;
|
||||
|
||||
|
||||
+79
-14
@@ -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
|
||||
@@ -1042,7 +1032,7 @@ size_t sqlite3_quota_fread(
|
||||
** the write if we exceed quota.
|
||||
*/
|
||||
size_t sqlite3_quota_fwrite(
|
||||
void *pBuf, /* Take content to write from here */
|
||||
const void *pBuf, /* Take content to write from here */
|
||||
size_t size, /* Size of each element */
|
||||
size_t nmemb, /* Number of elements */
|
||||
quota_FILE *p /* Write to this quota_FILE objecct */
|
||||
@@ -1052,7 +1042,7 @@ size_t sqlite3_quota_fwrite(
|
||||
sqlite3_int64 szNew;
|
||||
quotaFile *pFile;
|
||||
size_t rc;
|
||||
|
||||
|
||||
iOfst = ftell(p->f);
|
||||
iEnd = iOfst + size*nmemb;
|
||||
pFile = p->pFile;
|
||||
@@ -1091,7 +1081,7 @@ size_t sqlite3_quota_fwrite(
|
||||
pFile->iSize = iNewEnd;
|
||||
quotaLeave();
|
||||
}
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1160,6 +1150,13 @@ long sqlite3_quota_ftell(quota_FILE *p){
|
||||
return ftell(p->f);
|
||||
}
|
||||
|
||||
/*
|
||||
** Test the error indicator for the given file.
|
||||
*/
|
||||
int sqlite3_quota_ferror(quota_FILE *p){
|
||||
return ferror(p->f);
|
||||
}
|
||||
|
||||
/*
|
||||
** Truncate a file to szNew bytes.
|
||||
*/
|
||||
@@ -1236,6 +1233,25 @@ sqlite3_int64 sqlite3_quota_file_truesize(quota_FILE *p){
|
||||
sqlite3_int64 sqlite3_quota_file_size(quota_FILE *p){
|
||||
return p->pFile ? p->pFile->iSize : -1;
|
||||
}
|
||||
|
||||
/*
|
||||
** Determine the amount of data in bytes available for reading
|
||||
** in the given file.
|
||||
*/
|
||||
long sqlite3_quota_file_available(quota_FILE *p){
|
||||
FILE* f = p->f;
|
||||
long pos1, pos2;
|
||||
int rc;
|
||||
pos1 = ftell(f);
|
||||
if ( pos1 < 0 ) return -1;
|
||||
rc = fseek(f, 0, SEEK_END);
|
||||
if ( rc != 0 ) return -1;
|
||||
pos2 = ftell(f);
|
||||
if ( pos2 < 0 ) return -1;
|
||||
rc = fseek(f, pos1, SEEK_SET);
|
||||
if ( rc != 0 ) return -1;
|
||||
return pos2 - pos1;
|
||||
}
|
||||
|
||||
/*
|
||||
** Remove a managed file. Update quotas accordingly.
|
||||
@@ -1895,6 +1911,53 @@ static int test_quota_glob(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** tclcmd: sqlite3_quota_file_available HANDLE
|
||||
**
|
||||
** Return the number of bytes from the current file point to the end of
|
||||
** the file.
|
||||
*/
|
||||
static int test_quota_file_available(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
quota_FILE *p;
|
||||
sqlite3_int64 x;
|
||||
if( objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "HANDLE");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
p = sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
|
||||
x = sqlite3_quota_file_available(p);
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(x));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** tclcmd: sqlite3_quota_ferror HANDLE
|
||||
**
|
||||
** Return true if the file handle is in the error state.
|
||||
*/
|
||||
static int test_quota_ferror(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
quota_FILE *p;
|
||||
int x;
|
||||
if( objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "HANDLE");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
p = sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
|
||||
x = sqlite3_quota_ferror(p);
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(x));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine registers the custom TCL commands defined in this
|
||||
** module. This should be the only procedure visible from outside
|
||||
@@ -1924,6 +1987,8 @@ int Sqlitequota_Init(Tcl_Interp *interp){
|
||||
{ "sqlite3_quota_file_mtime", test_quota_file_mtime },
|
||||
{ "sqlite3_quota_remove", test_quota_remove },
|
||||
{ "sqlite3_quota_glob", test_quota_glob },
|
||||
{ "sqlite3_quota_file_available",test_quota_file_available },
|
||||
{ "sqlite3_quota_ferror", test_quota_ferror },
|
||||
};
|
||||
int i;
|
||||
|
||||
|
||||
+17
-2
@@ -162,7 +162,7 @@ quota_FILE *sqlite3_quota_fopen(const char *zFilename, const char *zMode);
|
||||
** the sum of sizes of all files from going over quota.
|
||||
*/
|
||||
size_t sqlite3_quota_fread(void*, size_t, size_t, quota_FILE*);
|
||||
size_t sqlite3_quota_fwrite(void*, size_t, size_t, quota_FILE*);
|
||||
size_t sqlite3_quota_fwrite(const void*, size_t, size_t, quota_FILE*);
|
||||
|
||||
/*
|
||||
** Flush all written content held in memory buffers out to disk.
|
||||
@@ -190,6 +190,13 @@ int sqlite3_quota_fseek(quota_FILE*, long, int);
|
||||
void sqlite3_quota_rewind(quota_FILE*);
|
||||
long sqlite3_quota_ftell(quota_FILE*);
|
||||
|
||||
/*
|
||||
** Test the error indicator for the given file.
|
||||
**
|
||||
** Return non-zero if the error indicator is set.
|
||||
*/
|
||||
int sqlite3_quota_ferror(quota_FILE*);
|
||||
|
||||
/*
|
||||
** Truncate a file previously opened by sqlite3_quota_fopen(). Return
|
||||
** zero on success and non-zero on any kind of failure.
|
||||
@@ -198,7 +205,7 @@ long sqlite3_quota_ftell(quota_FILE*);
|
||||
** Any attempt to "truncate" a file to a larger size results in
|
||||
** undefined behavior.
|
||||
*/
|
||||
int sqlite3_quota_ftrunate(quota_FILE*, sqlite3_int64 newSize);
|
||||
int sqlite3_quota_ftruncate(quota_FILE*, sqlite3_int64 newSize);
|
||||
|
||||
/*
|
||||
** Return the last modification time of the opened file, in seconds
|
||||
@@ -232,6 +239,14 @@ sqlite3_int64 sqlite3_quota_file_size(quota_FILE*);
|
||||
*/
|
||||
sqlite3_int64 sqlite3_quota_file_truesize(quota_FILE*);
|
||||
|
||||
/*
|
||||
** Determine the amount of data in bytes available for reading
|
||||
** in the given file.
|
||||
**
|
||||
** Return -1 if the amount cannot be determined for some reason.
|
||||
*/
|
||||
long sqlite3_quota_file_available(quota_FILE*);
|
||||
|
||||
/*
|
||||
** Delete a file from the disk, if that file is under quota management.
|
||||
** Adjust quotas accordingly.
|
||||
|
||||
+1415
-183
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] */
|
||||
|
||||
@@ -760,6 +761,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 +822,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 +870,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 +929,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 +951,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 +1369,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 +1385,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 +1407,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 +1454,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);
|
||||
|
||||
+6
-4
@@ -390,7 +390,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
void *pEngine; /* The LEMON-generated LALR(1) parser */
|
||||
int tokenType; /* type of the next token */
|
||||
int lastTokenParsed = -1; /* type of the previous token */
|
||||
u8 enableLookaside; /* Saved value of db->lookaside.bEnabled */
|
||||
u16 lookasideSz; /* Saved value of db->lookaside.sz */
|
||||
sqlite3 *db = pParse->db; /* The database connection */
|
||||
int mxSqlLen; /* Max length of an SQL string */
|
||||
|
||||
@@ -413,8 +413,10 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
assert( pParse->nVar==0 );
|
||||
assert( pParse->nzVar==0 );
|
||||
assert( pParse->azVar==0 );
|
||||
enableLookaside = db->lookaside.bEnabled;
|
||||
if( db->lookaside.pStart ) db->lookaside.bEnabled = 1;
|
||||
lookasideSz = db->lookaside.sz;
|
||||
if( db->lookaside.pStart ){
|
||||
db->lookaside.sz = db->lookaside.szEnabled;
|
||||
}
|
||||
while( !db->mallocFailed && zSql[i]!=0 ){
|
||||
assert( i>=0 );
|
||||
pParse->sLastToken.z = &zSql[i];
|
||||
@@ -468,7 +470,7 @@ abort_parse:
|
||||
);
|
||||
#endif /* YYDEBUG */
|
||||
sqlite3ParserFree(pEngine, sqlite3_free);
|
||||
db->lookaside.bEnabled = enableLookaside;
|
||||
db->lookaside.sz = lookasideSz;
|
||||
if( db->mallocFailed ){
|
||||
pParse->rc = SQLITE_NOMEM;
|
||||
}
|
||||
|
||||
+1
-1
@@ -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; }
|
||||
|
||||
+1
-1
@@ -339,7 +339,7 @@ end_of_vacuum:
|
||||
|
||||
/* This both clears the schemas and reduces the size of the db->aDb[]
|
||||
** array. */
|
||||
sqlite3ResetInternalSchema(db, -1);
|
||||
sqlite3ResetAllSchemasOfConnection(db);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
+5
-6
@@ -2747,7 +2747,7 @@ case OP_Savepoint: {
|
||||
}
|
||||
if( p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
|
||||
sqlite3ExpirePreparedStatements(db);
|
||||
sqlite3ResetInternalSchema(db, -1);
|
||||
sqlite3ResetAllSchemasOfConnection(db);
|
||||
db->flags = (db->flags | SQLITE_InternChanges);
|
||||
}
|
||||
}
|
||||
@@ -3051,7 +3051,7 @@ case OP_VerifyCookie: {
|
||||
** a v-table method.
|
||||
*/
|
||||
if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){
|
||||
sqlite3ResetInternalSchema(db, pOp->p1);
|
||||
sqlite3ResetOneSchema(db, pOp->p1);
|
||||
}
|
||||
|
||||
p->expired = 1;
|
||||
@@ -4214,7 +4214,6 @@ case OP_RowData: {
|
||||
assert( pC!=0 );
|
||||
assert( pC->nullRow==0 );
|
||||
assert( pC->pseudoTableReg==0 );
|
||||
assert( !pC->isSorter );
|
||||
assert( pC->pCursor!=0 );
|
||||
pCrsr = pC->pCursor;
|
||||
assert( sqlite3BtreeCursorIsValid(pCrsr) );
|
||||
@@ -4864,7 +4863,7 @@ case OP_ParseSchema: {
|
||||
db->init.busy = 0;
|
||||
}
|
||||
}
|
||||
if( rc ) sqlite3ResetInternalSchema(db, -1);
|
||||
if( rc ) sqlite3ResetAllSchemasOfConnection(db);
|
||||
if( rc==SQLITE_NOMEM ){
|
||||
goto no_mem;
|
||||
}
|
||||
@@ -5511,7 +5510,7 @@ case OP_JournalMode: { /* out2-prerelease */
|
||||
if( !sqlite3PagerOkToChangeJournalMode(pPager) ) eNew = eOld;
|
||||
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
zFilename = sqlite3PagerFilename(pPager);
|
||||
zFilename = sqlite3PagerFilename(pPager, 1);
|
||||
|
||||
/* Do not allow a transition to journal_mode=WAL for a database
|
||||
** in temporary storage or if the VFS does not support shared memory
|
||||
@@ -6159,7 +6158,7 @@ vdbe_error_halt:
|
||||
if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
|
||||
rc = SQLITE_ERROR;
|
||||
if( resetSchemaOnFault>0 ){
|
||||
sqlite3ResetInternalSchema(db, resetSchemaOnFault-1);
|
||||
sqlite3ResetOneSchema(db, resetSchemaOnFault-1);
|
||||
}
|
||||
|
||||
/* This is the only way out of this procedure. We have to
|
||||
|
||||
+2
-8
@@ -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;
|
||||
}
|
||||
|
||||
@@ -2469,6 +2469,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{
|
||||
|
||||
+51
-24
@@ -22,8 +22,8 @@
|
||||
** are invoked only from within xCreate and xConnect methods.
|
||||
*/
|
||||
struct VtabCtx {
|
||||
Table *pTab;
|
||||
VTable *pVTable;
|
||||
VTable *pVTable; /* The virtual table being constructed */
|
||||
Table *pTab; /* The Table object to which the virtual table belongs */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -38,33 +38,35 @@ static int createModule(
|
||||
void *pAux, /* Context pointer for xCreate/xConnect */
|
||||
void (*xDestroy)(void *) /* Module destructor function */
|
||||
){
|
||||
int rc, nName;
|
||||
Module *pMod;
|
||||
int rc = SQLITE_OK;
|
||||
int nName;
|
||||
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
nName = sqlite3Strlen30(zName);
|
||||
pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1);
|
||||
if( pMod ){
|
||||
Module *pDel;
|
||||
char *zCopy = (char *)(&pMod[1]);
|
||||
memcpy(zCopy, zName, nName+1);
|
||||
pMod->zName = zCopy;
|
||||
pMod->pModule = pModule;
|
||||
pMod->pAux = pAux;
|
||||
pMod->xDestroy = xDestroy;
|
||||
pDel = (Module *)sqlite3HashInsert(&db->aModule, zCopy, nName, (void*)pMod);
|
||||
if( pDel && pDel->xDestroy ){
|
||||
sqlite3ResetInternalSchema(db, -1);
|
||||
pDel->xDestroy(pDel->pAux);
|
||||
if( sqlite3HashFind(&db->aModule, zName, nName) ){
|
||||
rc = SQLITE_MISUSE_BKPT;
|
||||
}else{
|
||||
Module *pMod;
|
||||
pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1);
|
||||
if( pMod ){
|
||||
Module *pDel;
|
||||
char *zCopy = (char *)(&pMod[1]);
|
||||
memcpy(zCopy, zName, nName+1);
|
||||
pMod->zName = zCopy;
|
||||
pMod->pModule = pModule;
|
||||
pMod->pAux = pAux;
|
||||
pMod->xDestroy = xDestroy;
|
||||
pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,nName,(void*)pMod);
|
||||
assert( pDel==0 || pDel==pMod );
|
||||
if( pDel ){
|
||||
db->mallocFailed = 1;
|
||||
sqlite3DbFree(db, pDel);
|
||||
}
|
||||
}
|
||||
sqlite3DbFree(db, pDel);
|
||||
if( pDel==pMod ){
|
||||
db->mallocFailed = 1;
|
||||
}
|
||||
}else if( xDestroy ){
|
||||
xDestroy(pAux);
|
||||
}
|
||||
rc = sqlite3ApiExit(db, SQLITE_OK);
|
||||
rc = sqlite3ApiExit(db, rc);
|
||||
if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux);
|
||||
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return rc;
|
||||
}
|
||||
@@ -180,6 +182,31 @@ static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){
|
||||
return pRet;
|
||||
}
|
||||
|
||||
/*
|
||||
** Table *p is a virtual table. This function removes the VTable object
|
||||
** for table *p associated with database connection db from the linked
|
||||
** list in p->pVTab. It also decrements the VTable ref count. This is
|
||||
** used when closing database connection db to free all of its VTable
|
||||
** objects without disturbing the rest of the Schema object (which may
|
||||
** be being used by other shared-cache connections).
|
||||
*/
|
||||
void sqlite3VtabDisconnect(sqlite3 *db, Table *p){
|
||||
VTable **ppVTab;
|
||||
|
||||
assert( IsVirtual(p) );
|
||||
assert( sqlite3BtreeHoldsAllMutexes(db) );
|
||||
assert( sqlite3_mutex_held(db->mutex) );
|
||||
|
||||
for(ppVTab=&p->pVTable; *ppVTab; ppVTab=&(*ppVTab)->pNext){
|
||||
if( (*ppVTab)->db==db ){
|
||||
VTable *pVTab = *ppVTab;
|
||||
*ppVTab = pVTab->pNext;
|
||||
sqlite3VtabUnlock(pVTab);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Disconnect all the virtual table objects in the sqlite3.pDisconnect list.
|
||||
|
||||
@@ -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 ){
|
||||
|
||||
@@ -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
|
||||
+1
-1
@@ -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}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
# $Id: bigfile.test,v 1.12 2009/03/05 04:27:08 shane Exp $
|
||||
#
|
||||
|
||||
if {[file exists skip-big-file]} return
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
# files larger than 4GB.
|
||||
#
|
||||
|
||||
if {[file exists skip-big-file]} return
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix bigfile2
|
||||
|
||||
+9
-2
@@ -649,13 +649,18 @@ do_test capi3-6.1 {
|
||||
db cache flush
|
||||
sqlite3_close $DB
|
||||
} {SQLITE_BUSY}
|
||||
|
||||
# 6.2 and 6.3 used to return SQLITE_ERROR and SQLITE_SCHEMA, respectively.
|
||||
# But since attempting to close a connection no longer resets the internal
|
||||
# schema and expires all statements, this is no longer the case.
|
||||
do_test capi3-6.2 {
|
||||
sqlite3_step $STMT
|
||||
} {SQLITE_ERROR}
|
||||
} {SQLITE_ROW}
|
||||
#check_data $STMT capi3-6.3 {INTEGER} {1} {1.0} {1}
|
||||
do_test capi3-6.3 {
|
||||
sqlite3_finalize $STMT
|
||||
} {SQLITE_SCHEMA}
|
||||
} {SQLITE_OK}
|
||||
|
||||
do_test capi3-6.4-misuse {
|
||||
db cache flush
|
||||
sqlite3_close $DB
|
||||
@@ -778,6 +783,7 @@ foreach {code english} $code2english {
|
||||
}
|
||||
|
||||
# Test the error message when a "real" out of memory occurs.
|
||||
if { [permutation] != "nofaultsim" } {
|
||||
ifcapable memdebug {
|
||||
do_test capi3-10-1 {
|
||||
sqlite3 db test.db
|
||||
@@ -816,6 +822,7 @@ ifcapable memdebug {
|
||||
db close
|
||||
sqlite3_memdebug_fail -1
|
||||
}
|
||||
}
|
||||
|
||||
# The following tests - capi3-11.* - test that a COMMIT or ROLLBACK
|
||||
# statement issued while there are still outstanding VMs that are part of
|
||||
|
||||
@@ -751,6 +751,7 @@ foreach {code english} $code2english {
|
||||
}
|
||||
|
||||
# Test the error message when a "real" out of memory occurs.
|
||||
if { [permutation] != "nofaultsim" } {
|
||||
ifcapable memdebug {
|
||||
do_test capi3c-10-1 {
|
||||
sqlite3 db test.db
|
||||
@@ -771,6 +772,7 @@ ifcapable memdebug {
|
||||
db close
|
||||
sqlite3_memdebug_fail -1
|
||||
}
|
||||
}
|
||||
|
||||
# The following tests - capi3c-11.* - test that a COMMIT or ROLLBACK
|
||||
# statement issued while there are still outstanding VMs that are part of
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+16
-15
@@ -131,10 +131,10 @@ sqlite3_config_uri 1
|
||||
if {$tcl_platform(platform) == "unix"} {
|
||||
set flags [list SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_URI]
|
||||
foreach {tn uri error} "
|
||||
1 {file://localhost[get_pwd]/test.db} {not an error}
|
||||
2 {file://[get_pwd]/test.db} {not an error}
|
||||
3 {file://x[get_pwd]/test.db} {invalid uri authority: x}
|
||||
4 {file://invalid[get_pwd]/test.db} {invalid uri authority: invalid}
|
||||
1 {file://localhost[test_pwd /]test.db} {not an error}
|
||||
2 {file://[test_pwd /]test.db} {not an error}
|
||||
3 {file://x[test_pwd /]test.db} {invalid uri authority: x}
|
||||
4 {file://invalid[test_pwd /]test.db} {invalid uri authority: invalid}
|
||||
" {
|
||||
do_test 2.$tn {
|
||||
set DB [sqlite3_open_v2 $uri $flags ""]
|
||||
@@ -153,9 +153,9 @@ if {$tcl_platform(platform) == "unix"} {
|
||||
# parameters passed through to the VFS xOpen() methods.
|
||||
#
|
||||
foreach {tn uri parse} "
|
||||
1 {file:test.db#abc} {[get_pwd]/test.db {}}
|
||||
2 {file:test.db?a=b#abc} {[get_pwd]/test.db {a b}}
|
||||
3 {file:test.db?a=b#?c=d} {[get_pwd]/test.db {a b}}
|
||||
1 {file:test.db#abc} {[test_pwd / {}]test.db {}}
|
||||
2 {file:test.db?a=b#abc} {[test_pwd / {}]test.db {a b}}
|
||||
3 {file:test.db?a=b#?c=d} {[test_pwd / {}]test.db {a b}}
|
||||
" {
|
||||
do_filepath_test 3.$tn { parse_uri $uri } $parse
|
||||
}
|
||||
@@ -171,7 +171,7 @@ foreach {tn uri parse} "
|
||||
# path is interpreted as a relative path.
|
||||
#
|
||||
foreach {tn uri parse} "
|
||||
1 {file:test.db} {[get_pwd]/test.db {}}
|
||||
1 {file:test.db} {[test_pwd / {}]test.db {}}
|
||||
2 {file:/test.db} {/test.db {}}
|
||||
3 {file:///test.db} {/test.db {}}
|
||||
4 {file://localhost/test.db} {/test.db {}}
|
||||
@@ -241,9 +241,9 @@ do_test 6.1 {
|
||||
} {no such vfs: nosuchvfs}
|
||||
|
||||
|
||||
# EVIDENCE-OF: R-60479-64270 The mode parameter may be set to either
|
||||
# "ro", "rw" or "rwc". Attempting to set it to any other value is an
|
||||
# error
|
||||
# EVIDENCE-OF: R-44013-13102 The mode parameter may be set to either
|
||||
# "ro", "rw", "rwc", or "memory". Attempting to set it to any other
|
||||
# value is an error
|
||||
#
|
||||
sqlite3 db test.db
|
||||
db close
|
||||
@@ -254,6 +254,8 @@ foreach {tn uri error} "
|
||||
4 {file:test.db?mode=Ro} {no such access mode: Ro}
|
||||
5 {file:test.db?mode=Rw} {no such access mode: Rw}
|
||||
6 {file:test.db?mode=Rwc} {no such access mode: Rwc}
|
||||
7 {file:test.db?mode=memory} {not an error}
|
||||
8 {file:test.db?mode=MEMORY} {no such access mode: MEMORY}
|
||||
" {
|
||||
do_test 7.$tn { open_uri_error $uri } $error
|
||||
}
|
||||
@@ -306,10 +308,9 @@ foreach {tn uri read write create} {
|
||||
catch {db close}
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-56032-32287 If sqlite3_open_v2() is used, it is an
|
||||
# error to specify a value for the mode parameter that is less
|
||||
# restrictive than that specified by the flags passed as the third
|
||||
# parameter.
|
||||
# EVIDENCE-OF: R-20590-08726 It is an error to specify a value for the
|
||||
# mode parameter that is less restrictive than that specified by the
|
||||
# flags passed in the third parameter to sqlite3_open_v2().
|
||||
#
|
||||
forcedelete test.db
|
||||
sqlite3 db test.db
|
||||
|
||||
@@ -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) }
|
||||
} {}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -18,12 +18,31 @@ ifcapable !fts3_unicode { finish_test ; return }
|
||||
set ::testprefix fts4unicode
|
||||
|
||||
proc do_unicode_token_test {tn input res} {
|
||||
set input [string map {' ''} $input]
|
||||
uplevel [list do_execsql_test $tn "
|
||||
SELECT fts3_tokenizer_test('unicode61', 'remove_diacritics=0', '$input');
|
||||
" [list [list {*}$res]]]
|
||||
}
|
||||
|
||||
proc do_unicode_token_test2 {tn input res} {
|
||||
set input [string map {' ''} $input]
|
||||
uplevel [list do_execsql_test $tn "
|
||||
SELECT fts3_tokenizer_test('unicode61', '$input');
|
||||
" [list [list {*}$res]]]
|
||||
}
|
||||
|
||||
proc do_unicode_token_test3 {tn args} {
|
||||
set res [lindex $args end]
|
||||
set sql "SELECT fts3_tokenizer_test('unicode61'"
|
||||
foreach a [lrange $args 0 end-1] {
|
||||
append sql ", '"
|
||||
append sql [string map {' ''} $a]
|
||||
append sql "'"
|
||||
}
|
||||
append sql ")"
|
||||
uplevel [list do_execsql_test $tn $sql [list [list {*}$res]]]
|
||||
}
|
||||
|
||||
do_unicode_token_test 1.0 {a B c D} {0 a a 1 b B 2 c c 3 d D}
|
||||
do_unicode_token_test 1.1 {Ä Ö Ü} {0 ä Ä 1 ö Ö 2 ü Ü}
|
||||
do_unicode_token_test 1.2 {xÄx xÖx xÜx} {0 xäx xÄx 1 xöx xÖx 2 xüx xÜx}
|
||||
@@ -40,6 +59,14 @@ do_unicode_token_test 1.7 "The\u00bfquick\u224ebrown\u2263fox" {
|
||||
0 the The 1 quick quick 2 brown brown 3 fox fox
|
||||
}
|
||||
|
||||
do_unicode_token_test2 1.8 {a B c D} {0 a a 1 b B 2 c c 3 d D}
|
||||
do_unicode_token_test2 1.9 {Ä Ö Ü} {0 a Ä 1 o Ö 2 u Ü}
|
||||
do_unicode_token_test2 1.10 {xÄx xÖx xÜx} {0 xax xÄx 1 xox xÖx 2 xux xÜx}
|
||||
|
||||
# Check that diacritics are removed if remove_diacritics=1 is specified.
|
||||
# And that they do not break tokens.
|
||||
do_unicode_token_test2 1.10 "xx\u0301xx" "0 xxxx xx\u301xx"
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
set docs [list {
|
||||
@@ -221,7 +248,140 @@ do_test 4.3 {
|
||||
}
|
||||
} {}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
do_unicode_token_test3 5.1 {tokenchars=} {
|
||||
sqlite3_reset sqlite3_column_int
|
||||
} {
|
||||
0 sqlite3 sqlite3
|
||||
1 reset reset
|
||||
2 sqlite3 sqlite3
|
||||
3 column column
|
||||
4 int int
|
||||
}
|
||||
|
||||
do_unicode_token_test3 5.2 {tokenchars=_} {
|
||||
sqlite3_reset sqlite3_column_int
|
||||
} {
|
||||
0 sqlite3_reset sqlite3_reset
|
||||
1 sqlite3_column_int sqlite3_column_int
|
||||
}
|
||||
|
||||
do_unicode_token_test3 5.3 {separators=xyz} {
|
||||
Laotianxhorseyrunszfast
|
||||
} {
|
||||
0 laotian Laotian
|
||||
1 horse horse
|
||||
2 runs runs
|
||||
3 fast fast
|
||||
}
|
||||
|
||||
do_unicode_token_test3 5.4 {tokenchars=xyz} {
|
||||
Laotianxhorseyrunszfast
|
||||
} {
|
||||
0 laotianxhorseyrunszfast Laotianxhorseyrunszfast
|
||||
}
|
||||
|
||||
do_unicode_token_test3 5.5 {tokenchars=_} {separators=zyx} {
|
||||
sqlite3_resetxsqlite3_column_intyhonda_phantom
|
||||
} {
|
||||
0 sqlite3_reset sqlite3_reset
|
||||
1 sqlite3_column_int sqlite3_column_int
|
||||
2 honda_phantom honda_phantom
|
||||
}
|
||||
|
||||
do_unicode_token_test3 5.6 "separators=\u05D1" "abc\u05D1def" {
|
||||
0 abc abc 1 def def
|
||||
}
|
||||
|
||||
do_unicode_token_test3 5.7 \
|
||||
"tokenchars=\u2444\u2445" \
|
||||
"separators=\u05D0\u05D1\u05D2" \
|
||||
"\u2444fre\u2445sh\u05D0water\u05D2fish.\u2445timer" \
|
||||
[list \
|
||||
0 \u2444fre\u2445sh \u2444fre\u2445sh \
|
||||
1 water water \
|
||||
2 fish fish \
|
||||
3 \u2445timer \u2445timer \
|
||||
]
|
||||
|
||||
# Check that it is not possible to add a standalone diacritic codepoint
|
||||
# to either separators or tokenchars.
|
||||
do_unicode_token_test3 5.8 "separators=\u0301" \
|
||||
"hello\u0301world \u0301helloworld" \
|
||||
"0 helloworld hello\u0301world 1 helloworld helloworld"
|
||||
|
||||
do_unicode_token_test3 5.9 "tokenchars=\u0301" \
|
||||
"hello\u0301world \u0301helloworld" \
|
||||
"0 helloworld hello\u0301world 1 helloworld helloworld"
|
||||
|
||||
do_unicode_token_test3 5.10 "separators=\u0301" \
|
||||
"remove_diacritics=0" \
|
||||
"hello\u0301world \u0301helloworld" \
|
||||
"0 hello\u0301world hello\u0301world 1 helloworld helloworld"
|
||||
|
||||
do_unicode_token_test3 5.11 "tokenchars=\u0301" \
|
||||
"remove_diacritics=0" \
|
||||
"hello\u0301world \u0301helloworld" \
|
||||
"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
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -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}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
@@ -472,6 +472,11 @@ ifcapable subquery {
|
||||
} {1 2 3 4 5 6 7 8 9 10 11}
|
||||
}
|
||||
|
||||
#
|
||||
# The following tests can only work if the current SQLite VFS has the concept
|
||||
# of a current directory.
|
||||
#
|
||||
ifcapable curdir {
|
||||
# Make sure a database connection still works after changing the
|
||||
# working directory.
|
||||
#
|
||||
@@ -495,6 +500,7 @@ do_test misc1-14.3 {
|
||||
execsql {COMMIT}
|
||||
file exists ./test.db-journal
|
||||
} {0}
|
||||
}
|
||||
|
||||
# A failed create table should not leave the table in the internal
|
||||
# data structures. Ticket #238.
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+31
-4
@@ -524,18 +524,27 @@ db close
|
||||
# file-system is saved just before the xDelete() call to remove the
|
||||
# master journal file from the file-system.
|
||||
#
|
||||
set pwd [get_pwd]
|
||||
testvfs tv -default 1
|
||||
tv script copy_on_mj_delete
|
||||
set ::mj_filename_length 0
|
||||
proc copy_on_mj_delete {method filename args} {
|
||||
if {[string match *mj* [file tail $filename]]} {
|
||||
set ::mj_filename_length [string length $filename]
|
||||
#
|
||||
# NOTE: Is the file name relative? If so, add the length of the current
|
||||
# directory.
|
||||
#
|
||||
if {[is_relative_file $filename]} {
|
||||
set ::mj_filename_length \
|
||||
[expr {[string length $filename] + [string length $::pwd]}]
|
||||
} else {
|
||||
set ::mj_filename_length [string length $filename]
|
||||
}
|
||||
faultsim_save
|
||||
}
|
||||
return SQLITE_OK
|
||||
}
|
||||
|
||||
set pwd [get_pwd]
|
||||
foreach {tn1 tcl} {
|
||||
1 { set prefix "test.db" }
|
||||
2 {
|
||||
@@ -1019,8 +1028,17 @@ do_test pager1-5.4.1 {
|
||||
# the master-journal name encoded as utf-8 with no nul term.
|
||||
#
|
||||
set mj_pointer [expr {
|
||||
20 + [string length [get_pwd]] + [string length "/test.db-mjXXXXXX9XX"]
|
||||
20 + [string length "test.db-mjXXXXXX9XX"]
|
||||
}]
|
||||
#
|
||||
# NOTE: For item 3 above, if the current SQLite VFS lacks the concept of a
|
||||
# current directory, the length of the current directory name plus 1
|
||||
# character for the directory separator character are NOT counted as
|
||||
# part of the total size; otherwise, they are.
|
||||
#
|
||||
ifcapable curdir {
|
||||
set mj_pointer [expr {$mj_pointer + [string length [get_pwd]] + 1}]
|
||||
}
|
||||
expr {$::max_journal==(512+2*(1024+8)+$mj_pointer)}
|
||||
} 1
|
||||
do_test pager1-5.4.2 {
|
||||
@@ -1038,8 +1056,17 @@ do_test pager1-5.4.2 {
|
||||
# written starting at the next (in this case 512 byte) sector boundary.
|
||||
#
|
||||
set mj_pointer [expr {
|
||||
20 + [string length [get_pwd]] + [string length "/test.db-mjXXXXXX9XX"]
|
||||
20 + [string length "test.db-mjXXXXXX9XX"]
|
||||
}]
|
||||
#
|
||||
# NOTE: If the current SQLite VFS lacks the concept of a current directory,
|
||||
# the length of the current directory name plus 1 character for the
|
||||
# directory separator character are NOT counted as part of the total
|
||||
# size; otherwise, they are.
|
||||
#
|
||||
ifcapable curdir {
|
||||
set mj_pointer [expr {$mj_pointer + [string length [get_pwd]] + 1}]
|
||||
}
|
||||
expr {$::max_journal==(((512+2*(1024+8)+511)/512)*512 + $mj_pointer)}
|
||||
} 1
|
||||
db close
|
||||
|
||||
@@ -188,6 +188,21 @@ test_suite "fts3" -prefix "" -description {
|
||||
fts4check.test fts4unicode.test
|
||||
}
|
||||
|
||||
test_suite "nofaultsim" -prefix "" -description {
|
||||
"Very" quick test suite. Runs in less than 5 minutes on a workstation.
|
||||
This test suite is the same as the "quick" tests, except that some files
|
||||
that test malloc and IO errors are omitted.
|
||||
} -files [
|
||||
test_set $allquicktests -exclude *malloc* *ioerr* *fault*
|
||||
] -initialize {
|
||||
catch {db close}
|
||||
sqlite3_shutdown
|
||||
install_malloc_faultsim 0
|
||||
sqlite3_initialize
|
||||
autoinstall_test_functions
|
||||
} -shutdown {
|
||||
unset -nocomplain ::G(valgrind)
|
||||
}
|
||||
|
||||
lappend ::testsuitelist xxx
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@@ -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).
|
||||
@@ -40,6 +41,9 @@ do_not_use_codec
|
||||
# pragma-15.*: Test that the value set using the cache_size pragma is not
|
||||
# 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 {
|
||||
@@ -1510,5 +1514,110 @@ do_test pragma-19.5 {
|
||||
file tail [lindex [execsql {PRAGMA filename}] 0]
|
||||
} {test.db}
|
||||
|
||||
if {$tcl_platform(platform)=="windows"} {
|
||||
# Test data_store_directory pragma
|
||||
#
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
file mkdir data_dir
|
||||
do_test pragma-20.1 {
|
||||
catchsql {PRAGMA data_store_directory}
|
||||
} {0 {}}
|
||||
do_test pragma-20.2 {
|
||||
set pwd [string map {' ''} [file nativename [get_pwd]]]
|
||||
catchsql "PRAGMA data_store_directory='$pwd';"
|
||||
} {0 {}}
|
||||
do_test pragma-20.3 {
|
||||
catchsql {PRAGMA data_store_directory}
|
||||
} [list 0 [list [file nativename [get_pwd]]]]
|
||||
do_test pragma-20.4 {
|
||||
set pwd [string map {' ''} [file nativename \
|
||||
[file join [get_pwd] data_dir]]]
|
||||
catchsql "PRAGMA data_store_directory='$pwd';"
|
||||
} {0 {}}
|
||||
do_test pragma-20.5 {
|
||||
sqlite3 db2 test2.db
|
||||
catchsql "PRAGMA database_list;" db2
|
||||
} [list 0 [list 0 main [file nativename \
|
||||
[file join [get_pwd] data_dir test2.db]]]]
|
||||
catch {db2 close}
|
||||
do_test pragma-20.6 {
|
||||
sqlite3 db2 [file join [get_pwd] test2.db]
|
||||
catchsql "PRAGMA database_list;" db2
|
||||
} [list 0 [list 0 main [file nativename \
|
||||
[file join [get_pwd] test2.db]]]]
|
||||
catch {db2 close}
|
||||
do_test pragma-20.7 {
|
||||
catchsql "PRAGMA data_store_directory='';"
|
||||
} {0 {}}
|
||||
do_test pragma-20.8 {
|
||||
catchsql {PRAGMA data_store_directory}
|
||||
} {0 {}}
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
@@ -12,6 +12,13 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
# If SQLITE_CURDIR is not defined, omit this file.
|
||||
ifcapable !curdir {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
source $testdir/malloc_common.tcl
|
||||
|
||||
unset -nocomplain defaultVfs
|
||||
|
||||
+32
-1
@@ -12,6 +12,13 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
# If SQLITE_CURDIR is not defined, omit this file.
|
||||
ifcapable !curdir {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
source $testdir/malloc_common.tcl
|
||||
|
||||
db close
|
||||
@@ -164,11 +171,17 @@ do_test quota2-2.1 {
|
||||
do_test quota2-2.2 {
|
||||
set ::quota
|
||||
} {}
|
||||
do_test quota2-2.3 {
|
||||
do_test quota2-2.3.1 {
|
||||
sqlite3_quota_rewind $::h1
|
||||
sqlite3_quota_file_available $::h1
|
||||
} {7000}
|
||||
do_test quota2-2.3.2 {
|
||||
set ::x [sqlite3_quota_fread $::h1 1001 7]
|
||||
string length $::x
|
||||
} {6006}
|
||||
do_test quota2-2.3.3 {
|
||||
sqlite3_quota_file_available $::h1
|
||||
} {0}
|
||||
do_test quota2-2.4 {
|
||||
string match $::x [string range $::bigtext 0 6005]
|
||||
} {1}
|
||||
@@ -180,22 +193,40 @@ do_test quota2-2.6 {
|
||||
sqlite3_quota_fseek $::h1 -100 SEEK_END
|
||||
sqlite3_quota_ftell $::h1
|
||||
} {6900}
|
||||
do_test quota2-2.6.1 {
|
||||
sqlite3_quota_file_available $::h1
|
||||
} {100}
|
||||
do_test quota2-2.7 {
|
||||
sqlite3_quota_fseek $::h1 -100 SEEK_CUR
|
||||
sqlite3_quota_ftell $::h1
|
||||
} {6800}
|
||||
do_test quota2-2.7.1 {
|
||||
sqlite3_quota_file_available $::h1
|
||||
} {200}
|
||||
do_test quota2-2.8 {
|
||||
sqlite3_quota_fseek $::h1 50 SEEK_CUR
|
||||
sqlite3_quota_ftell $::h1
|
||||
} {6850}
|
||||
do_test quota2-2.8.1 {
|
||||
sqlite3_quota_file_available $::h1
|
||||
} {150}
|
||||
do_test quota2-2.9 {
|
||||
sqlite3_quota_fseek $::h1 50 SEEK_SET
|
||||
sqlite3_quota_ftell $::h1
|
||||
} {50}
|
||||
do_test quota2-2.9.1 {
|
||||
sqlite3_quota_file_available $::h1
|
||||
} {6950}
|
||||
do_test quota2-2.10 {
|
||||
sqlite3_quota_rewind $::h1
|
||||
sqlite3_quota_ftell $::h1
|
||||
} {0}
|
||||
do_test quota2-2.10.1 {
|
||||
sqlite3_quota_file_available $::h1
|
||||
} {7000}
|
||||
do_test quota2-2.10.2 {
|
||||
sqlite3_quota_ferror $::h1
|
||||
} {0}
|
||||
do_test quota2-2.11 {
|
||||
standard_path [sqlite3_quota_dump]
|
||||
} {{*/quota2b/* 5000 0} {*/quota2a/* 4000 0}}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
+126
-4
@@ -904,9 +904,11 @@ do_test shared-$av.11.8 {
|
||||
set res
|
||||
} {1 4 {} 7}
|
||||
if {[llength [info command sqlite3_shared_cache_report]]==1} {
|
||||
do_test shared-$av.11.9 {
|
||||
string tolower [sqlite3_shared_cache_report]
|
||||
} [string tolower [list [file nativename [file normalize test.db]] 2]]
|
||||
ifcapable curdir {
|
||||
do_test shared-$av.11.9 {
|
||||
string tolower [sqlite3_shared_cache_report]
|
||||
} [string tolower [list [file nativename [file normalize test.db]] 2]]
|
||||
}
|
||||
}
|
||||
|
||||
do_test shared-$av.11.11 {
|
||||
@@ -1056,7 +1058,127 @@ do_test shared-$av-15.2 {
|
||||
db close
|
||||
db2 close
|
||||
|
||||
}
|
||||
# Shared cache on a :memory: database. This only works for URI filenames.
|
||||
#
|
||||
do_test shared-$av-16.1 {
|
||||
sqlite3 db1 file::memory: -uri 1
|
||||
sqlite3 db2 file::memory: -uri 1
|
||||
db1 eval {
|
||||
CREATE TABLE t1(x); INSERT INTO t1 VALUES(1),(2),(3);
|
||||
}
|
||||
db2 eval {
|
||||
SELECT x FROM t1 ORDER BY x;
|
||||
}
|
||||
} {1 2 3}
|
||||
do_test shared-$av-16.2 {
|
||||
db2 eval {
|
||||
INSERT INTO t1 VALUES(99);
|
||||
DELETE FROM t1 WHERE x=2;
|
||||
}
|
||||
db1 eval {
|
||||
SELECT x FROM t1 ORDER BY x;
|
||||
}
|
||||
} {1 3 99}
|
||||
|
||||
# Verify that there is no cache sharing ordinary (non-URI) filenames are
|
||||
# used.
|
||||
#
|
||||
do_test shared-$av-16.3 {
|
||||
db1 close
|
||||
db2 close
|
||||
sqlite3 db1 :memory:
|
||||
sqlite3 db2 :memory:
|
||||
db1 eval {
|
||||
CREATE TABLE t1(x); INSERT INTO t1 VALUES(4),(5),(6);
|
||||
}
|
||||
catchsql {
|
||||
SELECT * FROM t1;
|
||||
} db2
|
||||
} {1 {no such table: t1}}
|
||||
|
||||
# Shared cache on named memory databases.
|
||||
#
|
||||
do_test shared-$av-16.4 {
|
||||
db1 close
|
||||
db2 close
|
||||
forcedelete test.db test.db-wal test.db-journal
|
||||
sqlite3 db1 file:test.db?mode=memory -uri 1
|
||||
sqlite3 db2 file:test.db?mode=memory -uri 1
|
||||
db1 eval {
|
||||
CREATE TABLE t1(x); INSERT INTO t1 VALUES(1),(2),(3);
|
||||
}
|
||||
db2 eval {
|
||||
SELECT x FROM t1 ORDER BY x;
|
||||
}
|
||||
} {1 2 3}
|
||||
do_test shared-$av-16.5 {
|
||||
db2 eval {
|
||||
INSERT INTO t1 VALUES(99);
|
||||
DELETE FROM t1 WHERE x=2;
|
||||
}
|
||||
db1 eval {
|
||||
SELECT x FROM t1 ORDER BY x;
|
||||
}
|
||||
} {1 3 99}
|
||||
do_test shared-$av-16.6 {
|
||||
file exists test.db
|
||||
} {0} ;# Verify that the database is in-memory
|
||||
|
||||
# Shared cache on named memory databases with different names.
|
||||
#
|
||||
do_test shared-$av-16.7 {
|
||||
db1 close
|
||||
db2 close
|
||||
forcedelete test1.db test2.db
|
||||
sqlite3 db1 file:test1.db?mode=memory -uri 1
|
||||
sqlite3 db2 file:test2.db?mode=memory -uri 1
|
||||
db1 eval {
|
||||
CREATE TABLE t1(x); INSERT INTO t1 VALUES(1),(2),(3);
|
||||
}
|
||||
catchsql {
|
||||
SELECT x FROM t1 ORDER BY x;
|
||||
} db2
|
||||
} {1 {no such table: t1}}
|
||||
do_test shared-$av-16.8 {
|
||||
file exists test1.db
|
||||
} {0} ;# Verify that the database is in-memory
|
||||
|
||||
# Shared cache on named memory databases attached to readonly connections.
|
||||
#
|
||||
do_test shared-$av-16.8.1 {
|
||||
db1 close
|
||||
db2 close
|
||||
|
||||
sqlite3 db test1.db
|
||||
db eval {
|
||||
CREATE TABLE yy(a, b);
|
||||
INSERT INTO yy VALUES(77, 88);
|
||||
}
|
||||
db close
|
||||
|
||||
sqlite3 db1 test1.db -uri 1 -readonly 1
|
||||
sqlite3 db2 test2.db -uri 1
|
||||
|
||||
db1 eval {
|
||||
ATTACH 'file:mem?mode=memory&cache=shared' AS shared;
|
||||
CREATE TABLE shared.xx(a, b);
|
||||
INSERT INTO xx VALUES(55, 66);
|
||||
}
|
||||
db2 eval {
|
||||
ATTACH 'file:mem?mode=memory&cache=shared' AS shared;
|
||||
SELECT * FROM xx;
|
||||
}
|
||||
} {55 66}
|
||||
|
||||
do_test shared-$av-16.8.2 { db1 eval { SELECT * FROM yy } } {77 88}
|
||||
do_test shared-$av-16.8.3 {
|
||||
list [catch {db1 eval { INSERT INTO yy VALUES(1, 2) }} msg] $msg
|
||||
} {1 {attempt to write a readonly database}}
|
||||
|
||||
db1 close
|
||||
db2 close
|
||||
|
||||
} ;# end of autovacuum on/off loop
|
||||
|
||||
sqlite3_enable_shared_cache $::enable_shared_cache
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
# 2012 May 15
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# The tests in this file are intended to show that closing one database
|
||||
# connection to a shared-cache while there exist other connections (a)
|
||||
# does not cause the schema to be reloaded and (b) does not cause any
|
||||
# other problems.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
ifcapable !shared_cache { finish_test ; return }
|
||||
set testprefix shared8
|
||||
|
||||
db close
|
||||
set ::enable_shared_cache [sqlite3_enable_shared_cache 1]
|
||||
do_test 0.0 { sqlite3_enable_shared_cache } {1}
|
||||
|
||||
proc roman {n} {
|
||||
array set R {1 i 2 ii 3 iii 4 iv 5 v 6 vi 7 vii 8 viii 9 ix 10 x}
|
||||
set R($n)
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# The following tests work as follows:
|
||||
#
|
||||
# 1.0: Open connection [db1] and populate the database.
|
||||
#
|
||||
# 1.1: Using "PRAGMA writable_schema", destroy the database schema on
|
||||
# disk. The schema is still in memory, so it is possible to keep
|
||||
# using it, but any attempt to reload it from disk will fail.
|
||||
#
|
||||
# 1.3-4: Open connection db2. Check that it can see the db schema. Then
|
||||
# close db1 and check that db2 still works. This shows that closing
|
||||
# db1 did not reset the in-memory schema.
|
||||
#
|
||||
# 1.5-7: Similar to 1.3-4.
|
||||
#
|
||||
# 1.8: Close all database connections (deleting the in-memory schema).
|
||||
# Then open a new connection and check that it cannot read the db.
|
||||
#
|
||||
do_test 1.0 {
|
||||
sqlite3 db1 test.db
|
||||
db1 func roman roman
|
||||
execsql {
|
||||
CREATE TABLE t1(a, b);
|
||||
INSERT INTO t1 VALUES(1, 1);
|
||||
INSERT INTO t1 VALUES(2, 2);
|
||||
INSERT INTO t1 VALUES(3, 3);
|
||||
INSERT INTO t1 VALUES(4, 4);
|
||||
CREATE VIEW v1 AS SELECT a, roman(b) FROM t1;
|
||||
SELECT * FROM v1;
|
||||
} db1
|
||||
} {1 i 2 ii 3 iii 4 iv}
|
||||
|
||||
do_test 1.1 {
|
||||
execsql {
|
||||
PRAGMA writable_schema = 1;
|
||||
DELETE FROM sqlite_master WHERE 1;
|
||||
PRAGMA writable_schema = 0;
|
||||
SELECT * FROM sqlite_master;
|
||||
} db1
|
||||
} {}
|
||||
|
||||
do_test 1.2 {
|
||||
execsql { SELECT * FROM v1 } db1
|
||||
} {1 i 2 ii 3 iii 4 iv}
|
||||
|
||||
do_test 1.3 {
|
||||
sqlite3 db2 test.db
|
||||
db2 func roman roman
|
||||
execsql { SELECT * FROM v1 } db2
|
||||
} {1 i 2 ii 3 iii 4 iv}
|
||||
|
||||
do_test 1.4 {
|
||||
db1 close
|
||||
execsql { SELECT * FROM v1 } db2
|
||||
} {1 i 2 ii 3 iii 4 iv}
|
||||
|
||||
do_test 1.5 {
|
||||
sqlite3 db3 test.db
|
||||
db3 func roman roman
|
||||
execsql { SELECT * FROM v1 } db3
|
||||
} {1 i 2 ii 3 iii 4 iv}
|
||||
|
||||
do_test 1.6 {
|
||||
execsql { SELECT * FROM v1 } db2
|
||||
} {1 i 2 ii 3 iii 4 iv}
|
||||
|
||||
do_test 1.7 {
|
||||
db2 close
|
||||
execsql { SELECT * FROM v1 } db3
|
||||
} {1 i 2 ii 3 iii 4 iv}
|
||||
|
||||
do_test 1.8 {
|
||||
db3 close
|
||||
sqlite3 db4 test.db
|
||||
catchsql { SELECT * FROM v1 } db4
|
||||
} {1 {no such table: v1}}
|
||||
|
||||
|
||||
foreach db {db1 db2 db3 db4} { catch { $db close } }
|
||||
sqlite3_enable_shared_cache $::enable_shared_cache
|
||||
finish_test
|
||||
|
||||
+1
-1
@@ -283,7 +283,7 @@ do_test shell1-3.2.4 {
|
||||
# .databases List names and files of attached databases
|
||||
do_test shell1-3.3.1 {
|
||||
catchcmd "-csv test.db" ".databases"
|
||||
} "/0 +.*main +[string map {/ .} [string range [pwd] 0 10]].*/"
|
||||
} "/0 +.*main +[string map {/ .} [string range [get_pwd] 0 10]].*/"
|
||||
do_test shell1-3.3.2 {
|
||||
# too many arguments
|
||||
catchcmd "test.db" ".databases BAD"
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
# 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
|
||||
|
||||
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 kappa 1 keypad 1}
|
||||
2 kellj* {killjoy 5 killed 4 killingly 4 kill 4 killer 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 LIMIT 5
|
||||
} $res
|
||||
}
|
||||
|
||||
finish_test
|
||||
@@ -19,6 +19,8 @@
|
||||
#
|
||||
# Commands to manipulate the db and the file-system at a high level:
|
||||
#
|
||||
# is_relative_file
|
||||
# test_pwd
|
||||
# get_pwd
|
||||
# copy_file FROM TO
|
||||
# delete_file FILENAME
|
||||
@@ -212,6 +214,34 @@ proc do_copy_file {force from to} {
|
||||
}
|
||||
}
|
||||
|
||||
# Check if a file name is relative
|
||||
#
|
||||
proc is_relative_file { file } {
|
||||
return [expr {[file pathtype $file] != "absolute"}]
|
||||
}
|
||||
|
||||
# If the VFS supports using the current directory, returns [pwd];
|
||||
# otherwise, it returns only the provided suffix string (which is
|
||||
# empty by default).
|
||||
#
|
||||
proc test_pwd { args } {
|
||||
if {[llength $args] > 0} {
|
||||
set suffix1 [lindex $args 0]
|
||||
if {[llength $args] > 1} {
|
||||
set suffix2 [lindex $args 1]
|
||||
} else {
|
||||
set suffix2 $suffix1
|
||||
}
|
||||
} else {
|
||||
set suffix1 ""; set suffix2 ""
|
||||
}
|
||||
ifcapable curdir {
|
||||
return "[get_pwd]$suffix1"
|
||||
} else {
|
||||
return $suffix2
|
||||
}
|
||||
}
|
||||
|
||||
# Delete a file or directory
|
||||
#
|
||||
proc delete_file {args} {
|
||||
|
||||
+15
-2
@@ -52,11 +52,24 @@ foreach {tn uri file} {
|
||||
16 file://localhostPWD/test.db%3Fhello test.db?hello
|
||||
} {
|
||||
|
||||
|
||||
ifcapable !curdir { if {$tn==3} break }
|
||||
|
||||
if {$tcl_platform(platform)=="windows"} {
|
||||
#
|
||||
# NOTE: Due to limits on legal characters for file names imposed by
|
||||
# Windows, we must skip the final two tests here (i.e. the
|
||||
# question mark is illegal in a file name on Windows).
|
||||
#
|
||||
if {$tn>14} break
|
||||
set uri [string map [list PWD /[get_pwd]] $uri]
|
||||
|
||||
#
|
||||
# NOTE: On Windows, we need to account for the fact that the current
|
||||
# directory does not start with a forward slash.
|
||||
#
|
||||
set uri [string map [list PWD/ /[test_pwd /]] $uri]
|
||||
} else {
|
||||
set uri [string map [list PWD [get_pwd]] $uri]
|
||||
set uri [string map [list PWD/ [test_pwd /]] $uri]
|
||||
}
|
||||
|
||||
if {[file isdir $file]} {error "$file is a directory"}
|
||||
|
||||
@@ -1222,6 +1222,10 @@ do_test vtab1-17.1 {
|
||||
}
|
||||
} {}
|
||||
|
||||
do_test vtab1-17.2 {
|
||||
execsql { DELETE FROM sqlite_master WHERE sql LIKE 'insert%' }
|
||||
} {}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# The following tests - vtab1-18.* - test that the optimization of LIKE
|
||||
# constraints in where.c plays well with virtual tables.
|
||||
@@ -1275,4 +1279,18 @@ foreach {tn sql res filter} {
|
||||
}
|
||||
do_execsql_test 18.2.x { PRAGMA case_sensitive_like = OFF }
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that an existing module may not be overridden.
|
||||
#
|
||||
do_test 19.1 {
|
||||
sqlite3 db2 test.db
|
||||
register_echo_module [sqlite3_connection_pointer db2]
|
||||
} SQLITE_OK
|
||||
do_test 19.2 {
|
||||
register_echo_module [sqlite3_connection_pointer db2]
|
||||
} SQLITE_MISUSE
|
||||
do_test 19.3 {
|
||||
db2 close
|
||||
} {}
|
||||
|
||||
finish_test
|
||||
|
||||
+5
-1
@@ -1478,7 +1478,11 @@ foreach pgsz {512 1024 2048 4096 8192 16384 32768 65536} {
|
||||
# Test that when 1 or more pages are recovered from a WAL file,
|
||||
# sqlite3_log() is invoked to report this to the user.
|
||||
#
|
||||
set walfile [file nativename [file join [get_pwd] test.db-wal]]
|
||||
ifcapable curdir {
|
||||
set walfile [file nativename [file join [get_pwd] test.db-wal]]
|
||||
} else {
|
||||
set walfile test.db-wal
|
||||
}
|
||||
catch {db close}
|
||||
forcedelete test.db
|
||||
do_test wal-23.1 {
|
||||
|
||||
+4
-2
@@ -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 {
|
||||
|
||||
+1
-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]
|
||||
}
|
||||
|
||||
+125
@@ -163,6 +163,131 @@ 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 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
|
||||
|
||||
|
||||
|
||||
+3
-1
@@ -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
|
||||
|
||||
+3
-5
@@ -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
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ rm -f sqlite3.c
|
||||
make sqlite3.c
|
||||
echo '************* FTS4 and RTREE ****************'
|
||||
scan-build gcc -c -DHAVE_STDINT_H -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE \
|
||||
-DSQLITE_DEBUG sqlite3.c 2>&1 | grep -v 'ANALYZE:'
|
||||
-DSQLITE_DEBUG -DSQLITE_ENABLE_STAT3 sqlite3.c 2>&1 | grep -v 'ANALYZE:'
|
||||
echo '********** ENABLE_STAT3. THREADSAFE=0 *******'
|
||||
scan-build gcc -c -I. -DSQLITE_ENABLE_STAT3 -DSQLITE_THREADSAFE=0 \
|
||||
-DSQLITE_DEBUG \
|
||||
|
||||
Reference in New Issue
Block a user