Merge all recent trunk enhancements.
FossilOrigin-Name: 9a71d56dcea953cb965f1fdda9a8b8f158cdeff6
This commit is contained in:
commit
8716bfd8cd
@ -1180,9 +1180,9 @@ lib_install: libsqlite3.la
|
|||||||
$(INSTALL) -d $(DESTDIR)$(libdir)
|
$(INSTALL) -d $(DESTDIR)$(libdir)
|
||||||
$(LTINSTALL) libsqlite3.la $(DESTDIR)$(libdir)
|
$(LTINSTALL) libsqlite3.la $(DESTDIR)$(libdir)
|
||||||
|
|
||||||
install: sqlite3$(BEXE) lib_install sqlite3.h sqlite3.pc ${HAVE_TCL:1=tcl_install}
|
install: sqlite3$(TEXE) lib_install sqlite3.h sqlite3.pc ${HAVE_TCL:1=tcl_install}
|
||||||
$(INSTALL) -d $(DESTDIR)$(bindir)
|
$(INSTALL) -d $(DESTDIR)$(bindir)
|
||||||
$(LTINSTALL) sqlite3$(BEXE) $(DESTDIR)$(bindir)
|
$(LTINSTALL) sqlite3$(TEXE) $(DESTDIR)$(bindir)
|
||||||
$(INSTALL) -d $(DESTDIR)$(includedir)
|
$(INSTALL) -d $(DESTDIR)$(includedir)
|
||||||
$(INSTALL) -m 0644 sqlite3.h $(DESTDIR)$(includedir)
|
$(INSTALL) -m 0644 sqlite3.h $(DESTDIR)$(includedir)
|
||||||
$(INSTALL) -m 0644 $(TOP)/src/sqlite3ext.h $(DESTDIR)$(includedir)
|
$(INSTALL) -m 0644 $(TOP)/src/sqlite3ext.h $(DESTDIR)$(includedir)
|
||||||
|
297
Makefile.msc
297
Makefile.msc
@ -10,11 +10,13 @@
|
|||||||
#
|
#
|
||||||
TOP = .
|
TOP = .
|
||||||
|
|
||||||
|
# <<mark>>
|
||||||
# Set this non-0 to create and use the SQLite amalgamation file.
|
# Set this non-0 to create and use the SQLite amalgamation file.
|
||||||
#
|
#
|
||||||
!IFNDEF USE_AMALGAMATION
|
!IFNDEF USE_AMALGAMATION
|
||||||
USE_AMALGAMATION = 1
|
USE_AMALGAMATION = 1
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
# <</mark>>
|
||||||
|
|
||||||
# Set this non-0 to enable full warnings (-W4, etc) when compiling.
|
# Set this non-0 to enable full warnings (-W4, etc) when compiling.
|
||||||
#
|
#
|
||||||
@ -68,11 +70,13 @@ USE_WP81_OPTS = 0
|
|||||||
SPLIT_AMALGAMATION = 0
|
SPLIT_AMALGAMATION = 0
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
|
# <<mark>>
|
||||||
# Set this non-0 to use the International Components for Unicode (ICU).
|
# Set this non-0 to use the International Components for Unicode (ICU).
|
||||||
#
|
#
|
||||||
!IFNDEF USE_ICU
|
!IFNDEF USE_ICU
|
||||||
USE_ICU = 0
|
USE_ICU = 0
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
# <</mark>>
|
||||||
|
|
||||||
# Set this non-0 to dynamically link to the MSVC runtime library.
|
# Set this non-0 to dynamically link to the MSVC runtime library.
|
||||||
#
|
#
|
||||||
@ -130,12 +134,20 @@ FOR_WINRT = 0
|
|||||||
FOR_UAP = 0
|
FOR_UAP = 0
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
|
# Set this non-0 to compile binaries suitable for the Windows 10 platform.
|
||||||
|
#
|
||||||
|
!IFNDEF FOR_WIN10
|
||||||
|
FOR_WIN10 = 0
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# <<mark>>
|
||||||
# Set this non-0 to skip attempting to look for and/or link with the Tcl
|
# Set this non-0 to skip attempting to look for and/or link with the Tcl
|
||||||
# runtime library.
|
# runtime library.
|
||||||
#
|
#
|
||||||
!IFNDEF NO_TCL
|
!IFNDEF NO_TCL
|
||||||
NO_TCL = 0
|
NO_TCL = 0
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
# <</mark>>
|
||||||
|
|
||||||
# Set this to non-0 to create and use PDBs.
|
# Set this to non-0 to create and use PDBs.
|
||||||
#
|
#
|
||||||
@ -186,6 +198,49 @@ DEBUG = 0
|
|||||||
OPTIMIZATIONS = 2
|
OPTIMIZATIONS = 2
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
|
# Set the source code file to be used by executables and libraries when
|
||||||
|
# they need the amalgamation.
|
||||||
|
#
|
||||||
|
!IFNDEF SQLITE3C
|
||||||
|
!IF $(SPLIT_AMALGAMATION)!=0
|
||||||
|
SQLITE3C = sqlite3-all.c
|
||||||
|
!ELSE
|
||||||
|
SQLITE3C = sqlite3.c
|
||||||
|
!ENDIF
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Set the include code file to be used by executables and libraries when
|
||||||
|
# they need SQLite.
|
||||||
|
#
|
||||||
|
!IFNDEF SQLITE3H
|
||||||
|
SQLITE3H = sqlite3.h
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# This is the name to use for the SQLite dynamic link library (DLL).
|
||||||
|
#
|
||||||
|
!IFNDEF SQLITE3DLL
|
||||||
|
SQLITE3DLL = sqlite3.dll
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# This is the name to use for the SQLite import library (LIB).
|
||||||
|
#
|
||||||
|
!IFNDEF SQLITE3LIB
|
||||||
|
SQLITE3LIB = sqlite3.lib
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# This is the name to use for the SQLite shell executable (EXE).
|
||||||
|
#
|
||||||
|
!IFNDEF SQLITE3EXE
|
||||||
|
SQLITE3EXE = sqlite3.exe
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# This is the argument used to set the program database (PDB) file for the
|
||||||
|
# SQLite shell executable (EXE).
|
||||||
|
#
|
||||||
|
!IFNDEF SQLITE3EXEPDB
|
||||||
|
SQLITE3EXEPDB = /pdb:sqlite3sh.pdb
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
# These are the "standard" SQLite compilation options used when compiling for
|
# These are the "standard" SQLite compilation options used when compiling for
|
||||||
# the Windows platform.
|
# the Windows platform.
|
||||||
#
|
#
|
||||||
@ -195,6 +250,19 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1
|
|||||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
|
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
|
# These are the "extended" SQLite compilation options used when compiling for
|
||||||
|
# the Windows 10 platform.
|
||||||
|
#
|
||||||
|
!IFNDEF EXT_FEATURE_FLAGS
|
||||||
|
!IF $(FOR_WIN10)!=0
|
||||||
|
EXT_FEATURE_FLAGS = $(EXT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS4=1
|
||||||
|
EXT_FEATURE_FLAGS = $(EXT_FEATURE_FLAGS) -DSQLITE_SYSTEM_MALLOC=1
|
||||||
|
EXT_FEATURE_FLAGS = $(EXT_FEATURE_FLAGS) -DSQLITE_OMIT_LOCALTIME=1
|
||||||
|
!ELSE
|
||||||
|
EXT_FEATURE_FLAGS =
|
||||||
|
!ENDIF
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
############################### END OF OPTIONS ################################
|
############################### END OF OPTIONS ################################
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@ -327,9 +395,18 @@ TCC = $(CC) -nologo -W4 -DINCLUDE_MSVC_H=1 $(CCOPTS) $(TCCOPTS)
|
|||||||
TCC = $(CC) -nologo -W3 $(CCOPTS) $(TCCOPTS)
|
TCC = $(CC) -nologo -W3 $(CCOPTS) $(TCCOPTS)
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
TCC = $(TCC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -I$(TOP)\src -fp:precise
|
TCC = $(TCC) -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src -fp:precise
|
||||||
RCC = $(RC) -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src $(RCOPTS) $(RCCOPTS)
|
RCC = $(RC) -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src $(RCOPTS) $(RCCOPTS)
|
||||||
|
|
||||||
|
# Adjust the names of the primary targets for use with Windows 10.
|
||||||
|
#
|
||||||
|
!IF $(FOR_WIN10)!=0
|
||||||
|
SQLITE3DLL = winsqlite3.dll
|
||||||
|
SQLITE3LIB = winsqlite3.lib
|
||||||
|
SQLITE3EXE = winsqlite3shell.exe
|
||||||
|
SQLITE3EXEPDB =
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
# Check if we want to use the "stdcall" calling convention when compiling.
|
# Check if we want to use the "stdcall" calling convention when compiling.
|
||||||
# This is not supported by the compilers for non-x86 platforms. It should
|
# This is not supported by the compilers for non-x86 platforms. It should
|
||||||
# also be noted here that building any target with these "stdcall" options
|
# also be noted here that building any target with these "stdcall" options
|
||||||
@ -337,7 +414,7 @@ RCC = $(RC) -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src $(RCOPTS) $(RCCOPTS)
|
|||||||
# to how the Tcl library functions are declared and exported (i.e. without
|
# to how the Tcl library functions are declared and exported (i.e. without
|
||||||
# an explicit calling convention, which results in "cdecl").
|
# an explicit calling convention, which results in "cdecl").
|
||||||
#
|
#
|
||||||
!IF $(USE_STDCALL)!=0
|
!IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0
|
||||||
!IF "$(PLATFORM)"=="x86"
|
!IF "$(PLATFORM)"=="x86"
|
||||||
CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall
|
CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall
|
||||||
SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall
|
SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall
|
||||||
@ -358,7 +435,7 @@ SHELL_CCONV_OPTS =
|
|||||||
# These are additional compiler options used for the core library.
|
# These are additional compiler options used for the core library.
|
||||||
#
|
#
|
||||||
!IFNDEF CORE_COMPILE_OPTS
|
!IFNDEF CORE_COMPILE_OPTS
|
||||||
!IF $(DYNAMIC_SHELL)!=0
|
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
|
||||||
CORE_COMPILE_OPTS = $(CORE_CCONV_OPTS) -DSQLITE_API=__declspec(dllexport)
|
CORE_COMPILE_OPTS = $(CORE_CCONV_OPTS) -DSQLITE_API=__declspec(dllexport)
|
||||||
!ELSE
|
!ELSE
|
||||||
CORE_COMPILE_OPTS = $(CORE_CCONV_OPTS)
|
CORE_COMPILE_OPTS = $(CORE_CCONV_OPTS)
|
||||||
@ -369,7 +446,7 @@ CORE_COMPILE_OPTS = $(CORE_CCONV_OPTS)
|
|||||||
# when linking.
|
# when linking.
|
||||||
#
|
#
|
||||||
!IFNDEF CORE_LINK_DEP
|
!IFNDEF CORE_LINK_DEP
|
||||||
!IF $(DYNAMIC_SHELL)!=0
|
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
|
||||||
CORE_LINK_DEP =
|
CORE_LINK_DEP =
|
||||||
!ELSE
|
!ELSE
|
||||||
CORE_LINK_DEP = sqlite3.def
|
CORE_LINK_DEP = sqlite3.def
|
||||||
@ -379,7 +456,7 @@ CORE_LINK_DEP = sqlite3.def
|
|||||||
# These are additional linker options used for the core library.
|
# These are additional linker options used for the core library.
|
||||||
#
|
#
|
||||||
!IFNDEF CORE_LINK_OPTS
|
!IFNDEF CORE_LINK_OPTS
|
||||||
!IF $(DYNAMIC_SHELL)!=0
|
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
|
||||||
CORE_LINK_OPTS =
|
CORE_LINK_OPTS =
|
||||||
!ELSE
|
!ELSE
|
||||||
CORE_LINK_OPTS = /DEF:sqlite3.def
|
CORE_LINK_OPTS = /DEF:sqlite3.def
|
||||||
@ -389,30 +466,41 @@ CORE_LINK_OPTS = /DEF:sqlite3.def
|
|||||||
# These are additional compiler options used for the shell executable.
|
# These are additional compiler options used for the shell executable.
|
||||||
#
|
#
|
||||||
!IFNDEF SHELL_COMPILE_OPTS
|
!IFNDEF SHELL_COMPILE_OPTS
|
||||||
!IF $(DYNAMIC_SHELL)!=0
|
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
|
||||||
SHELL_COMPILE_OPTS = -DSQLITE_SHELL_JSON1 $(SHELL_CCONV_OPTS) -DSQLITE_API=__declspec(dllimport)
|
SHELL_COMPILE_OPTS = $(SHELL_CCONV_OPTS) -DSQLITE_API=__declspec(dllimport)
|
||||||
!ELSE
|
!ELSE
|
||||||
SHELL_COMPILE_OPTS = -DSQLITE_SHELL_JSON1 $(SHELL_CCONV_OPTS)
|
SHELL_COMPILE_OPTS = $(SHELL_CCONV_OPTS)
|
||||||
|
!ENDIF
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# This is the source code that the shell executable should be compiled
|
||||||
|
# with.
|
||||||
|
#
|
||||||
|
!IFNDEF SHELL_CORE_SRC
|
||||||
|
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
|
||||||
|
SHELL_CORE_SRC =
|
||||||
|
!ELSE
|
||||||
|
SHELL_CORE_SRC = $(SQLITE3C)
|
||||||
!ENDIF
|
!ENDIF
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
# This is the core library that the shell executable should depend on.
|
# This is the core library that the shell executable should depend on.
|
||||||
#
|
#
|
||||||
!IFNDEF SHELL_CORE_DEP
|
!IFNDEF SHELL_CORE_DEP
|
||||||
!IF $(DYNAMIC_SHELL)!=0
|
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
|
||||||
SHELL_CORE_DEP = sqlite3.dll
|
SHELL_CORE_DEP = $(SQLITE3DLL)
|
||||||
!ELSE
|
!ELSE
|
||||||
SHELL_CORE_DEP = libsqlite3.lib
|
SHELL_CORE_DEP =
|
||||||
!ENDIF
|
!ENDIF
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
# This is the core library that the shell executable should link with.
|
# This is the core library that the shell executable should link with.
|
||||||
#
|
#
|
||||||
!IFNDEF SHELL_CORE_LIB
|
!IFNDEF SHELL_CORE_LIB
|
||||||
!IF $(DYNAMIC_SHELL)!=0
|
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
|
||||||
SHELL_CORE_LIB = sqlite3.lib
|
SHELL_CORE_LIB = $(SQLITE3LIB)
|
||||||
!ELSE
|
!ELSE
|
||||||
SHELL_CORE_LIB = libsqlite3.lib
|
SHELL_CORE_LIB =
|
||||||
!ENDIF
|
!ENDIF
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
@ -441,12 +529,19 @@ TCC = $(TCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
|
|||||||
RCC = $(RCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
|
RCC = $(RCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
|
# C compiler options for the Windows 10 platform (needs MSVC 2015).
|
||||||
|
#
|
||||||
|
!IF $(FOR_WIN10)!=0
|
||||||
|
TCC = $(TCC) /guard:cf -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
|
||||||
|
BCC = $(BCC) /guard:cf -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
# Also, we need to dynamically link to the correct MSVC runtime
|
# Also, we need to dynamically link to the correct MSVC runtime
|
||||||
# when compiling for WinRT (e.g. debug or release) OR if the
|
# when compiling for WinRT (e.g. debug or release) OR if the
|
||||||
# USE_CRT_DLL option is set to force dynamically linking to the
|
# USE_CRT_DLL option is set to force dynamically linking to the
|
||||||
# MSVC runtime library.
|
# MSVC runtime library.
|
||||||
#
|
#
|
||||||
!IF $(FOR_WINRT)!=0 || $(USE_CRT_DLL)!=0
|
!IF $(FOR_WINRT)!=0 || $(FOR_WIN10)!=0 || $(USE_CRT_DLL)!=0
|
||||||
!IF $(DEBUG)>1
|
!IF $(DEBUG)>1
|
||||||
TCC = $(TCC) -MDd
|
TCC = $(TCC) -MDd
|
||||||
BCC = $(BCC) -MDd
|
BCC = $(BCC) -MDd
|
||||||
@ -464,6 +559,7 @@ BCC = $(BCC) -MT
|
|||||||
!ENDIF
|
!ENDIF
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
|
# <<mark>>
|
||||||
# The mksqlite3c.tcl and mksqlite3h.tcl scripts will pull in
|
# The mksqlite3c.tcl and mksqlite3h.tcl scripts will pull in
|
||||||
# any extension header files by default. For non-amalgamation
|
# any extension header files by default. For non-amalgamation
|
||||||
# builds, we need to make sure the compiler can find these.
|
# builds, we need to make sure the compiler can find these.
|
||||||
@ -487,6 +583,7 @@ MKSQLITE3C_ARGS = --linemacros
|
|||||||
MKSQLITE3C_ARGS =
|
MKSQLITE3C_ARGS =
|
||||||
!ENDIF
|
!ENDIF
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
# <</mark>>
|
||||||
|
|
||||||
# Define -DNDEBUG to compile without debugging (i.e., for production usage)
|
# Define -DNDEBUG to compile without debugging (i.e., for production usage)
|
||||||
# Omitting the define will cause extra debugging code to be inserted and
|
# Omitting the define will cause extra debugging code to be inserted and
|
||||||
@ -498,7 +595,7 @@ BCC = $(BCC) -DNDEBUG
|
|||||||
RCC = $(RCC) -DNDEBUG
|
RCC = $(RCC) -DNDEBUG
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
!IF $(DEBUG)>0 || $(API_ARMOR)!=0
|
!IF $(DEBUG)>0 || $(API_ARMOR)!=0 || $(FOR_WIN10)!=0
|
||||||
TCC = $(TCC) -DSQLITE_ENABLE_API_ARMOR=1
|
TCC = $(TCC) -DSQLITE_ENABLE_API_ARMOR=1
|
||||||
RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR=1
|
RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR=1
|
||||||
!ENDIF
|
!ENDIF
|
||||||
@ -551,6 +648,7 @@ RCC = $(RCC) -DSQLITE_WIN32_MALLOC_VALIDATE=1
|
|||||||
!ENDIF
|
!ENDIF
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
|
# <<mark>>
|
||||||
# The locations of the Tcl header and library files. Also, the library that
|
# The locations of the Tcl header and library files. Also, the library that
|
||||||
# non-stubs enabled programs using Tcl must link against. These variables
|
# non-stubs enabled programs using Tcl must link against. These variables
|
||||||
# (TCLINCDIR, TCLLIBDIR, and LIBTCL) may be overridden via the environment
|
# (TCLINCDIR, TCLLIBDIR, and LIBTCL) may be overridden via the environment
|
||||||
@ -602,6 +700,7 @@ LIBICU = icuuc.lib icuin.lib
|
|||||||
!IFNDEF TCLSH_CMD
|
!IFNDEF TCLSH_CMD
|
||||||
TCLSH_CMD = tclsh85
|
TCLSH_CMD = tclsh85
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
# <</mark>>
|
||||||
|
|
||||||
# Compiler options needed for programs that use the readline() library.
|
# Compiler options needed for programs that use the readline() library.
|
||||||
#
|
#
|
||||||
@ -659,8 +758,8 @@ REQ_FEATURE_FLAGS = $(REQ_FEATURE_FLAGS) -DSQLITE_WIN32_USE_UUID=1
|
|||||||
# Add the required and optional SQLite compilation options into the command
|
# Add the required and optional SQLite compilation options into the command
|
||||||
# lines used to invoke the MSVC code and resource compilers.
|
# lines used to invoke the MSVC code and resource compilers.
|
||||||
#
|
#
|
||||||
TCC = $(TCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS)
|
TCC = $(TCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS)
|
||||||
RCC = $(RCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS)
|
RCC = $(RCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS)
|
||||||
|
|
||||||
# Add in any optional parameters specified on the commane line, e.g.
|
# Add in any optional parameters specified on the commane line, e.g.
|
||||||
# nmake /f Makefile.msc all "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1"
|
# nmake /f Makefile.msc all "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1"
|
||||||
@ -700,6 +799,7 @@ TCC = $(TCC) -Zi
|
|||||||
BCC = $(BCC) -Zi
|
BCC = $(BCC) -Zi
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
|
# <<mark>>
|
||||||
# If ICU support is enabled, add the compiler options for it.
|
# If ICU support is enabled, add the compiler options for it.
|
||||||
#
|
#
|
||||||
!IF $(USE_ICU)!=0
|
!IF $(USE_ICU)!=0
|
||||||
@ -710,6 +810,7 @@ RCC = $(RCC) -I$(TOP)\ext\icu
|
|||||||
TCC = $(TCC) -I$(ICUINCDIR)
|
TCC = $(TCC) -I$(ICUINCDIR)
|
||||||
RCC = $(RCC) -I$(ICUINCDIR)
|
RCC = $(RCC) -I$(ICUINCDIR)
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
# <</mark>>
|
||||||
|
|
||||||
# Command line prefixes for compiling code, compiling resources,
|
# Command line prefixes for compiling code, compiling resources,
|
||||||
# linking, etc.
|
# linking, etc.
|
||||||
@ -805,6 +906,7 @@ LDFLAGS = /DEBUG $(LDOPTS)
|
|||||||
LDFLAGS = $(LDOPTS)
|
LDFLAGS = $(LDOPTS)
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
|
# <<mark>>
|
||||||
# Start with the Tcl related linker options.
|
# Start with the Tcl related linker options.
|
||||||
#
|
#
|
||||||
!IF $(NO_TCL)==0
|
!IF $(NO_TCL)==0
|
||||||
@ -818,10 +920,12 @@ LTLIBS = $(LIBTCL)
|
|||||||
LTLIBPATHS = $(LTLIBPATHS) /LIBPATH:$(ICULIBDIR)
|
LTLIBPATHS = $(LTLIBPATHS) /LIBPATH:$(ICULIBDIR)
|
||||||
LTLIBS = $(LTLIBS) $(LIBICU)
|
LTLIBS = $(LTLIBS) $(LIBICU)
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
# <</mark>>
|
||||||
|
|
||||||
# You should not have to change anything below this line
|
# You should not have to change anything below this line
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
# <<mark>>
|
||||||
# Object files for the SQLite library (non-amalgamation).
|
# Object files for the SQLite library (non-amalgamation).
|
||||||
#
|
#
|
||||||
LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \
|
LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \
|
||||||
@ -845,6 +949,7 @@ LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \
|
|||||||
vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
|
vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
|
||||||
vdbetrace.lo wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \
|
vdbetrace.lo wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \
|
||||||
utf.lo vtab.lo
|
utf.lo vtab.lo
|
||||||
|
# <</mark>>
|
||||||
|
|
||||||
# Object files for the amalgamation.
|
# Object files for the amalgamation.
|
||||||
#
|
#
|
||||||
@ -852,11 +957,15 @@ LIBOBJS1 = sqlite3.lo
|
|||||||
|
|
||||||
# Determine the real value of LIBOBJ based on the 'configure' script
|
# Determine the real value of LIBOBJ based on the 'configure' script
|
||||||
#
|
#
|
||||||
|
# <<mark>>
|
||||||
!IF $(USE_AMALGAMATION)==0
|
!IF $(USE_AMALGAMATION)==0
|
||||||
LIBOBJ = $(LIBOBJS0)
|
LIBOBJ = $(LIBOBJS0)
|
||||||
!ELSE
|
!ELSE
|
||||||
|
# <</mark>>
|
||||||
LIBOBJ = $(LIBOBJS1)
|
LIBOBJ = $(LIBOBJS1)
|
||||||
|
# <<mark>>
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
# <</mark>>
|
||||||
|
|
||||||
# Determine if embedded resource compilation and usage are enabled.
|
# Determine if embedded resource compilation and usage are enabled.
|
||||||
#
|
#
|
||||||
@ -866,6 +975,7 @@ LIBRESOBJS = sqlite3res.lo
|
|||||||
LIBRESOBJS =
|
LIBRESOBJS =
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
|
# <<mark>>
|
||||||
# All of the source code files.
|
# All of the source code files.
|
||||||
#
|
#
|
||||||
SRC1 = \
|
SRC1 = \
|
||||||
@ -1024,7 +1134,7 @@ SRC5 = \
|
|||||||
opcodes.h \
|
opcodes.h \
|
||||||
parse.c \
|
parse.c \
|
||||||
parse.h \
|
parse.h \
|
||||||
sqlite3.h
|
$(SQLITE3H)
|
||||||
|
|
||||||
# All source code files.
|
# All source code files.
|
||||||
#
|
#
|
||||||
@ -1168,7 +1278,7 @@ HDR = \
|
|||||||
$(TOP)\src\pcache.h \
|
$(TOP)\src\pcache.h \
|
||||||
parse.h \
|
parse.h \
|
||||||
$(TOP)\src\pragma.h \
|
$(TOP)\src\pragma.h \
|
||||||
sqlite3.h \
|
$(SQLITE3H) \
|
||||||
$(TOP)\src\sqlite3ext.h \
|
$(TOP)\src\sqlite3ext.h \
|
||||||
$(TOP)\src\sqliteInt.h \
|
$(TOP)\src\sqliteInt.h \
|
||||||
$(TOP)\src\sqliteLimit.h \
|
$(TOP)\src\sqliteLimit.h \
|
||||||
@ -1203,7 +1313,7 @@ EXTHDR = $(EXTHDR) \
|
|||||||
#
|
#
|
||||||
TESTPROGS = \
|
TESTPROGS = \
|
||||||
testfixture.exe \
|
testfixture.exe \
|
||||||
sqlite3.exe \
|
$(SQLITE3EXE) \
|
||||||
sqlite3_analyzer.exe \
|
sqlite3_analyzer.exe \
|
||||||
sqldiff.exe
|
sqldiff.exe
|
||||||
|
|
||||||
@ -1214,45 +1324,75 @@ FUZZDATA = \
|
|||||||
$(TOP)\test\fuzzdata2.db \
|
$(TOP)\test\fuzzdata2.db \
|
||||||
$(TOP)\test\fuzzdata3.db \
|
$(TOP)\test\fuzzdata3.db \
|
||||||
$(TOP)\test\fuzzdata4.db
|
$(TOP)\test\fuzzdata4.db
|
||||||
|
# <</mark>>
|
||||||
|
|
||||||
# Extra compiler options for various shell tools
|
# Additional compiler options for the shell. These are only effective
|
||||||
|
# when the shell is not being dynamically linked.
|
||||||
#
|
#
|
||||||
SHELL_COMPILE_OPTS = -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
|
!IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
|
||||||
|
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# <<mark>>
|
||||||
|
# Extra compiler options for various test tools.
|
||||||
|
#
|
||||||
|
MPTESTER_COMPILE_OPTS = -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS5
|
||||||
FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
|
FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
|
||||||
FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
|
FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
|
||||||
|
|
||||||
# Standard options to testfixture
|
# Standard options to testfixture.
|
||||||
#
|
#
|
||||||
TESTOPTS = --verbose=file --output=test-out.txt
|
TESTOPTS = --verbose=file --output=test-out.txt
|
||||||
|
# <</mark>>
|
||||||
|
|
||||||
# This is the default Makefile target. The objects listed here
|
# This is the default Makefile target. The objects listed here
|
||||||
# are what get build when you type just "make" with no arguments.
|
# are what get build when you type just "make" with no arguments.
|
||||||
#
|
#
|
||||||
all: dll libsqlite3.lib sqlite3.exe libtclsqlite3.lib
|
all: dll libsqlite3.lib shell libtclsqlite3.lib
|
||||||
|
|
||||||
|
# Dynamic link library section.
|
||||||
|
#
|
||||||
|
dll: $(SQLITE3DLL)
|
||||||
|
|
||||||
|
# Shell executable.
|
||||||
|
#
|
||||||
|
shell: $(SQLITE3EXE)
|
||||||
|
|
||||||
libsqlite3.lib: $(LIBOBJ)
|
libsqlite3.lib: $(LIBOBJ)
|
||||||
$(LTLIB) $(LTLIBOPTS) /OUT:$@ $(LIBOBJ) $(TLIBS)
|
$(LTLIB) $(LTLIBOPTS) /OUT:$@ $(LIBOBJ) $(TLIBS)
|
||||||
|
|
||||||
|
# <<mark>>
|
||||||
libtclsqlite3.lib: tclsqlite.lo libsqlite3.lib
|
libtclsqlite3.lib: tclsqlite.lo libsqlite3.lib
|
||||||
$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCLSTUB) $(TLIBS)
|
$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCLSTUB) $(TLIBS)
|
||||||
|
# <</mark>>
|
||||||
|
|
||||||
sqlite3.exe: $(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
|
$(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
|
||||||
$(LTLINK) $(SHELL_COMPILE_OPTS) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\src\shell.c \
|
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
||||||
/link /pdb:sqlite3sh.pdb $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
|
|
||||||
|
|
||||||
sqldiff.exe: $(TOP)\tool\sqldiff.c sqlite3.c sqlite3.h
|
# <<mark>>
|
||||||
$(LTLINK) $(NO_WARN) $(TOP)\tool\sqldiff.c sqlite3.c /link $(LDFLAGS) $(LTLINKOPTS)
|
sqlite3.def: libsqlite3.lib
|
||||||
|
echo EXPORTS > sqlite3.def
|
||||||
|
dumpbin /all libsqlite3.lib \
|
||||||
|
| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3_.*)$$" \1 \
|
||||||
|
| sort >> sqlite3.def
|
||||||
|
# <</mark>>
|
||||||
|
|
||||||
fuzzershell.exe: $(TOP)\tool\fuzzershell.c sqlite3.c sqlite3.h
|
$(SQLITE3EXE): $(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H)
|
||||||
$(LTLINK) $(NO_WARN) $(FUZZERSHELL_COMPILE_OPTS) \
|
$(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\src\shell.c $(SHELL_CORE_SRC) \
|
||||||
$(TOP)\tool\fuzzershell.c sqlite3.c /link $(LDFLAGS) $(LTLINKOPTS)
|
/link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
|
||||||
|
|
||||||
fuzzcheck.exe: $(TOP)\test\fuzzcheck.c sqlite3.c sqlite3.h
|
# <<mark>>
|
||||||
$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(TOP)\test\fuzzcheck.c sqlite3.c /link $(LDFLAGS) $(LTLINKOPTS)
|
sqldiff.exe: $(TOP)\tool\sqldiff.c $(SQLITE3C) $(SQLITE3H)
|
||||||
|
$(LTLINK) $(NO_WARN) $(TOP)\tool\sqldiff.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||||
|
|
||||||
mptester.exe: $(TOP)\mptest\mptest.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
|
fuzzershell.exe: $(TOP)\tool\fuzzershell.c $(SQLITE3C) $(SQLITE3H)
|
||||||
$(LTLINK) $(NO_WARN) $(SHELL_COMPILE_OPTS) $(TOP)\mptest\mptest.c \
|
$(LTLINK) $(NO_WARN) $(FUZZERSHELL_COMPILE_OPTS) $(TOP)\tool\fuzzershell.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||||
/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(SHELL_LINK_OPTS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
|
|
||||||
|
fuzzcheck.exe: $(TOP)\test\fuzzcheck.c $(SQLITE3C) $(SQLITE3H)
|
||||||
|
$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(TOP)\test\fuzzcheck.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||||
|
|
||||||
|
mptester.exe: $(TOP)\mptest\mptest.c $(SQLITE3C) $(SQLITE3H)
|
||||||
|
$(LTLINK) $(NO_WARN) $(MPTESTER_COMPILE_OPTS) $(TOP)\mptest\mptest.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||||
|
|
||||||
MPTEST1 = mptester mptest.db $(TOP)\mptest\crash01.test --repeat 20
|
MPTEST1 = mptester mptest.db $(TOP)\mptest\crash01.test --repeat 20
|
||||||
MPTEST2 = mptester mptest.db $(TOP)\mptest\multiwrite01.test --repeat 20
|
MPTEST2 = mptester mptest.db $(TOP)\mptest\multiwrite01.test --repeat 20
|
||||||
@ -1295,21 +1435,14 @@ sqlite3.c: .target_source sqlite3ext.h $(TOP)\tool\mksqlite3c.tcl
|
|||||||
|
|
||||||
sqlite3-all.c: sqlite3.c $(TOP)\tool\split-sqlite3c.tcl
|
sqlite3-all.c: sqlite3.c $(TOP)\tool\split-sqlite3c.tcl
|
||||||
$(TCLSH_CMD) $(TOP)\tool\split-sqlite3c.tcl
|
$(TCLSH_CMD) $(TOP)\tool\split-sqlite3c.tcl
|
||||||
|
# <</mark>>
|
||||||
# Set the source code file to be used by executables and libraries when
|
|
||||||
# they need the amalgamation.
|
|
||||||
#
|
|
||||||
!IF $(SPLIT_AMALGAMATION)!=0
|
|
||||||
SQLITE3C = sqlite3-all.c
|
|
||||||
!ELSE
|
|
||||||
SQLITE3C = sqlite3.c
|
|
||||||
!ENDIF
|
|
||||||
|
|
||||||
# Rule to build the amalgamation
|
# Rule to build the amalgamation
|
||||||
#
|
#
|
||||||
sqlite3.lo: $(SQLITE3C)
|
sqlite3.lo: $(SQLITE3C)
|
||||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(SQLITE3C)
|
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(SQLITE3C)
|
||||||
|
|
||||||
|
# <<mark>>
|
||||||
# Rules to build the LEMON compiler generator
|
# Rules to build the LEMON compiler generator
|
||||||
#
|
#
|
||||||
lempar.c: $(TOP)\tool\lempar.c
|
lempar.c: $(TOP)\tool\lempar.c
|
||||||
@ -1330,11 +1463,13 @@ parse.lo: parse.c $(HDR)
|
|||||||
|
|
||||||
opcodes.lo: opcodes.c
|
opcodes.lo: opcodes.c
|
||||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c opcodes.c
|
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c opcodes.c
|
||||||
|
# <</mark>>
|
||||||
|
|
||||||
# Rule to build the Win32 resources object file.
|
# Rule to build the Win32 resources object file.
|
||||||
#
|
#
|
||||||
!IF $(USE_RC)!=0
|
!IF $(USE_RC)!=0
|
||||||
$(LIBRESOBJS): $(TOP)\src\sqlite3.rc $(HDR)
|
# <<block1>>
|
||||||
|
$(LIBRESOBJS): $(TOP)\src\sqlite3.rc $(SQLITE3H)
|
||||||
echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h
|
echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h
|
||||||
for /F %%V in ('type "$(TOP)\VERSION"') do ( \
|
for /F %%V in ('type "$(TOP)\VERSION"') do ( \
|
||||||
echo #define SQLITE_RESOURCE_VERSION %%V \
|
echo #define SQLITE_RESOURCE_VERSION %%V \
|
||||||
@ -1342,8 +1477,10 @@ $(LIBRESOBJS): $(TOP)\src\sqlite3.rc $(HDR)
|
|||||||
)
|
)
|
||||||
echo #endif >> sqlite3rc.h
|
echo #endif >> sqlite3rc.h
|
||||||
$(LTRCOMPILE) -fo $(LIBRESOBJS) $(TOP)\src\sqlite3.rc
|
$(LTRCOMPILE) -fo $(LIBRESOBJS) $(TOP)\src\sqlite3.rc
|
||||||
|
# <</block1>>
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
|
# <<mark>>
|
||||||
# Rules to build individual *.lo files from files in the src directory.
|
# Rules to build individual *.lo files from files in the src directory.
|
||||||
#
|
#
|
||||||
alter.lo: $(TOP)\src\alter.c $(HDR)
|
alter.lo: $(TOP)\src\alter.c $(HDR)
|
||||||
@ -1574,7 +1711,7 @@ tclsqlite.lo: $(TOP)\src\tclsqlite.c $(HDR)
|
|||||||
tclsqlite-shell.lo: $(TOP)\src\tclsqlite.c $(HDR)
|
tclsqlite-shell.lo: $(TOP)\src\tclsqlite.c $(HDR)
|
||||||
$(LTCOMPILE) $(NO_WARN) -DTCLSH=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
|
$(LTCOMPILE) $(NO_WARN) -DTCLSH=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
|
||||||
|
|
||||||
tclsqlite3.exe: tclsqlite-shell.lo $(SQLITE3C) $(LIBRESOBJS)
|
tclsqlite3.exe: tclsqlite-shell.lo $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS)
|
||||||
$(LTLINK) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite-shell.lo $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
$(LTLINK) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite-shell.lo $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
||||||
|
|
||||||
# Rules to build opcodes.c and opcodes.h
|
# Rules to build opcodes.c and opcodes.h
|
||||||
@ -1592,18 +1729,18 @@ parse.h: parse.c
|
|||||||
parse.c: $(TOP)\src\parse.y lemon.exe $(TOP)\tool\addopcodes.tcl
|
parse.c: $(TOP)\src\parse.y lemon.exe $(TOP)\tool\addopcodes.tcl
|
||||||
del /Q parse.y parse.h parse.h.temp 2>NUL
|
del /Q parse.y parse.h parse.h.temp 2>NUL
|
||||||
copy $(TOP)\src\parse.y .
|
copy $(TOP)\src\parse.y .
|
||||||
.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) parse.y
|
.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) parse.y
|
||||||
move parse.h parse.h.temp
|
move parse.h parse.h.temp
|
||||||
$(TCLSH_CMD) $(TOP)\tool\addopcodes.tcl parse.h.temp > parse.h
|
$(TCLSH_CMD) $(TOP)\tool\addopcodes.tcl parse.h.temp > parse.h
|
||||||
|
|
||||||
sqlite3.h: $(TOP)\src\sqlite.h.in $(TOP)\manifest.uuid $(TOP)\VERSION
|
$(SQLITE3H): $(TOP)\src\sqlite.h.in $(TOP)\manifest.uuid $(TOP)\VERSION
|
||||||
$(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > sqlite3.h
|
$(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > $(SQLITE3H)
|
||||||
|
|
||||||
sqlite3ext.h: .target_source
|
sqlite3ext.h: .target_source
|
||||||
copy tsrc\sqlite3ext.h .
|
copy tsrc\sqlite3ext.h .
|
||||||
|
|
||||||
mkkeywordhash.exe: $(TOP)\tool\mkkeywordhash.c
|
mkkeywordhash.exe: $(TOP)\tool\mkkeywordhash.c
|
||||||
$(BCC) $(NO_WARN) -Fe$@ $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) \
|
$(BCC) $(NO_WARN) -Fe$@ $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) \
|
||||||
$(TOP)\tool\mkkeywordhash.c /link $(LDFLAGS) $(NLTLINKOPTS) $(NLTLIBPATHS)
|
$(TOP)\tool\mkkeywordhash.c /link $(LDFLAGS) $(NLTLINKOPTS) $(NLTLIBPATHS)
|
||||||
|
|
||||||
keywordhash.h: $(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe
|
keywordhash.h: $(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe
|
||||||
@ -1698,7 +1835,7 @@ FTS5_SRC = \
|
|||||||
fts5parse.c: $(TOP)\ext\fts5\fts5parse.y lemon.exe
|
fts5parse.c: $(TOP)\ext\fts5\fts5parse.y lemon.exe
|
||||||
copy $(TOP)\ext\fts5\fts5parse.y .
|
copy $(TOP)\ext\fts5\fts5parse.y .
|
||||||
del /Q fts5parse.h 2>NUL
|
del /Q fts5parse.h 2>NUL
|
||||||
.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) fts5parse.y
|
.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) fts5parse.y
|
||||||
|
|
||||||
fts5parse.h: fts5parse.c
|
fts5parse.h: fts5parse.c
|
||||||
|
|
||||||
@ -1737,7 +1874,7 @@ TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0)
|
|||||||
TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC1)
|
TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC1)
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
testfixture.exe: $(TESTFIXTURE_SRC) $(LIBRESOBJS) $(HDR)
|
testfixture.exe: $(TESTFIXTURE_SRC) $(SQLITE3H) $(LIBRESOBJS) $(HDR)
|
||||||
$(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \
|
$(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \
|
||||||
-DBUILD_sqlite -I$(TCLINCDIR) \
|
-DBUILD_sqlite -I$(TCLINCDIR) \
|
||||||
$(TESTFIXTURE_SRC) \
|
$(TESTFIXTURE_SRC) \
|
||||||
@ -1759,7 +1896,7 @@ fulltestonly: $(TESTPROGS) fuzztest
|
|||||||
@set PATH=$(LIBTCLPATH);$(PATH)
|
@set PATH=$(LIBTCLPATH);$(PATH)
|
||||||
.\testfixture.exe $(TOP)\test\full.test
|
.\testfixture.exe $(TOP)\test\full.test
|
||||||
|
|
||||||
queryplantest: testfixture.exe sqlite3.exe
|
queryplantest: testfixture.exe shell
|
||||||
@set PATH=$(LIBTCLPATH);$(PATH)
|
@set PATH=$(LIBTCLPATH);$(PATH)
|
||||||
.\testfixture.exe $(TOP)\test\permutations.test queryplanner $(TESTOPTS)
|
.\testfixture.exe $(TOP)\test\permutations.test queryplanner $(TESTOPTS)
|
||||||
|
|
||||||
@ -1786,7 +1923,7 @@ smoketest: $(TESTPROGS)
|
|||||||
@set PATH=$(LIBTCLPATH);$(PATH)
|
@set PATH=$(LIBTCLPATH);$(PATH)
|
||||||
.\testfixture.exe $(TOP)\test\main.test $(TESTOPTS)
|
.\testfixture.exe $(TOP)\test\main.test $(TESTOPTS)
|
||||||
|
|
||||||
sqlite3_analyzer.c: $(SQLITE3C) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl
|
sqlite3_analyzer.c: $(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl
|
||||||
echo #define TCLSH 2 > $@
|
echo #define TCLSH 2 > $@
|
||||||
echo #define SQLITE_ENABLE_DBSTAT_VTAB 1 >> $@
|
echo #define SQLITE_ENABLE_DBSTAT_VTAB 1 >> $@
|
||||||
copy $@ + $(SQLITE3C) + $(TOP)\src\tclsqlite.c $@
|
copy $@ + $(SQLITE3C) + $(TOP)\src\tclsqlite.c $@
|
||||||
@ -1805,49 +1942,51 @@ testloadext.lo: $(TOP)\src\test_loadext.c
|
|||||||
testloadext.dll: testloadext.lo
|
testloadext.dll: testloadext.lo
|
||||||
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /OUT:$@ testloadext.lo
|
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /OUT:$@ testloadext.lo
|
||||||
|
|
||||||
showdb.exe: $(TOP)\tool\showdb.c $(SQLITE3C)
|
showdb.exe: $(TOP)\tool\showdb.c $(SQLITE3C) $(SQLITE3H)
|
||||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||||
$(TOP)\tool\showdb.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
$(TOP)\tool\showdb.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||||
|
|
||||||
showstat4.exe: $(TOP)\tool\showstat4.c $(SQLITE3C)
|
showstat4.exe: $(TOP)\tool\showstat4.c $(SQLITE3C) $(SQLITE3H)
|
||||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||||
$(TOP)\tool\showstat4.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
$(TOP)\tool\showstat4.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||||
|
|
||||||
showjournal.exe: $(TOP)\tool\showjournal.c $(SQLITE3C)
|
showjournal.exe: $(TOP)\tool\showjournal.c $(SQLITE3C) $(SQLITE3H)
|
||||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||||
$(TOP)\tool\showjournal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
$(TOP)\tool\showjournal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||||
|
|
||||||
showwal.exe: $(TOP)\tool\showwal.c $(SQLITE3C)
|
showwal.exe: $(TOP)\tool\showwal.c $(SQLITE3C) $(SQLITE3H)
|
||||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||||
$(TOP)\tool\showwal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
$(TOP)\tool\showwal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||||
|
|
||||||
fts3view.exe: $(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C)
|
fts3view.exe: $(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) $(SQLITE3H)
|
||||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||||
$(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
$(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||||
|
|
||||||
rollback-test.exe: $(TOP)\tool\rollback-test.c $(SQLITE3C)
|
rollback-test.exe: $(TOP)\tool\rollback-test.c $(SQLITE3C) $(SQLITE3H)
|
||||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||||
$(TOP)\tool\rollback-test.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
$(TOP)\tool\rollback-test.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||||
|
|
||||||
LogEst.exe: $(TOP)\tool\logest.c sqlite3.h
|
LogEst.exe: $(TOP)\tool\logest.c $(SQLITE3H)
|
||||||
$(LTLINK) $(NO_WARN) -Fe$@ $(TOP)\tool\LogEst.c /link $(LDFLAGS) $(LTLINKOPTS)
|
$(LTLINK) $(NO_WARN) -Fe$@ $(TOP)\tool\LogEst.c /link $(LDFLAGS) $(LTLINKOPTS)
|
||||||
|
|
||||||
wordcount.exe: $(TOP)\test\wordcount.c $(SQLITE3C)
|
wordcount.exe: $(TOP)\test\wordcount.c $(SQLITE3C) $(SQLITE3H)
|
||||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||||
$(TOP)\test\wordcount.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
$(TOP)\test\wordcount.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||||
|
|
||||||
speedtest1.exe: $(TOP)\test\speedtest1.c $(SQLITE3C)
|
speedtest1.exe: $(TOP)\test\speedtest1.c $(SQLITE3C) $(SQLITE3H)
|
||||||
$(LTLINK) $(NO_WARN) -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
$(LTLINK) $(NO_WARN) -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||||
$(TOP)\test\speedtest1.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
$(TOP)\test\speedtest1.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||||
|
|
||||||
rbu.exe: $(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C)
|
rbu.exe: $(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C) $(SQLITE3H)
|
||||||
$(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU -Fe$@ $(TOP)\ext\rbu\rbu.c $(SQLITE3C) \
|
$(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU -Fe$@ \
|
||||||
/link $(LDFLAGS) $(LTLINKOPTS)
|
$(TOP)\ext\rbu\rbu.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||||
|
# <</mark>>
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL
|
del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL
|
||||||
del /Q *.bsc *.cod *.da *.bb *.bbg gmon.out 2>NUL
|
del /Q *.bsc *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL
|
||||||
del /Q sqlite3.h opcodes.c opcodes.h 2>NUL
|
# <<mark>>
|
||||||
|
del /Q $(SQLITE3C) $(SQLITE3H) opcodes.c opcodes.h 2>NUL
|
||||||
del /Q lemon.* lempar.c parse.* 2>NUL
|
del /Q lemon.* lempar.c parse.* 2>NUL
|
||||||
del /Q mkkeywordhash.* keywordhash.h 2>NUL
|
del /Q mkkeywordhash.* keywordhash.h 2>NUL
|
||||||
del /Q notasharedlib.* 2>NUL
|
del /Q notasharedlib.* 2>NUL
|
||||||
@ -1864,7 +2003,7 @@ clean:
|
|||||||
del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe 2>NUL
|
del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe 2>NUL
|
||||||
del /Q showjournal.exe showstat4.exe showwal.exe speedtest1.exe 2>NUL
|
del /Q showjournal.exe showstat4.exe showwal.exe speedtest1.exe 2>NUL
|
||||||
del /Q mptester.exe wordcount.exe rbu.exe 2>NUL
|
del /Q mptester.exe wordcount.exe rbu.exe 2>NUL
|
||||||
del /Q sqlite3.exe sqlite3.dll sqlite3.def 2>NUL
|
del /Q $(SQLITE3EXE) $(SQLITE3DLL) sqlite3.def 2>NUL
|
||||||
del /Q sqlite3.c sqlite3-*.c 2>NUL
|
del /Q sqlite3.c sqlite3-*.c 2>NUL
|
||||||
del /Q sqlite3rc.h 2>NUL
|
del /Q sqlite3rc.h 2>NUL
|
||||||
del /Q shell.c sqlite3ext.h 2>NUL
|
del /Q shell.c sqlite3ext.h 2>NUL
|
||||||
@ -1872,16 +2011,4 @@ clean:
|
|||||||
del /Q sqlite-*-output.vsix 2>NUL
|
del /Q sqlite-*-output.vsix 2>NUL
|
||||||
del /Q fuzzershell.exe fuzzcheck.exe sqldiff.exe 2>NUL
|
del /Q fuzzershell.exe fuzzcheck.exe sqldiff.exe 2>NUL
|
||||||
del /Q fts5.* fts5parse.* 2>NUL
|
del /Q fts5.* fts5parse.* 2>NUL
|
||||||
|
# <</mark>>
|
||||||
# Dynamic link library section.
|
|
||||||
#
|
|
||||||
dll: sqlite3.dll
|
|
||||||
|
|
||||||
sqlite3.def: libsqlite3.lib
|
|
||||||
echo EXPORTS > sqlite3.def
|
|
||||||
dumpbin /all libsqlite3.lib \
|
|
||||||
| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3_.*)$$" \1 \
|
|
||||||
| sort >> sqlite3.def
|
|
||||||
|
|
||||||
sqlite3.dll: $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
|
|
||||||
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
|
||||||
|
@ -14,7 +14,7 @@ sqlite3_CFLAGS = $(AM_CFLAGS)
|
|||||||
|
|
||||||
include_HEADERS = sqlite3.h sqlite3ext.h
|
include_HEADERS = sqlite3.h sqlite3ext.h
|
||||||
|
|
||||||
EXTRA_DIST = sqlite3.1 tea
|
EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc README.txt
|
||||||
pkgconfigdir = ${libdir}/pkgconfig
|
pkgconfigdir = ${libdir}/pkgconfig
|
||||||
pkgconfig_DATA = sqlite3.pc
|
pkgconfig_DATA = sqlite3.pc
|
||||||
|
|
||||||
|
892
autoconf/Makefile.msc
Normal file
892
autoconf/Makefile.msc
Normal file
@ -0,0 +1,892 @@
|
|||||||
|
#### DO NOT EDIT ####
|
||||||
|
# This makefile is automatically generated from the Makefile.msc at
|
||||||
|
# the root of the canonical SQLite source tree (not the
|
||||||
|
# amalgamation tarball) using the tool/mkmsvcmin.tcl
|
||||||
|
# script.
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# nmake Makefile for SQLite
|
||||||
|
#
|
||||||
|
###############################################################################
|
||||||
|
############################## START OF OPTIONS ###############################
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
# The toplevel directory of the source tree. This is the directory
|
||||||
|
# that contains this "Makefile.msc".
|
||||||
|
#
|
||||||
|
TOP = .
|
||||||
|
|
||||||
|
|
||||||
|
# Set this non-0 to enable full warnings (-W4, etc) when compiling.
|
||||||
|
#
|
||||||
|
!IFNDEF USE_FULLWARN
|
||||||
|
USE_FULLWARN = 0
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Set this non-0 to use "stdcall" calling convention for the core library
|
||||||
|
# and shell executable.
|
||||||
|
#
|
||||||
|
!IFNDEF USE_STDCALL
|
||||||
|
USE_STDCALL = 0
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Set this non-0 to have the shell executable link against the core dynamic
|
||||||
|
# link library.
|
||||||
|
#
|
||||||
|
!IFNDEF DYNAMIC_SHELL
|
||||||
|
DYNAMIC_SHELL = 0
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Set this non-0 to enable extra code that attempts to detect misuse of the
|
||||||
|
# SQLite API.
|
||||||
|
#
|
||||||
|
!IFNDEF API_ARMOR
|
||||||
|
API_ARMOR = 0
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# If necessary, create a list of harmless compiler warnings to disable when
|
||||||
|
# compiling the various tools. For the SQLite source code itself, warnings,
|
||||||
|
# if any, will be disabled from within it.
|
||||||
|
#
|
||||||
|
!IFNDEF NO_WARN
|
||||||
|
!IF $(USE_FULLWARN)!=0
|
||||||
|
NO_WARN = -wd4054 -wd4055 -wd4100 -wd4127 -wd4130 -wd4152 -wd4189 -wd4206
|
||||||
|
NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4305 -wd4306 -wd4702 -wd4706
|
||||||
|
!ENDIF
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Set this non-0 to use the library paths and other options necessary for
|
||||||
|
# Windows Phone 8.1.
|
||||||
|
#
|
||||||
|
!IFNDEF USE_WP81_OPTS
|
||||||
|
USE_WP81_OPTS = 0
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Set this non-0 to split the SQLite amalgamation file into chunks to
|
||||||
|
# be used for debugging with Visual Studio.
|
||||||
|
#
|
||||||
|
!IFNDEF SPLIT_AMALGAMATION
|
||||||
|
SPLIT_AMALGAMATION = 0
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
# Set this non-0 to dynamically link to the MSVC runtime library.
|
||||||
|
#
|
||||||
|
!IFNDEF USE_CRT_DLL
|
||||||
|
USE_CRT_DLL = 0
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Set this non-0 to link to the RPCRT4 library.
|
||||||
|
#
|
||||||
|
!IFNDEF USE_RPCRT4_LIB
|
||||||
|
USE_RPCRT4_LIB = 0
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Set this non-0 to generate assembly code listings for the source code
|
||||||
|
# files.
|
||||||
|
#
|
||||||
|
!IFNDEF USE_LISTINGS
|
||||||
|
USE_LISTINGS = 0
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Set this non-0 to attempt setting the native compiler automatically
|
||||||
|
# for cross-compiling the command line tools needed during the compilation
|
||||||
|
# process.
|
||||||
|
#
|
||||||
|
!IFNDEF XCOMPILE
|
||||||
|
XCOMPILE = 0
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Set this non-0 to use the native libraries paths for cross-compiling
|
||||||
|
# the command line tools needed during the compilation process.
|
||||||
|
#
|
||||||
|
!IFNDEF USE_NATIVE_LIBPATHS
|
||||||
|
USE_NATIVE_LIBPATHS = 0
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Set this 0 to skip the compiling and embedding of version resources.
|
||||||
|
#
|
||||||
|
!IFNDEF USE_RC
|
||||||
|
USE_RC = 1
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# 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).
|
||||||
|
#
|
||||||
|
!IFNDEF FOR_WINRT
|
||||||
|
FOR_WINRT = 0
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Set this non-0 to compile binaries suitable for the UAP environment.
|
||||||
|
# This setting does not apply to any binaries that require Tcl to operate
|
||||||
|
# properly (i.e. the text fixture, etc).
|
||||||
|
#
|
||||||
|
!IFNDEF FOR_UAP
|
||||||
|
FOR_UAP = 0
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Set this non-0 to compile binaries suitable for the Windows 10 platform.
|
||||||
|
#
|
||||||
|
!IFNDEF FOR_WIN10
|
||||||
|
FOR_WIN10 = 0
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
# Set this to non-0 to create and use PDBs.
|
||||||
|
#
|
||||||
|
!IFNDEF SYMBOLS
|
||||||
|
SYMBOLS = 1
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Set this to non-0 to use the SQLite debugging heap subsystem.
|
||||||
|
#
|
||||||
|
!IFNDEF MEMDEBUG
|
||||||
|
MEMDEBUG = 0
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Set this to non-0 to use the Win32 native heap subsystem.
|
||||||
|
#
|
||||||
|
!IFNDEF WIN32HEAP
|
||||||
|
WIN32HEAP = 0
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Set this to non-0 to enable OSTRACE() macros, which can be useful when
|
||||||
|
# debugging.
|
||||||
|
#
|
||||||
|
!IFNDEF OSTRACE
|
||||||
|
OSTRACE = 0
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Set this to one of the following values to enable various debugging
|
||||||
|
# features. Each level includes the debugging options from the previous
|
||||||
|
# levels. Currently, the recognized values for DEBUG are:
|
||||||
|
#
|
||||||
|
# 0 == NDEBUG: Disables assert() and other runtime diagnostics.
|
||||||
|
# 1 == SQLITE_ENABLE_API_ARMOR: extra attempts to detect misuse of the API.
|
||||||
|
# 2 == Disables NDEBUG and all optimizations and then enables PDBs.
|
||||||
|
# 3 == SQLITE_DEBUG: Enables various diagnostics messages and code.
|
||||||
|
# 4 == SQLITE_WIN32_MALLOC_VALIDATE: Validate the Win32 native heap per call.
|
||||||
|
# 5 == SQLITE_DEBUG_OS_TRACE: Enables output from the OSTRACE() macros.
|
||||||
|
# 6 == SQLITE_ENABLE_IOTRACE: Enables output from the IOTRACE() macros.
|
||||||
|
#
|
||||||
|
!IFNDEF DEBUG
|
||||||
|
DEBUG = 0
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Enable use of available compiler optimizations? Normally, this should be
|
||||||
|
# non-zero. Setting this to zero, thus disabling all compiler optimizations,
|
||||||
|
# can be useful for testing.
|
||||||
|
#
|
||||||
|
!IFNDEF OPTIMIZATIONS
|
||||||
|
OPTIMIZATIONS = 2
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Set the source code file to be used by executables and libraries when
|
||||||
|
# they need the amalgamation.
|
||||||
|
#
|
||||||
|
!IFNDEF SQLITE3C
|
||||||
|
!IF $(SPLIT_AMALGAMATION)!=0
|
||||||
|
SQLITE3C = sqlite3-all.c
|
||||||
|
!ELSE
|
||||||
|
SQLITE3C = sqlite3.c
|
||||||
|
!ENDIF
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Set the include code file to be used by executables and libraries when
|
||||||
|
# they need SQLite.
|
||||||
|
#
|
||||||
|
!IFNDEF SQLITE3H
|
||||||
|
SQLITE3H = sqlite3.h
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# This is the name to use for the SQLite dynamic link library (DLL).
|
||||||
|
#
|
||||||
|
!IFNDEF SQLITE3DLL
|
||||||
|
SQLITE3DLL = sqlite3.dll
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# This is the name to use for the SQLite import library (LIB).
|
||||||
|
#
|
||||||
|
!IFNDEF SQLITE3LIB
|
||||||
|
SQLITE3LIB = sqlite3.lib
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# This is the name to use for the SQLite shell executable (EXE).
|
||||||
|
#
|
||||||
|
!IFNDEF SQLITE3EXE
|
||||||
|
SQLITE3EXE = sqlite3.exe
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# This is the argument used to set the program database (PDB) file for the
|
||||||
|
# SQLite shell executable (EXE).
|
||||||
|
#
|
||||||
|
!IFNDEF SQLITE3EXEPDB
|
||||||
|
SQLITE3EXEPDB = /pdb:sqlite3sh.pdb
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# These are the "standard" SQLite compilation options used when compiling for
|
||||||
|
# the Windows platform.
|
||||||
|
#
|
||||||
|
!IFNDEF OPT_FEATURE_FLAGS
|
||||||
|
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1
|
||||||
|
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1
|
||||||
|
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# These are the "extended" SQLite compilation options used when compiling for
|
||||||
|
# the Windows 10 platform.
|
||||||
|
#
|
||||||
|
!IFNDEF EXT_FEATURE_FLAGS
|
||||||
|
!IF $(FOR_WIN10)!=0
|
||||||
|
EXT_FEATURE_FLAGS = $(EXT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS4=1
|
||||||
|
EXT_FEATURE_FLAGS = $(EXT_FEATURE_FLAGS) -DSQLITE_SYSTEM_MALLOC=1
|
||||||
|
EXT_FEATURE_FLAGS = $(EXT_FEATURE_FLAGS) -DSQLITE_OMIT_LOCALTIME=1
|
||||||
|
!ELSE
|
||||||
|
EXT_FEATURE_FLAGS =
|
||||||
|
!ENDIF
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
############################### END OF OPTIONS ################################
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
# This assumes that MSVC is always installed in 32-bit Program Files directory
|
||||||
|
# and sets the variable for use in locating other 32-bit installs accordingly.
|
||||||
|
#
|
||||||
|
PROGRAMFILES_X86 = $(VCINSTALLDIR)\..\..
|
||||||
|
PROGRAMFILES_X86 = $(PROGRAMFILES_X86:\\=\)
|
||||||
|
|
||||||
|
# Check for the predefined command macro CC. This should point to the compiler
|
||||||
|
# binary for the target platform. If it is not defined, simply define it to
|
||||||
|
# the legacy default value 'cl.exe'.
|
||||||
|
#
|
||||||
|
!IFNDEF CC
|
||||||
|
CC = cl.exe
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Check for the command macro LD. This should point to the linker binary for
|
||||||
|
# the target platform. If it is not defined, simply define it to the legacy
|
||||||
|
# default value 'link.exe'.
|
||||||
|
#
|
||||||
|
!IFNDEF LD
|
||||||
|
LD = link.exe
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Check for the predefined command macro RC. This should point to the resource
|
||||||
|
# compiler binary for the target platform. If it is not defined, simply define
|
||||||
|
# it to the legacy default value 'rc.exe'.
|
||||||
|
#
|
||||||
|
!IFNDEF RC
|
||||||
|
RC = rc.exe
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Check for the MSVC runtime library path macro. Othertise, this value will
|
||||||
|
# default to the 'lib' directory underneath the MSVC installation directory.
|
||||||
|
#
|
||||||
|
!IFNDEF CRTLIBPATH
|
||||||
|
CRTLIBPATH = $(VCINSTALLDIR)\lib
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
CRTLIBPATH = $(CRTLIBPATH:\\=\)
|
||||||
|
|
||||||
|
# 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 sqlite3.dll
|
||||||
|
# XCOMPILE=1 USE_NATIVE_LIBPATHS=1
|
||||||
|
#
|
||||||
|
# Alternatively, the full path and file name to the compiler binary for the
|
||||||
|
# platform the compilation process is taking place may be specified (all on
|
||||||
|
# one line):
|
||||||
|
#
|
||||||
|
# nmake /f Makefile.msc sqlite3.dll
|
||||||
|
# "NCC=""%VCINSTALLDIR%\bin\cl.exe"""
|
||||||
|
# USE_NATIVE_LIBPATHS=1
|
||||||
|
#
|
||||||
|
!IFDEF NCC
|
||||||
|
NCC = $(NCC:\\=\)
|
||||||
|
!ELSEIF $(XCOMPILE)!=0
|
||||||
|
NCC = "$(VCINSTALLDIR)\bin\$(CC)"
|
||||||
|
NCC = $(NCC:\\=\)
|
||||||
|
!ELSE
|
||||||
|
NCC = $(CC)
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Check for the MSVC native runtime library path macro. Othertise,
|
||||||
|
# this value will default to the 'lib' directory underneath the MSVC
|
||||||
|
# installation directory.
|
||||||
|
#
|
||||||
|
!IFNDEF NCRTLIBPATH
|
||||||
|
NCRTLIBPATH = $(VCINSTALLDIR)\lib
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
NCRTLIBPATH = $(NCRTLIBPATH:\\=\)
|
||||||
|
|
||||||
|
# Check for the Platform SDK library path macro. Othertise, this
|
||||||
|
# value will default to the 'lib' directory underneath the Windows
|
||||||
|
# SDK installation directory (the environment variable used appears
|
||||||
|
# to be available when using Visual C++ 2008 or later via the
|
||||||
|
# command line).
|
||||||
|
#
|
||||||
|
!IFNDEF NSDKLIBPATH
|
||||||
|
NSDKLIBPATH = $(WINDOWSSDKDIR)\lib
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
NSDKLIBPATH = $(NSDKLIBPATH:\\=\)
|
||||||
|
|
||||||
|
# C compiler and options for use in building executables that
|
||||||
|
# will run on the platform that is doing the build.
|
||||||
|
#
|
||||||
|
!IF $(USE_FULLWARN)!=0
|
||||||
|
BCC = $(NCC) -nologo -W4 $(CCOPTS) $(BCCOPTS)
|
||||||
|
!ELSE
|
||||||
|
BCC = $(NCC) -nologo -W3 $(CCOPTS) $(BCCOPTS)
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Check if assembly code listings should be generated for the source
|
||||||
|
# code files to be compiled.
|
||||||
|
#
|
||||||
|
!IF $(USE_LISTINGS)!=0
|
||||||
|
BCC = $(BCC) -FAcs
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# 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)"
|
||||||
|
|
||||||
|
!IFDEF NUCRTLIBPATH
|
||||||
|
NUCRTLIBPATH = $(NUCRTLIBPATH:\\=\)
|
||||||
|
NLTLIBPATHS = $(NLTLIBPATHS) "/LIBPATH:$(NUCRTLIBPATH)"
|
||||||
|
!ENDIF
|
||||||
|
!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.)
|
||||||
|
#
|
||||||
|
!IF $(USE_FULLWARN)!=0
|
||||||
|
TCC = $(CC) -nologo -W4 -DINCLUDE_MSVC_H=1 $(CCOPTS) $(TCCOPTS)
|
||||||
|
!ELSE
|
||||||
|
TCC = $(CC) -nologo -W3 $(CCOPTS) $(TCCOPTS)
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
TCC = $(TCC) -DSQLITE_OS_WIN=1 -I$(TOP) -fp:precise
|
||||||
|
RCC = $(RC) -DSQLITE_OS_WIN=1 -I$(TOP) $(RCOPTS) $(RCCOPTS)
|
||||||
|
|
||||||
|
# Adjust the names of the primary targets for use with Windows 10.
|
||||||
|
#
|
||||||
|
!IF $(FOR_WIN10)!=0
|
||||||
|
SQLITE3DLL = winsqlite3.dll
|
||||||
|
SQLITE3LIB = winsqlite3.lib
|
||||||
|
SQLITE3EXE = winsqlite3shell.exe
|
||||||
|
SQLITE3EXEPDB =
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Check if we want to use the "stdcall" calling convention when compiling.
|
||||||
|
# This is not supported by the compilers for non-x86 platforms. It should
|
||||||
|
# also be noted here that building any target with these "stdcall" options
|
||||||
|
# will most likely fail if the Tcl library is also required. This is due
|
||||||
|
# to how the Tcl library functions are declared and exported (i.e. without
|
||||||
|
# an explicit calling convention, which results in "cdecl").
|
||||||
|
#
|
||||||
|
!IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0
|
||||||
|
!IF "$(PLATFORM)"=="x86"
|
||||||
|
CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall
|
||||||
|
SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall
|
||||||
|
!ELSE
|
||||||
|
!IFNDEF PLATFORM
|
||||||
|
CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall
|
||||||
|
SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall
|
||||||
|
!ELSE
|
||||||
|
CORE_CCONV_OPTS =
|
||||||
|
SHELL_CCONV_OPTS =
|
||||||
|
!ENDIF
|
||||||
|
!ENDIF
|
||||||
|
!ELSE
|
||||||
|
CORE_CCONV_OPTS =
|
||||||
|
SHELL_CCONV_OPTS =
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# These are additional compiler options used for the core library.
|
||||||
|
#
|
||||||
|
!IFNDEF CORE_COMPILE_OPTS
|
||||||
|
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
|
||||||
|
CORE_COMPILE_OPTS = $(CORE_CCONV_OPTS) -DSQLITE_API=__declspec(dllexport)
|
||||||
|
!ELSE
|
||||||
|
CORE_COMPILE_OPTS = $(CORE_CCONV_OPTS)
|
||||||
|
!ENDIF
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# These are the additional targets that the core library should depend on
|
||||||
|
# when linking.
|
||||||
|
#
|
||||||
|
!IFNDEF CORE_LINK_DEP
|
||||||
|
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
|
||||||
|
CORE_LINK_DEP =
|
||||||
|
!ELSE
|
||||||
|
CORE_LINK_DEP =
|
||||||
|
!ENDIF
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# These are additional linker options used for the core library.
|
||||||
|
#
|
||||||
|
!IFNDEF CORE_LINK_OPTS
|
||||||
|
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
|
||||||
|
CORE_LINK_OPTS =
|
||||||
|
!ELSE
|
||||||
|
CORE_LINK_OPTS =
|
||||||
|
!ENDIF
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# These are additional compiler options used for the shell executable.
|
||||||
|
#
|
||||||
|
!IFNDEF SHELL_COMPILE_OPTS
|
||||||
|
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
|
||||||
|
SHELL_COMPILE_OPTS = $(SHELL_CCONV_OPTS) -DSQLITE_API=__declspec(dllimport)
|
||||||
|
!ELSE
|
||||||
|
SHELL_COMPILE_OPTS = $(SHELL_CCONV_OPTS)
|
||||||
|
!ENDIF
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# This is the source code that the shell executable should be compiled
|
||||||
|
# with.
|
||||||
|
#
|
||||||
|
!IFNDEF SHELL_CORE_SRC
|
||||||
|
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
|
||||||
|
SHELL_CORE_SRC =
|
||||||
|
!ELSE
|
||||||
|
SHELL_CORE_SRC = $(SQLITE3C)
|
||||||
|
!ENDIF
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# This is the core library that the shell executable should depend on.
|
||||||
|
#
|
||||||
|
!IFNDEF SHELL_CORE_DEP
|
||||||
|
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
|
||||||
|
SHELL_CORE_DEP = $(SQLITE3DLL)
|
||||||
|
!ELSE
|
||||||
|
SHELL_CORE_DEP =
|
||||||
|
!ENDIF
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# This is the core library that the shell executable should link with.
|
||||||
|
#
|
||||||
|
!IFNDEF SHELL_CORE_LIB
|
||||||
|
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
|
||||||
|
SHELL_CORE_LIB = $(SQLITE3LIB)
|
||||||
|
!ELSE
|
||||||
|
SHELL_CORE_LIB =
|
||||||
|
!ENDIF
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# These are additional linker options used for the shell executable.
|
||||||
|
#
|
||||||
|
!IFNDEF SHELL_LINK_OPTS
|
||||||
|
SHELL_LINK_OPTS = $(SHELL_CORE_LIB)
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Check if assembly code listings should be generated for the source
|
||||||
|
# code files to be compiled.
|
||||||
|
#
|
||||||
|
!IF $(USE_LISTINGS)!=0
|
||||||
|
TCC = $(TCC) -FAcs
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# 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
|
||||||
|
RCC = $(RCC) -DSQLITE_OS_WINRT=1
|
||||||
|
TCC = $(TCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
|
||||||
|
RCC = $(RCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# C compiler options for the Windows 10 platform (needs MSVC 2015).
|
||||||
|
#
|
||||||
|
!IF $(FOR_WIN10)!=0
|
||||||
|
TCC = $(TCC) /guard:cf -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
|
||||||
|
BCC = $(BCC) /guard:cf -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
|
||||||
|
!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 || $(FOR_WIN10)!=0 || $(USE_CRT_DLL)!=0
|
||||||
|
!IF $(DEBUG)>1
|
||||||
|
TCC = $(TCC) -MDd
|
||||||
|
BCC = $(BCC) -MDd
|
||||||
|
!ELSE
|
||||||
|
TCC = $(TCC) -MD
|
||||||
|
BCC = $(BCC) -MD
|
||||||
|
!ENDIF
|
||||||
|
!ELSE
|
||||||
|
!IF $(DEBUG)>1
|
||||||
|
TCC = $(TCC) -MTd
|
||||||
|
BCC = $(BCC) -MTd
|
||||||
|
!ELSE
|
||||||
|
TCC = $(TCC) -MT
|
||||||
|
BCC = $(BCC) -MT
|
||||||
|
!ENDIF
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
# Define -DNDEBUG to compile without debugging (i.e., for production usage)
|
||||||
|
# Omitting the define will cause extra debugging code to be inserted and
|
||||||
|
# includes extra comments when "EXPLAIN stmt" is used.
|
||||||
|
#
|
||||||
|
!IF $(DEBUG)==0
|
||||||
|
TCC = $(TCC) -DNDEBUG
|
||||||
|
BCC = $(BCC) -DNDEBUG
|
||||||
|
RCC = $(RCC) -DNDEBUG
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
!IF $(DEBUG)>0 || $(API_ARMOR)!=0 || $(FOR_WIN10)!=0
|
||||||
|
TCC = $(TCC) -DSQLITE_ENABLE_API_ARMOR=1
|
||||||
|
RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR=1
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
!IF $(DEBUG)>2
|
||||||
|
TCC = $(TCC) -DSQLITE_DEBUG=1
|
||||||
|
RCC = $(RCC) -DSQLITE_DEBUG=1
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
!IF $(DEBUG)>4 || $(OSTRACE)!=0
|
||||||
|
TCC = $(TCC) -DSQLITE_FORCE_OS_TRACE=1 -DSQLITE_DEBUG_OS_TRACE=1
|
||||||
|
RCC = $(RCC) -DSQLITE_FORCE_OS_TRACE=1 -DSQLITE_DEBUG_OS_TRACE=1
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
!IF $(DEBUG)>5
|
||||||
|
TCC = $(TCC) -DSQLITE_ENABLE_IOTRACE=1
|
||||||
|
RCC = $(RCC) -DSQLITE_ENABLE_IOTRACE=1
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# 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
|
||||||
|
RCC = $(RCC) -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
|
||||||
|
RCC = $(RCC) -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS
|
||||||
|
|
||||||
|
# Use the SQLite debugging heap subsystem?
|
||||||
|
#
|
||||||
|
!IF $(MEMDEBUG)!=0
|
||||||
|
TCC = $(TCC) -DSQLITE_MEMDEBUG=1
|
||||||
|
RCC = $(RCC) -DSQLITE_MEMDEBUG=1
|
||||||
|
|
||||||
|
# Use native Win32 heap subsystem instead of malloc/free?
|
||||||
|
#
|
||||||
|
!ELSEIF $(WIN32HEAP)!=0
|
||||||
|
TCC = $(TCC) -DSQLITE_WIN32_MALLOC=1
|
||||||
|
RCC = $(RCC) -DSQLITE_WIN32_MALLOC=1
|
||||||
|
|
||||||
|
# Validate the heap on every call into the native Win32 heap subsystem?
|
||||||
|
#
|
||||||
|
!IF $(DEBUG)>3
|
||||||
|
TCC = $(TCC) -DSQLITE_WIN32_MALLOC_VALIDATE=1
|
||||||
|
RCC = $(RCC) -DSQLITE_WIN32_MALLOC_VALIDATE=1
|
||||||
|
!ENDIF
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
# Compiler options needed for programs that use the readline() library.
|
||||||
|
#
|
||||||
|
!IFNDEF READLINE_FLAGS
|
||||||
|
READLINE_FLAGS = -DHAVE_READLINE=0
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# The library that programs using readline() must link against.
|
||||||
|
#
|
||||||
|
!IFNDEF LIBREADLINE
|
||||||
|
LIBREADLINE =
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Should the database engine be compiled threadsafe
|
||||||
|
#
|
||||||
|
TCC = $(TCC) -DSQLITE_THREADSAFE=1
|
||||||
|
RCC = $(RCC) -DSQLITE_THREADSAFE=1
|
||||||
|
|
||||||
|
# Do threads override each others locks by default (1), or do we test (-1)
|
||||||
|
#
|
||||||
|
TCC = $(TCC) -DSQLITE_THREAD_OVERRIDE_LOCK=-1
|
||||||
|
RCC = $(RCC) -DSQLITE_THREAD_OVERRIDE_LOCK=-1
|
||||||
|
|
||||||
|
# Any target libraries which libsqlite must be linked against
|
||||||
|
#
|
||||||
|
!IFNDEF TLIBS
|
||||||
|
TLIBS =
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Flags controlling use of the in memory btree implementation
|
||||||
|
#
|
||||||
|
# SQLITE_TEMP_STORE is 0 to force temporary tables to be in a file, 1 to
|
||||||
|
# default to file, 2 to default to memory, and 3 to force temporary
|
||||||
|
# tables to always be in memory.
|
||||||
|
#
|
||||||
|
TCC = $(TCC) -DSQLITE_TEMP_STORE=1
|
||||||
|
RCC = $(RCC) -DSQLITE_TEMP_STORE=1
|
||||||
|
|
||||||
|
# Enable/disable loadable extensions, and other optional features
|
||||||
|
# based on configuration. (-DSQLITE_OMIT*, -DSQLITE_ENABLE*).
|
||||||
|
# The same set of OMIT and ENABLE flags should be passed to the
|
||||||
|
# LEMON parser generator and the mkkeywordhash tool as well.
|
||||||
|
|
||||||
|
# These are the required SQLite compilation options used when compiling for
|
||||||
|
# the Windows platform.
|
||||||
|
#
|
||||||
|
REQ_FEATURE_FLAGS = $(REQ_FEATURE_FLAGS) -DSQLITE_MAX_TRIGGER_DEPTH=100
|
||||||
|
|
||||||
|
# If we are linking to the RPCRT4 library, enable features that need it.
|
||||||
|
#
|
||||||
|
!IF $(USE_RPCRT4_LIB)!=0
|
||||||
|
REQ_FEATURE_FLAGS = $(REQ_FEATURE_FLAGS) -DSQLITE_WIN32_USE_UUID=1
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Add the required and optional SQLite compilation options into the command
|
||||||
|
# lines used to invoke the MSVC code and resource compilers.
|
||||||
|
#
|
||||||
|
TCC = $(TCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS)
|
||||||
|
RCC = $(RCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS)
|
||||||
|
|
||||||
|
# Add in any optional parameters specified on the commane line, e.g.
|
||||||
|
# nmake /f Makefile.msc all "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1"
|
||||||
|
#
|
||||||
|
TCC = $(TCC) $(OPTS)
|
||||||
|
RCC = $(RCC) $(OPTS)
|
||||||
|
|
||||||
|
# If compiling for debugging, add some defines.
|
||||||
|
#
|
||||||
|
!IF $(DEBUG)>1
|
||||||
|
TCC = $(TCC) -D_DEBUG
|
||||||
|
BCC = $(BCC) -D_DEBUG
|
||||||
|
RCC = $(RCC) -D_DEBUG
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# If optimizations are enabled or disabled (either implicitly or
|
||||||
|
# explicitly), add the necessary flags.
|
||||||
|
#
|
||||||
|
!IF $(DEBUG)>1 || $(OPTIMIZATIONS)==0
|
||||||
|
TCC = $(TCC) -Od
|
||||||
|
BCC = $(BCC) -Od
|
||||||
|
!ELSEIF $(OPTIMIZATIONS)>=3
|
||||||
|
TCC = $(TCC) -Ox
|
||||||
|
BCC = $(BCC) -Ox
|
||||||
|
!ELSEIF $(OPTIMIZATIONS)==2
|
||||||
|
TCC = $(TCC) -O2
|
||||||
|
BCC = $(BCC) -O2
|
||||||
|
!ELSEIF $(OPTIMIZATIONS)==1
|
||||||
|
TCC = $(TCC) -O1
|
||||||
|
BCC = $(BCC) -O1
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# If symbols are enabled (or compiling for debugging), enable PDBs.
|
||||||
|
#
|
||||||
|
!IF $(DEBUG)>1 || $(SYMBOLS)!=0
|
||||||
|
TCC = $(TCC) -Zi
|
||||||
|
BCC = $(BCC) -Zi
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
# Command line prefixes for compiling code, compiling resources,
|
||||||
|
# linking, etc.
|
||||||
|
#
|
||||||
|
LTCOMPILE = $(TCC) -Fo$@
|
||||||
|
LTRCOMPILE = $(RCC) -r
|
||||||
|
LTLIB = lib.exe
|
||||||
|
LTLINK = $(TCC) -Fe$@
|
||||||
|
|
||||||
|
# If requested, link to the RPCRT4 library.
|
||||||
|
#
|
||||||
|
!IF $(USE_RPCRT4_LIB)!=0
|
||||||
|
LTLINK = $(LTLINK) rpcrt4.lib
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# If a platform was set, force the linker to target that.
|
||||||
|
# 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.
|
||||||
|
!IFDEF PLATFORM
|
||||||
|
LTLINKOPTS = /NOLOGO /MACHINE:$(PLATFORM)
|
||||||
|
LTLIBOPTS = /NOLOGO /MACHINE:$(PLATFORM)
|
||||||
|
!ELSE
|
||||||
|
LTLINKOPTS = /NOLOGO
|
||||||
|
LTLIBOPTS = /NOLOGO
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# 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
|
||||||
|
!IF "$(VISUALSTUDIOVERSION)"=="12.0" || "$(VISUALSTUDIOVERSION)"=="14.0"
|
||||||
|
!IFNDEF STORELIBPATH
|
||||||
|
!IF "$(PLATFORM)"=="x86"
|
||||||
|
STORELIBPATH = $(CRTLIBPATH)\store
|
||||||
|
!ELSEIF "$(PLATFORM)"=="x64"
|
||||||
|
STORELIBPATH = $(CRTLIBPATH)\store\amd64
|
||||||
|
!ELSEIF "$(PLATFORM)"=="ARM"
|
||||||
|
STORELIBPATH = $(CRTLIBPATH)\store\arm
|
||||||
|
!ELSE
|
||||||
|
STORELIBPATH = $(CRTLIBPATH)\store
|
||||||
|
!ENDIF
|
||||||
|
!ENDIF
|
||||||
|
STORELIBPATH = $(STORELIBPATH:\\=\)
|
||||||
|
LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(STORELIBPATH)"
|
||||||
|
!ENDIF
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# When compiling for Windows Phone 8.1, an extra library path is
|
||||||
|
# required.
|
||||||
|
#
|
||||||
|
!IF $(USE_WP81_OPTS)!=0
|
||||||
|
!IFNDEF WP81LIBPATH
|
||||||
|
!IF "$(PLATFORM)"=="x86"
|
||||||
|
WP81LIBPATH = $(PROGRAMFILES_X86)\Windows Phone Kits\8.1\lib\x86
|
||||||
|
!ELSEIF "$(PLATFORM)"=="ARM"
|
||||||
|
WP81LIBPATH = $(PROGRAMFILES_X86)\Windows Phone Kits\8.1\lib\ARM
|
||||||
|
!ELSE
|
||||||
|
WP81LIBPATH = $(PROGRAMFILES_X86)\Windows Phone Kits\8.1\lib\x86
|
||||||
|
!ENDIF
|
||||||
|
!ENDIF
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# When compiling for Windows Phone 8.1, some extra linker options
|
||||||
|
# are also required.
|
||||||
|
#
|
||||||
|
!IF $(USE_WP81_OPTS)!=0
|
||||||
|
!IFDEF WP81LIBPATH
|
||||||
|
LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(WP81LIBPATH)"
|
||||||
|
!ENDIF
|
||||||
|
LTLINKOPTS = $(LTLINKOPTS) /DYNAMICBASE
|
||||||
|
LTLINKOPTS = $(LTLINKOPTS) WindowsPhoneCore.lib RuntimeObject.lib PhoneAppModelHost.lib
|
||||||
|
LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:kernel32.lib /NODEFAULTLIB:ole32.lib
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# When compiling for UAP, some extra linker options are also required.
|
||||||
|
#
|
||||||
|
!IF $(FOR_UAP)!=0
|
||||||
|
LTLINKOPTS = $(LTLINKOPTS) /DYNAMICBASE /NODEFAULTLIB:kernel32.lib
|
||||||
|
LTLINKOPTS = $(LTLINKOPTS) mincore.lib
|
||||||
|
!IFDEF PSDKLIBPATH
|
||||||
|
LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(PSDKLIBPATH)"
|
||||||
|
!ENDIF
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# If either debugging or symbols are enabled, enable PDBs.
|
||||||
|
#
|
||||||
|
!IF $(DEBUG)>1 || $(SYMBOLS)!=0
|
||||||
|
LDFLAGS = /DEBUG $(LDOPTS)
|
||||||
|
!ELSE
|
||||||
|
LDFLAGS = $(LDOPTS)
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
# You should not have to change anything below this line
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
# Object files for the amalgamation.
|
||||||
|
#
|
||||||
|
LIBOBJS1 = sqlite3.lo
|
||||||
|
|
||||||
|
# Determine the real value of LIBOBJ based on the 'configure' script
|
||||||
|
#
|
||||||
|
LIBOBJ = $(LIBOBJS1)
|
||||||
|
|
||||||
|
# Determine if embedded resource compilation and usage are enabled.
|
||||||
|
#
|
||||||
|
!IF $(USE_RC)!=0
|
||||||
|
LIBRESOBJS = sqlite3res.lo
|
||||||
|
!ELSE
|
||||||
|
LIBRESOBJS =
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
# Additional compiler options for the shell. These are only effective
|
||||||
|
# when the shell is not being dynamically linked.
|
||||||
|
#
|
||||||
|
!IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
|
||||||
|
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
# This is the default Makefile target. The objects listed here
|
||||||
|
# are what get build when you type just "make" with no arguments.
|
||||||
|
#
|
||||||
|
all: dll libsqlite3.lib shell
|
||||||
|
|
||||||
|
# Dynamic link library section.
|
||||||
|
#
|
||||||
|
dll: $(SQLITE3DLL)
|
||||||
|
|
||||||
|
# Shell executable.
|
||||||
|
#
|
||||||
|
shell: $(SQLITE3EXE)
|
||||||
|
|
||||||
|
libsqlite3.lib: $(LIBOBJ)
|
||||||
|
$(LTLIB) $(LTLIBOPTS) /OUT:$@ $(LIBOBJ) $(TLIBS)
|
||||||
|
|
||||||
|
|
||||||
|
$(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
|
||||||
|
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
||||||
|
|
||||||
|
|
||||||
|
$(SQLITE3EXE): $(TOP)\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H)
|
||||||
|
$(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\shell.c $(SHELL_CORE_SRC) \
|
||||||
|
/link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
|
||||||
|
|
||||||
|
|
||||||
|
# Rule to build the amalgamation
|
||||||
|
#
|
||||||
|
sqlite3.lo: $(SQLITE3C)
|
||||||
|
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(SQLITE3C)
|
||||||
|
|
||||||
|
|
||||||
|
# Rule to build the Win32 resources object file.
|
||||||
|
#
|
||||||
|
!IF $(USE_RC)!=0
|
||||||
|
_HASHCHAR=^#
|
||||||
|
!IF ![echo !IFNDEF VERSION > rcver.vc] && \
|
||||||
|
![for /F "delims=" %V in ('type "$(SQLITE3H)" ^| find "$(_HASHCHAR)define SQLITE_VERSION "') do (echo VERSION = ^^%V >> rcver.vc)] && \
|
||||||
|
![echo !ENDIF >> rcver.vc]
|
||||||
|
!INCLUDE rcver.vc
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
RESOURCE_VERSION = $(VERSION:^#=)
|
||||||
|
RESOURCE_VERSION = $(RESOURCE_VERSION:define=)
|
||||||
|
RESOURCE_VERSION = $(RESOURCE_VERSION:SQLITE_VERSION=)
|
||||||
|
RESOURCE_VERSION = $(RESOURCE_VERSION:"=)
|
||||||
|
RESOURCE_VERSION = $(RESOURCE_VERSION:.=,)
|
||||||
|
|
||||||
|
$(LIBRESOBJS): $(TOP)\sqlite3.rc rcver.vc $(SQLITE3H)
|
||||||
|
echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h
|
||||||
|
echo #define SQLITE_RESOURCE_VERSION $(RESOURCE_VERSION) >> sqlite3rc.h
|
||||||
|
echo #endif >> sqlite3rc.h
|
||||||
|
$(LTRCOMPILE) -fo $(LIBRESOBJS) -DRC_VERONLY $(TOP)\sqlite3.rc
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL
|
||||||
|
del /Q *.bsc *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL
|
@ -1,32 +0,0 @@
|
|||||||
|
|
||||||
This package contains:
|
|
||||||
|
|
||||||
* the SQLite library amalgamation (single file) source code distribution,
|
|
||||||
* the shell.c file used to build the sqlite3 shell too, and
|
|
||||||
* the sqlite3.h and sqlite3ext.h header files required to link programs
|
|
||||||
and sqlite extensions against the installed libary.
|
|
||||||
* autoconf/automake installation infrastucture.
|
|
||||||
|
|
||||||
The generic installation instructions for autoconf/automake are found
|
|
||||||
in the INSTALL file.
|
|
||||||
|
|
||||||
The following SQLite specific boolean options are supported:
|
|
||||||
|
|
||||||
--enable-readline use readline in shell tool [default=yes]
|
|
||||||
--enable-threadsafe build a thread-safe library [default=yes]
|
|
||||||
--enable-dynamic-extensions support loadable extensions [default=yes]
|
|
||||||
|
|
||||||
The default value for the CFLAGS variable (options passed to the C
|
|
||||||
compiler) includes debugging symbols in the build, resulting in larger
|
|
||||||
binaries than are necessary. Override it on the configure command
|
|
||||||
line like this:
|
|
||||||
|
|
||||||
$ CFLAGS="-Os" ./configure
|
|
||||||
|
|
||||||
to produce a smaller installation footprint.
|
|
||||||
|
|
||||||
Other SQLite compilation parameters can also be set using CFLAGS. For
|
|
||||||
example:
|
|
||||||
|
|
||||||
$ CFLAGS="-Os -DSQLITE_OMIT_TRIGGERS" ./configure
|
|
||||||
|
|
113
autoconf/README.txt
Normal file
113
autoconf/README.txt
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
This package contains:
|
||||||
|
|
||||||
|
* the SQLite library amalgamation (single file) source code distribution,
|
||||||
|
* the shell.c file used to build the sqlite3 shell too, and
|
||||||
|
* the sqlite3.h and sqlite3ext.h header files required to link programs
|
||||||
|
and sqlite extensions against the installed libary.
|
||||||
|
* autoconf/automake installation infrastucture for building on POSIX
|
||||||
|
compliant systems.
|
||||||
|
* a Makefile.msc and sqlite3.rc for building with Microsoft Visual C++ on
|
||||||
|
Windows.
|
||||||
|
|
||||||
|
SUMMARY OF HOW TO BUILD
|
||||||
|
=======================
|
||||||
|
|
||||||
|
Unix: ./configure; make
|
||||||
|
Windows: nmake /f Makefile.msc
|
||||||
|
|
||||||
|
BUILDING ON POSIX
|
||||||
|
=================
|
||||||
|
|
||||||
|
The generic installation instructions for autoconf/automake are found
|
||||||
|
in the INSTALL file.
|
||||||
|
|
||||||
|
The following SQLite specific boolean options are supported:
|
||||||
|
|
||||||
|
--enable-readline use readline in shell tool [default=yes]
|
||||||
|
--enable-threadsafe build a thread-safe library [default=yes]
|
||||||
|
--enable-dynamic-extensions support loadable extensions [default=yes]
|
||||||
|
|
||||||
|
The default value for the CFLAGS variable (options passed to the C
|
||||||
|
compiler) includes debugging symbols in the build, resulting in larger
|
||||||
|
binaries than are necessary. Override it on the configure command
|
||||||
|
line like this:
|
||||||
|
|
||||||
|
$ CFLAGS="-Os" ./configure
|
||||||
|
|
||||||
|
to produce a smaller installation footprint.
|
||||||
|
|
||||||
|
Other SQLite compilation parameters can also be set using CFLAGS. For
|
||||||
|
example:
|
||||||
|
|
||||||
|
$ CFLAGS="-Os -DSQLITE_OMIT_TRIGGERS" ./configure
|
||||||
|
|
||||||
|
|
||||||
|
BUILDING WITH MICROSOFT VISUAL C++
|
||||||
|
==================================
|
||||||
|
|
||||||
|
To compile for Windows using Microsoft Visual C++:
|
||||||
|
|
||||||
|
$ nmake /f Makefile.msc
|
||||||
|
|
||||||
|
Using Microsoft Visual C++ 2005 (or later) is recommended. Several Windows
|
||||||
|
platform variants may be built by adding additional macros to the NMAKE
|
||||||
|
command line.
|
||||||
|
|
||||||
|
Building for WinRT 8.0
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
FOR_WINRT=1
|
||||||
|
|
||||||
|
Using Microsoft Visual C++ 2012 (or later) is required. When using the
|
||||||
|
above, something like the following macro will need to be added to the
|
||||||
|
NMAKE command line as well:
|
||||||
|
|
||||||
|
"NSDKLIBPATH=%WindowsSdkDir%\..\8.0\lib\win8\um\x86"
|
||||||
|
|
||||||
|
Building for WinRT 8.1
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
FOR_WINRT=1
|
||||||
|
|
||||||
|
Using Microsoft Visual C++ 2013 (or later) is required. When using the
|
||||||
|
above, something like the following macro will need to be added to the
|
||||||
|
NMAKE command line as well:
|
||||||
|
|
||||||
|
"NSDKLIBPATH=%WindowsSdkDir%\..\8.1\lib\winv6.3\um\x86"
|
||||||
|
|
||||||
|
Building for UAP 10.0
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
FOR_WINRT=1 FOR_UAP=1
|
||||||
|
|
||||||
|
Using Microsoft Visual C++ 2015 (or later) is required. When using the
|
||||||
|
above, something like the following macros will need to be added to the
|
||||||
|
NMAKE command line as well:
|
||||||
|
|
||||||
|
"NSDKLIBPATH=%WindowsSdkDir%\..\10\lib\10.0.10586.0\um\x86"
|
||||||
|
"PSDKLIBPATH=%WindowsSdkDir%\..\10\lib\10.0.10586.0\um\x86"
|
||||||
|
"NUCRTLIBPATH=%UniversalCRTSdkDir%\..\10\lib\10.0.10586.0\ucrt\x86"
|
||||||
|
|
||||||
|
Building for the Windows 10 SDK
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
FOR_WIN10=1
|
||||||
|
|
||||||
|
Using Microsoft Visual C++ 2015 (or later) is required. When using the
|
||||||
|
above, no other macros should be needed on the NMAKE command line.
|
||||||
|
|
||||||
|
Other preprocessor defines
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
Additionally, preprocessor defines may be specified by using the OPTS macro
|
||||||
|
on the NMAKE command line. However, not all possible preprocessor defines
|
||||||
|
may be specified in this manner as some require the amalgamation to be built
|
||||||
|
with them enabled (see http://www.sqlite.org/compile.html). For example, the
|
||||||
|
following will work:
|
||||||
|
|
||||||
|
"OPTS=-DSQLITE_ENABLE_STAT4=1 -DSQLITE_ENABLE_JSON1=1"
|
||||||
|
|
||||||
|
However, the following will not compile unless the amalgamation was built
|
||||||
|
with it enabled:
|
||||||
|
|
||||||
|
"OPTS=-DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1"
|
@ -29,7 +29,7 @@ typedef unsigned short u16;
|
|||||||
typedef sqlite3_int64 i64;
|
typedef sqlite3_int64 i64;
|
||||||
typedef sqlite3_uint64 u64;
|
typedef sqlite3_uint64 u64;
|
||||||
|
|
||||||
#define ArraySize(x) (sizeof(x) / sizeof(x[0]))
|
#define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0])))
|
||||||
|
|
||||||
#define testcase(x)
|
#define testcase(x)
|
||||||
#define ALWAYS(x) 1
|
#define ALWAYS(x) 1
|
||||||
@ -225,8 +225,8 @@ int sqlite3Fts5ConfigParseRank(const char*, char**, char**);
|
|||||||
typedef struct Fts5Buffer Fts5Buffer;
|
typedef struct Fts5Buffer Fts5Buffer;
|
||||||
struct Fts5Buffer {
|
struct Fts5Buffer {
|
||||||
u8 *p;
|
u8 *p;
|
||||||
u32 n;
|
int n;
|
||||||
u32 nSpace;
|
int nSpace;
|
||||||
};
|
};
|
||||||
|
|
||||||
int sqlite3Fts5BufferSize(int*, Fts5Buffer*, u32);
|
int sqlite3Fts5BufferSize(int*, Fts5Buffer*, u32);
|
||||||
@ -247,7 +247,7 @@ char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...);
|
|||||||
#define fts5BufferSet(a,b,c,d) sqlite3Fts5BufferSet(a,b,c,d)
|
#define fts5BufferSet(a,b,c,d) sqlite3Fts5BufferSet(a,b,c,d)
|
||||||
|
|
||||||
#define fts5BufferGrow(pRc,pBuf,nn) ( \
|
#define fts5BufferGrow(pRc,pBuf,nn) ( \
|
||||||
(pBuf)->n + (nn) <= (pBuf)->nSpace ? 0 : \
|
(u32)((pBuf)->n) + (u32)(nn) <= (u32)((pBuf)->nSpace) ? 0 : \
|
||||||
sqlite3Fts5BufferSize((pRc),(pBuf),(nn)+(pBuf)->n) \
|
sqlite3Fts5BufferSize((pRc),(pBuf),(nn)+(pBuf)->n) \
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -315,6 +315,12 @@ void sqlite3Fts5TermsetFree(Fts5Termset*);
|
|||||||
typedef struct Fts5Index Fts5Index;
|
typedef struct Fts5Index Fts5Index;
|
||||||
typedef struct Fts5IndexIter Fts5IndexIter;
|
typedef struct Fts5IndexIter Fts5IndexIter;
|
||||||
|
|
||||||
|
struct Fts5IndexIter {
|
||||||
|
i64 iRowid;
|
||||||
|
const u8 *pData;
|
||||||
|
int nData;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Values used as part of the flags argument passed to IndexQuery().
|
** Values used as part of the flags argument passed to IndexQuery().
|
||||||
*/
|
*/
|
||||||
@ -382,8 +388,6 @@ int sqlite3Fts5IterEof(Fts5IndexIter*);
|
|||||||
int sqlite3Fts5IterNext(Fts5IndexIter*);
|
int sqlite3Fts5IterNext(Fts5IndexIter*);
|
||||||
int sqlite3Fts5IterNextFrom(Fts5IndexIter*, i64 iMatch);
|
int sqlite3Fts5IterNextFrom(Fts5IndexIter*, i64 iMatch);
|
||||||
i64 sqlite3Fts5IterRowid(Fts5IndexIter*);
|
i64 sqlite3Fts5IterRowid(Fts5IndexIter*);
|
||||||
int sqlite3Fts5IterPoslist(Fts5IndexIter*,Fts5Colset*, const u8**, int*, i64*);
|
|
||||||
int sqlite3Fts5IterPoslistBuffer(Fts5IndexIter *pIter, Fts5Buffer *pBuf);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Close an iterator opened by sqlite3Fts5IndexQuery().
|
** Close an iterator opened by sqlite3Fts5IndexQuery().
|
||||||
@ -469,8 +473,6 @@ int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge);
|
|||||||
|
|
||||||
int sqlite3Fts5IndexLoadConfig(Fts5Index *p);
|
int sqlite3Fts5IndexLoadConfig(Fts5Index *p);
|
||||||
|
|
||||||
int sqlite3Fts5IterCollist(Fts5IndexIter*, const u8 **, int*);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** End of interface to code in fts5_index.c.
|
** End of interface to code in fts5_index.c.
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
@ -544,7 +544,7 @@ int sqlite3Fts5AuxInit(fts5_api *pApi){
|
|||||||
int rc = SQLITE_OK; /* Return code */
|
int rc = SQLITE_OK; /* Return code */
|
||||||
int i; /* To iterate through builtin functions */
|
int i; /* To iterate through builtin functions */
|
||||||
|
|
||||||
for(i=0; rc==SQLITE_OK && i<(int)ArraySize(aBuiltin); i++){
|
for(i=0; rc==SQLITE_OK && i<ArraySize(aBuiltin); i++){
|
||||||
rc = pApi->xCreateFunction(pApi,
|
rc = pApi->xCreateFunction(pApi,
|
||||||
aBuiltin[i].zFunc,
|
aBuiltin[i].zFunc,
|
||||||
aBuiltin[i].pUserData,
|
aBuiltin[i].pUserData,
|
||||||
|
@ -322,7 +322,7 @@ int sqlite3Fts5TermsetAdd(
|
|||||||
*pbPresent = 0;
|
*pbPresent = 0;
|
||||||
if( p ){
|
if( p ){
|
||||||
int i;
|
int i;
|
||||||
int hash = 13;
|
u32 hash = 13;
|
||||||
Fts5TermsetEntry *pEntry;
|
Fts5TermsetEntry *pEntry;
|
||||||
|
|
||||||
/* Calculate a hash value for this term. This is the same hash checksum
|
/* Calculate a hash value for this term. This is the same hash checksum
|
||||||
@ -339,7 +339,7 @@ int sqlite3Fts5TermsetAdd(
|
|||||||
if( pEntry->iIdx==iIdx
|
if( pEntry->iIdx==iIdx
|
||||||
&& pEntry->nTerm==nTerm
|
&& pEntry->nTerm==nTerm
|
||||||
&& memcmp(pEntry->pTerm, pTerm, nTerm)==0
|
&& memcmp(pEntry->pTerm, pTerm, nTerm)==0
|
||||||
){
|
){
|
||||||
*pbPresent = 1;
|
*pbPresent = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -363,7 +363,7 @@ int sqlite3Fts5TermsetAdd(
|
|||||||
|
|
||||||
void sqlite3Fts5TermsetFree(Fts5Termset *p){
|
void sqlite3Fts5TermsetFree(Fts5Termset *p){
|
||||||
if( p ){
|
if( p ){
|
||||||
int i;
|
u32 i;
|
||||||
for(i=0; i<ArraySize(p->apHash); i++){
|
for(i=0; i<ArraySize(p->apHash); i++){
|
||||||
Fts5TermsetEntry *pEntry = p->apHash[i];
|
Fts5TermsetEntry *pEntry = p->apHash[i];
|
||||||
while( pEntry ){
|
while( pEntry ){
|
||||||
|
@ -306,7 +306,7 @@ static int fts5ExprSynonymList(
|
|||||||
int bCollist,
|
int bCollist,
|
||||||
Fts5Colset *pColset,
|
Fts5Colset *pColset,
|
||||||
i64 iRowid,
|
i64 iRowid,
|
||||||
int *pbDel, /* OUT: Caller should sqlite3_free(*pa) */
|
Fts5Buffer *pBuf, /* Use this buffer for space if required */
|
||||||
u8 **pa, int *pn
|
u8 **pa, int *pn
|
||||||
){
|
){
|
||||||
Fts5PoslistReader aStatic[4];
|
Fts5PoslistReader aStatic[4];
|
||||||
@ -320,18 +320,7 @@ static int fts5ExprSynonymList(
|
|||||||
for(p=pTerm; p; p=p->pSynonym){
|
for(p=pTerm; p; p=p->pSynonym){
|
||||||
Fts5IndexIter *pIter = p->pIter;
|
Fts5IndexIter *pIter = p->pIter;
|
||||||
if( sqlite3Fts5IterEof(pIter)==0 && sqlite3Fts5IterRowid(pIter)==iRowid ){
|
if( sqlite3Fts5IterEof(pIter)==0 && sqlite3Fts5IterRowid(pIter)==iRowid ){
|
||||||
const u8 *a;
|
if( pIter->nData==0 ) continue;
|
||||||
int n;
|
|
||||||
|
|
||||||
if( bCollist ){
|
|
||||||
rc = sqlite3Fts5IterCollist(pIter, &a, &n);
|
|
||||||
}else{
|
|
||||||
i64 dummy;
|
|
||||||
rc = sqlite3Fts5IterPoslist(pIter, pColset, &a, &n, &dummy);
|
|
||||||
}
|
|
||||||
|
|
||||||
if( rc!=SQLITE_OK ) goto synonym_poslist_out;
|
|
||||||
if( n==0 ) continue;
|
|
||||||
if( nIter==nAlloc ){
|
if( nIter==nAlloc ){
|
||||||
int nByte = sizeof(Fts5PoslistReader) * nAlloc * 2;
|
int nByte = sizeof(Fts5PoslistReader) * nAlloc * 2;
|
||||||
Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc(nByte);
|
Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc(nByte);
|
||||||
@ -344,20 +333,19 @@ static int fts5ExprSynonymList(
|
|||||||
if( aIter!=aStatic ) sqlite3_free(aIter);
|
if( aIter!=aStatic ) sqlite3_free(aIter);
|
||||||
aIter = aNew;
|
aIter = aNew;
|
||||||
}
|
}
|
||||||
sqlite3Fts5PoslistReaderInit(a, n, &aIter[nIter]);
|
sqlite3Fts5PoslistReaderInit(pIter->pData, pIter->nData, &aIter[nIter]);
|
||||||
assert( aIter[nIter].bEof==0 );
|
assert( aIter[nIter].bEof==0 );
|
||||||
nIter++;
|
nIter++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert( *pbDel==0 );
|
|
||||||
if( nIter==1 ){
|
if( nIter==1 ){
|
||||||
*pa = (u8*)aIter[0].a;
|
*pa = (u8*)aIter[0].a;
|
||||||
*pn = aIter[0].n;
|
*pn = aIter[0].n;
|
||||||
}else{
|
}else{
|
||||||
Fts5PoslistWriter writer = {0};
|
Fts5PoslistWriter writer = {0};
|
||||||
Fts5Buffer buf = {0,0,0};
|
|
||||||
i64 iPrev = -1;
|
i64 iPrev = -1;
|
||||||
|
fts5BufferZero(pBuf);
|
||||||
while( 1 ){
|
while( 1 ){
|
||||||
int i;
|
int i;
|
||||||
i64 iMin = FTS5_LARGEST_INT64;
|
i64 iMin = FTS5_LARGEST_INT64;
|
||||||
@ -372,15 +360,12 @@ static int fts5ExprSynonymList(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( iMin==FTS5_LARGEST_INT64 || rc!=SQLITE_OK ) break;
|
if( iMin==FTS5_LARGEST_INT64 || rc!=SQLITE_OK ) break;
|
||||||
rc = sqlite3Fts5PoslistWriterAppend(&buf, &writer, iMin);
|
rc = sqlite3Fts5PoslistWriterAppend(pBuf, &writer, iMin);
|
||||||
iPrev = iMin;
|
iPrev = iMin;
|
||||||
}
|
}
|
||||||
if( rc ){
|
if( rc==SQLITE_OK ){
|
||||||
sqlite3_free(buf.p);
|
*pa = pBuf->p;
|
||||||
}else{
|
*pn = pBuf->n;
|
||||||
*pa = buf.p;
|
|
||||||
*pn = buf.n;
|
|
||||||
*pbDel = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -417,7 +402,7 @@ static int fts5ExprPhraseIsMatch(
|
|||||||
|
|
||||||
/* If the aStatic[] array is not large enough, allocate a large array
|
/* If the aStatic[] array is not large enough, allocate a large array
|
||||||
** using sqlite3_malloc(). This approach could be improved upon. */
|
** using sqlite3_malloc(). This approach could be improved upon. */
|
||||||
if( pPhrase->nTerm>(int)ArraySize(aStatic) ){
|
if( pPhrase->nTerm>ArraySize(aStatic) ){
|
||||||
int nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm;
|
int nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm;
|
||||||
aIter = (Fts5PoslistReader*)sqlite3_malloc(nByte);
|
aIter = (Fts5PoslistReader*)sqlite3_malloc(nByte);
|
||||||
if( !aIter ) return SQLITE_NOMEM;
|
if( !aIter ) return SQLITE_NOMEM;
|
||||||
@ -427,18 +412,23 @@ static int fts5ExprPhraseIsMatch(
|
|||||||
/* Initialize a term iterator for each term in the phrase */
|
/* Initialize a term iterator for each term in the phrase */
|
||||||
for(i=0; i<pPhrase->nTerm; i++){
|
for(i=0; i<pPhrase->nTerm; i++){
|
||||||
Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
|
Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
|
||||||
i64 dummy;
|
|
||||||
int n = 0;
|
int n = 0;
|
||||||
int bFlag = 0;
|
int bFlag = 0;
|
||||||
const u8 *a = 0;
|
u8 *a = 0;
|
||||||
if( pTerm->pSynonym ){
|
if( pTerm->pSynonym ){
|
||||||
|
Fts5Buffer buf = {0, 0, 0};
|
||||||
rc = fts5ExprSynonymList(
|
rc = fts5ExprSynonymList(
|
||||||
pTerm, 0, pColset, pNode->iRowid, &bFlag, (u8**)&a, &n
|
pTerm, 0, pColset, pNode->iRowid, &buf, &a, &n
|
||||||
);
|
);
|
||||||
|
if( rc ){
|
||||||
|
sqlite3_free(a);
|
||||||
|
goto ismatch_out;
|
||||||
|
}
|
||||||
|
if( a==buf.p ) bFlag = 1;
|
||||||
}else{
|
}else{
|
||||||
rc = sqlite3Fts5IterPoslist(pTerm->pIter, pColset, &a, &n, &dummy);
|
a = (u8*)pTerm->pIter->pData;
|
||||||
|
n = pTerm->pIter->nData;
|
||||||
}
|
}
|
||||||
if( rc!=SQLITE_OK ) goto ismatch_out;
|
|
||||||
sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
|
sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
|
||||||
aIter[i].bFlag = (u8)bFlag;
|
aIter[i].bFlag = (u8)bFlag;
|
||||||
if( aIter[i].bEof ) goto ismatch_out;
|
if( aIter[i].bEof ) goto ismatch_out;
|
||||||
@ -553,7 +543,7 @@ static int fts5ExprNearIsMatch(int *pRc, Fts5ExprNearset *pNear){
|
|||||||
|
|
||||||
/* If the aStatic[] array is not large enough, allocate a large array
|
/* If the aStatic[] array is not large enough, allocate a large array
|
||||||
** using sqlite3_malloc(). This approach could be improved upon. */
|
** using sqlite3_malloc(). This approach could be improved upon. */
|
||||||
if( pNear->nPhrase>(int)ArraySize(aStatic) ){
|
if( pNear->nPhrase>ArraySize(aStatic) ){
|
||||||
int nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase;
|
int nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase;
|
||||||
a = (Fts5NearTrimmer*)sqlite3Fts5MallocZero(&rc, nByte);
|
a = (Fts5NearTrimmer*)sqlite3Fts5MallocZero(&rc, nByte);
|
||||||
}else{
|
}else{
|
||||||
@ -775,6 +765,7 @@ static int fts5ExprNearTest(
|
|||||||
for(pTerm=&pPhrase->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){
|
for(pTerm=&pPhrase->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){
|
||||||
Fts5IndexIter *pIter = pTerm->pIter;
|
Fts5IndexIter *pIter = pTerm->pIter;
|
||||||
if( sqlite3Fts5IterEof(pIter)==0 ){
|
if( sqlite3Fts5IterEof(pIter)==0 ){
|
||||||
|
#if 0
|
||||||
int n;
|
int n;
|
||||||
i64 iRowid;
|
i64 iRowid;
|
||||||
rc = sqlite3Fts5IterPoslist(pIter, pNear->pColset, 0, &n, &iRowid);
|
rc = sqlite3Fts5IterPoslist(pIter, pNear->pColset, 0, &n, &iRowid);
|
||||||
@ -784,6 +775,10 @@ static int fts5ExprNearTest(
|
|||||||
}else if( iRowid==pNode->iRowid && n>0 ){
|
}else if( iRowid==pNode->iRowid && n>0 ){
|
||||||
pPhrase->poslist.n = 1;
|
pPhrase->poslist.n = 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
if( pIter->iRowid==pNode->iRowid && pIter->nData>0 ){
|
||||||
|
pPhrase->poslist.n = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pPhrase->poslist.n;
|
return pPhrase->poslist.n;
|
||||||
@ -800,9 +795,13 @@ static int fts5ExprNearTest(
|
|||||||
rc = fts5ExprPhraseIsMatch(pNode, pNear->pColset, pPhrase, &bMatch);
|
rc = fts5ExprPhraseIsMatch(pNode, pNear->pColset, pPhrase, &bMatch);
|
||||||
if( bMatch==0 ) break;
|
if( bMatch==0 ) break;
|
||||||
}else{
|
}else{
|
||||||
|
Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
|
||||||
|
fts5BufferSet(&rc, &pPhrase->poslist, pIter->nData, pIter->pData);
|
||||||
|
#if 0
|
||||||
rc = sqlite3Fts5IterPoslistBuffer(
|
rc = sqlite3Fts5IterPoslistBuffer(
|
||||||
pPhrase->aTerm[0].pIter, &pPhrase->poslist
|
pPhrase->aTerm[0].pIter, &pPhrase->poslist
|
||||||
);
|
);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -823,21 +822,20 @@ static int fts5ExprTokenTest(
|
|||||||
** fts5_index.c iterator object. This is much faster than synthesizing
|
** fts5_index.c iterator object. This is much faster than synthesizing
|
||||||
** a new poslist the way we have to for more complicated phrase or NEAR
|
** a new poslist the way we have to for more complicated phrase or NEAR
|
||||||
** expressions. */
|
** expressions. */
|
||||||
Fts5ExprNearset *pNear = pNode->pNear;
|
Fts5ExprPhrase *pPhrase = pNode->pNear->apPhrase[0];
|
||||||
Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
|
|
||||||
Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
|
Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
|
||||||
Fts5Colset *pColset = pNear->pColset;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
assert( pNode->eType==FTS5_TERM );
|
assert( pNode->eType==FTS5_TERM );
|
||||||
assert( pNear->nPhrase==1 && pPhrase->nTerm==1 );
|
assert( pNode->pNear->nPhrase==1 && pPhrase->nTerm==1 );
|
||||||
assert( pPhrase->aTerm[0].pSynonym==0 );
|
assert( pPhrase->aTerm[0].pSynonym==0 );
|
||||||
|
|
||||||
rc = sqlite3Fts5IterPoslist(pIter, pColset,
|
pPhrase->poslist.n = pIter->nData;
|
||||||
(const u8**)&pPhrase->poslist.p, (int*)&pPhrase->poslist.n, &pNode->iRowid
|
if( pExpr->pConfig->eDetail==FTS5_DETAIL_FULL ){
|
||||||
);
|
pPhrase->poslist.p = (u8*)pIter->pData;
|
||||||
|
}
|
||||||
|
pNode->iRowid = pIter->iRowid;
|
||||||
pNode->bNomatch = (pPhrase->poslist.n==0);
|
pNode->bNomatch = (pPhrase->poslist.n==0);
|
||||||
return rc;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1370,10 +1368,10 @@ static void fts5ExprPhraseFree(Fts5ExprPhrase *pPhrase){
|
|||||||
Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
|
Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
|
||||||
sqlite3_free(pTerm->zTerm);
|
sqlite3_free(pTerm->zTerm);
|
||||||
sqlite3Fts5IterClose(pTerm->pIter);
|
sqlite3Fts5IterClose(pTerm->pIter);
|
||||||
|
|
||||||
for(pSyn=pTerm->pSynonym; pSyn; pSyn=pNext){
|
for(pSyn=pTerm->pSynonym; pSyn; pSyn=pNext){
|
||||||
pNext = pSyn->pSynonym;
|
pNext = pSyn->pSynonym;
|
||||||
sqlite3Fts5IterClose(pSyn->pIter);
|
sqlite3Fts5IterClose(pSyn->pIter);
|
||||||
|
fts5BufferFree((Fts5Buffer*)&pSyn[1]);
|
||||||
sqlite3_free(pSyn);
|
sqlite3_free(pSyn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1461,13 +1459,13 @@ static int fts5ParseTokenize(
|
|||||||
assert( pPhrase==0 || pPhrase->nTerm>0 );
|
assert( pPhrase==0 || pPhrase->nTerm>0 );
|
||||||
if( pPhrase && (tflags & FTS5_TOKEN_COLOCATED) ){
|
if( pPhrase && (tflags & FTS5_TOKEN_COLOCATED) ){
|
||||||
Fts5ExprTerm *pSyn;
|
Fts5ExprTerm *pSyn;
|
||||||
int nByte = sizeof(Fts5ExprTerm) + nToken+1;
|
int nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1;
|
||||||
pSyn = (Fts5ExprTerm*)sqlite3_malloc(nByte);
|
pSyn = (Fts5ExprTerm*)sqlite3_malloc(nByte);
|
||||||
if( pSyn==0 ){
|
if( pSyn==0 ){
|
||||||
rc = SQLITE_NOMEM;
|
rc = SQLITE_NOMEM;
|
||||||
}else{
|
}else{
|
||||||
memset(pSyn, 0, nByte);
|
memset(pSyn, 0, nByte);
|
||||||
pSyn->zTerm = (char*)&pSyn[1];
|
pSyn->zTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer);
|
||||||
memcpy(pSyn->zTerm, pToken, nToken);
|
memcpy(pSyn->zTerm, pToken, nToken);
|
||||||
pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym;
|
pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym;
|
||||||
pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn;
|
pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn;
|
||||||
@ -2246,7 +2244,7 @@ int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){
|
|||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
void *pCtx = (void*)pGlobal;
|
void *pCtx = (void*)pGlobal;
|
||||||
|
|
||||||
for(i=0; rc==SQLITE_OK && i<(int)ArraySize(aFunc); i++){
|
for(i=0; rc==SQLITE_OK && i<ArraySize(aFunc); i++){
|
||||||
struct Fts5ExprFunc *p = &aFunc[i];
|
struct Fts5ExprFunc *p = &aFunc[i];
|
||||||
rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0);
|
rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0);
|
||||||
}
|
}
|
||||||
@ -2484,26 +2482,21 @@ int sqlite3Fts5ExprPhraseCollist(
|
|||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
|
|
||||||
assert( iPhrase>=0 && iPhrase<pExpr->nPhrase );
|
assert( iPhrase>=0 && iPhrase<pExpr->nPhrase );
|
||||||
|
assert( pExpr->pConfig->eDetail==FTS5_DETAIL_COLUMNS );
|
||||||
|
|
||||||
if( pNode->bEof==0
|
if( pNode->bEof==0
|
||||||
&& pNode->iRowid==pExpr->pRoot->iRowid
|
&& pNode->iRowid==pExpr->pRoot->iRowid
|
||||||
&& pPhrase->poslist.n>0
|
&& pPhrase->poslist.n>0
|
||||||
){
|
){
|
||||||
Fts5ExprTerm *pTerm = &pPhrase->aTerm[0];
|
Fts5ExprTerm *pTerm = &pPhrase->aTerm[0];
|
||||||
if( pTerm->pSynonym ){
|
if( pTerm->pSynonym ){
|
||||||
int bDel = 0;
|
Fts5Buffer *pBuf = (Fts5Buffer*)&pTerm->pSynonym[1];
|
||||||
u8 *a;
|
|
||||||
rc = fts5ExprSynonymList(
|
rc = fts5ExprSynonymList(
|
||||||
pTerm, 1, 0, pNode->iRowid, &bDel, &a, pnCollist
|
pTerm, 1, 0, pNode->iRowid, pBuf, (u8**)ppCollist, pnCollist
|
||||||
);
|
);
|
||||||
if( bDel ){
|
|
||||||
sqlite3Fts5BufferSet(&rc, &pPhrase->poslist, *pnCollist, a);
|
|
||||||
*ppCollist = pPhrase->poslist.p;
|
|
||||||
sqlite3_free(a);
|
|
||||||
}else{
|
|
||||||
*ppCollist = a;
|
|
||||||
}
|
|
||||||
}else{
|
}else{
|
||||||
sqlite3Fts5IterCollist(pPhrase->aTerm[0].pIter, ppCollist, pnCollist);
|
*ppCollist = pPhrase->aTerm[0].pIter->pData;
|
||||||
|
*pnCollist = pPhrase->aTerm[0].pIter->nData;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
*ppCollist = 0;
|
*ppCollist = 0;
|
||||||
|
@ -261,6 +261,7 @@ typedef struct Fts5Data Fts5Data;
|
|||||||
typedef struct Fts5DlidxIter Fts5DlidxIter;
|
typedef struct Fts5DlidxIter Fts5DlidxIter;
|
||||||
typedef struct Fts5DlidxLvl Fts5DlidxLvl;
|
typedef struct Fts5DlidxLvl Fts5DlidxLvl;
|
||||||
typedef struct Fts5DlidxWriter Fts5DlidxWriter;
|
typedef struct Fts5DlidxWriter Fts5DlidxWriter;
|
||||||
|
typedef struct Fts5Iter Fts5Iter;
|
||||||
typedef struct Fts5PageWriter Fts5PageWriter;
|
typedef struct Fts5PageWriter Fts5PageWriter;
|
||||||
typedef struct Fts5SegIter Fts5SegIter;
|
typedef struct Fts5SegIter Fts5SegIter;
|
||||||
typedef struct Fts5DoclistIter Fts5DoclistIter;
|
typedef struct Fts5DoclistIter Fts5DoclistIter;
|
||||||
@ -503,10 +504,16 @@ struct Fts5SegIter {
|
|||||||
** Used by sqlite3Fts5IterPoslist() when the poslist needs to be buffered.
|
** Used by sqlite3Fts5IterPoslist() when the poslist needs to be buffered.
|
||||||
** There is no way to tell if this is populated or not.
|
** There is no way to tell if this is populated or not.
|
||||||
*/
|
*/
|
||||||
struct Fts5IndexIter {
|
struct Fts5Iter {
|
||||||
|
Fts5IndexIter base; /* Base class containing output vars */
|
||||||
|
|
||||||
Fts5Index *pIndex; /* Index that owns this iterator */
|
Fts5Index *pIndex; /* Index that owns this iterator */
|
||||||
Fts5Structure *pStruct; /* Database structure for this iterator */
|
Fts5Structure *pStruct; /* Database structure for this iterator */
|
||||||
Fts5Buffer poslist; /* Buffer containing current poslist */
|
Fts5Buffer poslist; /* Buffer containing current poslist */
|
||||||
|
Fts5Colset *pColset; /* Restrict matches to these columns */
|
||||||
|
|
||||||
|
/* Invoked to set output variables. */
|
||||||
|
void (*xSetOutputs)(Fts5Iter*, Fts5SegIter*);
|
||||||
|
|
||||||
int nSeg; /* Size of aSeg[] array */
|
int nSeg; /* Size of aSeg[] array */
|
||||||
int bRev; /* True to iterate in reverse order */
|
int bRev; /* True to iterate in reverse order */
|
||||||
@ -1752,7 +1759,7 @@ static void fts5SegIterReverseNewPage(Fts5Index *p, Fts5SegIter *pIter){
|
|||||||
** points to a delete marker. A delete marker is an entry with a 0 byte
|
** points to a delete marker. A delete marker is an entry with a 0 byte
|
||||||
** position-list.
|
** position-list.
|
||||||
*/
|
*/
|
||||||
static int fts5MultiIterIsEmpty(Fts5Index *p, Fts5IndexIter *pIter){
|
static int fts5MultiIterIsEmpty(Fts5Index *p, Fts5Iter *pIter){
|
||||||
Fts5SegIter *pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst];
|
Fts5SegIter *pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst];
|
||||||
return (p->rc==SQLITE_OK && pSeg->pLeaf && pSeg->nPos==0);
|
return (p->rc==SQLITE_OK && pSeg->pLeaf && pSeg->nPos==0);
|
||||||
}
|
}
|
||||||
@ -2406,7 +2413,7 @@ static void fts5SegIterClear(Fts5SegIter *pIter){
|
|||||||
** two iterators.
|
** two iterators.
|
||||||
*/
|
*/
|
||||||
static void fts5AssertComparisonResult(
|
static void fts5AssertComparisonResult(
|
||||||
Fts5IndexIter *pIter,
|
Fts5Iter *pIter,
|
||||||
Fts5SegIter *p1,
|
Fts5SegIter *p1,
|
||||||
Fts5SegIter *p2,
|
Fts5SegIter *p2,
|
||||||
Fts5CResult *pRes
|
Fts5CResult *pRes
|
||||||
@ -2447,7 +2454,7 @@ static void fts5AssertComparisonResult(
|
|||||||
** statement used to verify that the contents of the pIter->aFirst[] array
|
** statement used to verify that the contents of the pIter->aFirst[] array
|
||||||
** are correct.
|
** are correct.
|
||||||
*/
|
*/
|
||||||
static void fts5AssertMultiIterSetup(Fts5Index *p, Fts5IndexIter *pIter){
|
static void fts5AssertMultiIterSetup(Fts5Index *p, Fts5Iter *pIter){
|
||||||
if( p->rc==SQLITE_OK ){
|
if( p->rc==SQLITE_OK ){
|
||||||
Fts5SegIter *pFirst = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
|
Fts5SegIter *pFirst = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
|
||||||
int i;
|
int i;
|
||||||
@ -2492,7 +2499,7 @@ static void fts5AssertMultiIterSetup(Fts5Index *p, Fts5IndexIter *pIter){
|
|||||||
** to a key that is a duplicate of another, higher priority,
|
** to a key that is a duplicate of another, higher priority,
|
||||||
** segment-iterator in the pSeg->aSeg[] array.
|
** segment-iterator in the pSeg->aSeg[] array.
|
||||||
*/
|
*/
|
||||||
static int fts5MultiIterDoCompare(Fts5IndexIter *pIter, int iOut){
|
static int fts5MultiIterDoCompare(Fts5Iter *pIter, int iOut){
|
||||||
int i1; /* Index of left-hand Fts5SegIter */
|
int i1; /* Index of left-hand Fts5SegIter */
|
||||||
int i2; /* Index of right-hand Fts5SegIter */
|
int i2; /* Index of right-hand Fts5SegIter */
|
||||||
int iRes;
|
int iRes;
|
||||||
@ -2638,7 +2645,7 @@ static void fts5SegIterNextFrom(
|
|||||||
/*
|
/*
|
||||||
** Free the iterator object passed as the second argument.
|
** Free the iterator object passed as the second argument.
|
||||||
*/
|
*/
|
||||||
static void fts5MultiIterFree(Fts5Index *p, Fts5IndexIter *pIter){
|
static void fts5MultiIterFree(Fts5Index *p, Fts5Iter *pIter){
|
||||||
if( pIter ){
|
if( pIter ){
|
||||||
int i;
|
int i;
|
||||||
for(i=0; i<pIter->nSeg; i++){
|
for(i=0; i<pIter->nSeg; i++){
|
||||||
@ -2652,7 +2659,7 @@ static void fts5MultiIterFree(Fts5Index *p, Fts5IndexIter *pIter){
|
|||||||
|
|
||||||
static void fts5MultiIterAdvanced(
|
static void fts5MultiIterAdvanced(
|
||||||
Fts5Index *p, /* FTS5 backend to iterate within */
|
Fts5Index *p, /* FTS5 backend to iterate within */
|
||||||
Fts5IndexIter *pIter, /* Iterator to update aFirst[] array for */
|
Fts5Iter *pIter, /* Iterator to update aFirst[] array for */
|
||||||
int iChanged, /* Index of sub-iterator just advanced */
|
int iChanged, /* Index of sub-iterator just advanced */
|
||||||
int iMinset /* Minimum entry in aFirst[] to set */
|
int iMinset /* Minimum entry in aFirst[] to set */
|
||||||
){
|
){
|
||||||
@ -2680,8 +2687,9 @@ static void fts5MultiIterAdvanced(
|
|||||||
*/
|
*/
|
||||||
static int fts5MultiIterAdvanceRowid(
|
static int fts5MultiIterAdvanceRowid(
|
||||||
Fts5Index *p, /* FTS5 backend to iterate within */
|
Fts5Index *p, /* FTS5 backend to iterate within */
|
||||||
Fts5IndexIter *pIter, /* Iterator to update aFirst[] array for */
|
Fts5Iter *pIter, /* Iterator to update aFirst[] array for */
|
||||||
int iChanged /* Index of sub-iterator just advanced */
|
int iChanged, /* Index of sub-iterator just advanced */
|
||||||
|
Fts5SegIter **ppFirst
|
||||||
){
|
){
|
||||||
Fts5SegIter *pNew = &pIter->aSeg[iChanged];
|
Fts5SegIter *pNew = &pIter->aSeg[iChanged];
|
||||||
|
|
||||||
@ -2714,13 +2722,14 @@ static int fts5MultiIterAdvanceRowid(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*ppFirst = pNew;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Set the pIter->bEof variable based on the state of the sub-iterators.
|
** Set the pIter->bEof variable based on the state of the sub-iterators.
|
||||||
*/
|
*/
|
||||||
static void fts5MultiIterSetEof(Fts5IndexIter *pIter){
|
static void fts5MultiIterSetEof(Fts5Iter *pIter){
|
||||||
Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
|
Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
|
||||||
pIter->bEof = pSeg->pLeaf==0;
|
pIter->bEof = pSeg->pLeaf==0;
|
||||||
pIter->iSwitchRowid = pSeg->iRowid;
|
pIter->iSwitchRowid = pSeg->iRowid;
|
||||||
@ -2735,39 +2744,44 @@ static void fts5MultiIterSetEof(Fts5IndexIter *pIter){
|
|||||||
*/
|
*/
|
||||||
static void fts5MultiIterNext(
|
static void fts5MultiIterNext(
|
||||||
Fts5Index *p,
|
Fts5Index *p,
|
||||||
Fts5IndexIter *pIter,
|
Fts5Iter *pIter,
|
||||||
int bFrom, /* True if argument iFrom is valid */
|
int bFrom, /* True if argument iFrom is valid */
|
||||||
i64 iFrom /* Advance at least as far as this */
|
i64 iFrom /* Advance at least as far as this */
|
||||||
){
|
){
|
||||||
if( p->rc==SQLITE_OK ){
|
int bUseFrom = bFrom;
|
||||||
int bUseFrom = bFrom;
|
while( p->rc==SQLITE_OK ){
|
||||||
do {
|
int iFirst = pIter->aFirst[1].iFirst;
|
||||||
int iFirst = pIter->aFirst[1].iFirst;
|
int bNewTerm = 0;
|
||||||
int bNewTerm = 0;
|
Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
|
||||||
Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
|
assert( p->rc==SQLITE_OK );
|
||||||
assert( p->rc==SQLITE_OK );
|
if( bUseFrom && pSeg->pDlidx ){
|
||||||
if( bUseFrom && pSeg->pDlidx ){
|
fts5SegIterNextFrom(p, pSeg, iFrom);
|
||||||
fts5SegIterNextFrom(p, pSeg, iFrom);
|
}else{
|
||||||
}else{
|
pSeg->xNext(p, pSeg, &bNewTerm);
|
||||||
pSeg->xNext(p, pSeg, &bNewTerm);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if( pSeg->pLeaf==0 || bNewTerm
|
if( pSeg->pLeaf==0 || bNewTerm
|
||||||
|| fts5MultiIterAdvanceRowid(p, pIter, iFirst)
|
|| fts5MultiIterAdvanceRowid(p, pIter, iFirst, &pSeg)
|
||||||
){
|
){
|
||||||
fts5MultiIterAdvanced(p, pIter, iFirst, 1);
|
fts5MultiIterAdvanced(p, pIter, iFirst, 1);
|
||||||
fts5MultiIterSetEof(pIter);
|
fts5MultiIterSetEof(pIter);
|
||||||
}
|
pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst];
|
||||||
fts5AssertMultiIterSetup(p, pIter);
|
if( pSeg->pLeaf==0 ) return;
|
||||||
|
}
|
||||||
|
|
||||||
bUseFrom = 0;
|
fts5AssertMultiIterSetup(p, pIter);
|
||||||
}while( pIter->bSkipEmpty && fts5MultiIterIsEmpty(p, pIter) );
|
assert( pSeg==&pIter->aSeg[pIter->aFirst[1].iFirst] && pSeg->pLeaf );
|
||||||
|
if( pIter->bSkipEmpty==0 || pSeg->nPos ){
|
||||||
|
pIter->xSetOutputs(pIter, pSeg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bUseFrom = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fts5MultiIterNext2(
|
static void fts5MultiIterNext2(
|
||||||
Fts5Index *p,
|
Fts5Index *p,
|
||||||
Fts5IndexIter *pIter,
|
Fts5Iter *pIter,
|
||||||
int *pbNewTerm /* OUT: True if *might* be new term */
|
int *pbNewTerm /* OUT: True if *might* be new term */
|
||||||
){
|
){
|
||||||
assert( pIter->bSkipEmpty );
|
assert( pIter->bSkipEmpty );
|
||||||
@ -2780,7 +2794,7 @@ static void fts5MultiIterNext2(
|
|||||||
assert( p->rc==SQLITE_OK );
|
assert( p->rc==SQLITE_OK );
|
||||||
pSeg->xNext(p, pSeg, &bNewTerm);
|
pSeg->xNext(p, pSeg, &bNewTerm);
|
||||||
if( pSeg->pLeaf==0 || bNewTerm
|
if( pSeg->pLeaf==0 || bNewTerm
|
||||||
|| fts5MultiIterAdvanceRowid(p, pIter, iFirst)
|
|| fts5MultiIterAdvanceRowid(p, pIter, iFirst, &pSeg)
|
||||||
){
|
){
|
||||||
fts5MultiIterAdvanced(p, pIter, iFirst, 1);
|
fts5MultiIterAdvanced(p, pIter, iFirst, 1);
|
||||||
fts5MultiIterSetEof(pIter);
|
fts5MultiIterSetEof(pIter);
|
||||||
@ -2794,17 +2808,19 @@ static void fts5MultiIterNext2(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fts5IterSetOutputs_Noop(Fts5Iter *pIter, Fts5SegIter *pSeg){
|
||||||
|
}
|
||||||
|
|
||||||
static Fts5IndexIter *fts5MultiIterAlloc(
|
static Fts5Iter *fts5MultiIterAlloc(
|
||||||
Fts5Index *p, /* FTS5 backend to iterate within */
|
Fts5Index *p, /* FTS5 backend to iterate within */
|
||||||
int nSeg
|
int nSeg
|
||||||
){
|
){
|
||||||
Fts5IndexIter *pNew;
|
Fts5Iter *pNew;
|
||||||
int nSlot; /* Power of two >= nSeg */
|
int nSlot; /* Power of two >= nSeg */
|
||||||
|
|
||||||
for(nSlot=2; nSlot<nSeg; nSlot=nSlot*2);
|
for(nSlot=2; nSlot<nSeg; nSlot=nSlot*2);
|
||||||
pNew = fts5IdxMalloc(p,
|
pNew = fts5IdxMalloc(p,
|
||||||
sizeof(Fts5IndexIter) + /* pNew */
|
sizeof(Fts5Iter) + /* pNew */
|
||||||
sizeof(Fts5SegIter) * (nSlot-1) + /* pNew->aSeg[] */
|
sizeof(Fts5SegIter) * (nSlot-1) + /* pNew->aSeg[] */
|
||||||
sizeof(Fts5CResult) * nSlot /* pNew->aFirst[] */
|
sizeof(Fts5CResult) * nSlot /* pNew->aFirst[] */
|
||||||
);
|
);
|
||||||
@ -2812,12 +2828,13 @@ static Fts5IndexIter *fts5MultiIterAlloc(
|
|||||||
pNew->nSeg = nSlot;
|
pNew->nSeg = nSlot;
|
||||||
pNew->aFirst = (Fts5CResult*)&pNew->aSeg[nSlot];
|
pNew->aFirst = (Fts5CResult*)&pNew->aSeg[nSlot];
|
||||||
pNew->pIndex = p;
|
pNew->pIndex = p;
|
||||||
|
pNew->xSetOutputs = fts5IterSetOutputs_Noop;
|
||||||
}
|
}
|
||||||
return pNew;
|
return pNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Allocate a new Fts5IndexIter object.
|
** Allocate a new Fts5Iter object.
|
||||||
**
|
**
|
||||||
** The new object will be used to iterate through data in structure pStruct.
|
** The new object will be used to iterate through data in structure pStruct.
|
||||||
** If iLevel is -ve, then all data in all segments is merged. Or, if iLevel
|
** If iLevel is -ve, then all data in all segments is merged. Or, if iLevel
|
||||||
@ -2835,14 +2852,14 @@ static void fts5MultiIterNew(
|
|||||||
const u8 *pTerm, int nTerm, /* Term to seek to (or NULL/0) */
|
const u8 *pTerm, int nTerm, /* Term to seek to (or NULL/0) */
|
||||||
int iLevel, /* Level to iterate (-1 for all) */
|
int iLevel, /* Level to iterate (-1 for all) */
|
||||||
int nSegment, /* Number of segments to merge (iLevel>=0) */
|
int nSegment, /* Number of segments to merge (iLevel>=0) */
|
||||||
Fts5IndexIter **ppOut /* New object */
|
Fts5Iter **ppOut /* New object */
|
||||||
){
|
){
|
||||||
int nSeg = 0; /* Number of segment-iters in use */
|
int nSeg = 0; /* Number of segment-iters in use */
|
||||||
int iIter = 0; /* */
|
int iIter = 0; /* */
|
||||||
int iSeg; /* Used to iterate through segments */
|
int iSeg; /* Used to iterate through segments */
|
||||||
Fts5Buffer buf = {0,0,0}; /* Buffer used by fts5SegIterSeekInit() */
|
Fts5Buffer buf = {0,0,0}; /* Buffer used by fts5SegIterSeekInit() */
|
||||||
Fts5StructureLevel *pLvl;
|
Fts5StructureLevel *pLvl;
|
||||||
Fts5IndexIter *pNew;
|
Fts5Iter *pNew;
|
||||||
|
|
||||||
assert( (pTerm==0 && nTerm==0) || iLevel<0 );
|
assert( (pTerm==0 && nTerm==0) || iLevel<0 );
|
||||||
|
|
||||||
@ -2917,16 +2934,16 @@ static void fts5MultiIterNew(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Create an Fts5IndexIter that iterates through the doclist provided
|
** Create an Fts5Iter that iterates through the doclist provided
|
||||||
** as the second argument.
|
** as the second argument.
|
||||||
*/
|
*/
|
||||||
static void fts5MultiIterNew2(
|
static void fts5MultiIterNew2(
|
||||||
Fts5Index *p, /* FTS5 backend to iterate within */
|
Fts5Index *p, /* FTS5 backend to iterate within */
|
||||||
Fts5Data *pData, /* Doclist to iterate through */
|
Fts5Data *pData, /* Doclist to iterate through */
|
||||||
int bDesc, /* True for descending rowid order */
|
int bDesc, /* True for descending rowid order */
|
||||||
Fts5IndexIter **ppOut /* New object */
|
Fts5Iter **ppOut /* New object */
|
||||||
){
|
){
|
||||||
Fts5IndexIter *pNew;
|
Fts5Iter *pNew;
|
||||||
pNew = fts5MultiIterAlloc(p, 2);
|
pNew = fts5MultiIterAlloc(p, 2);
|
||||||
if( pNew ){
|
if( pNew ){
|
||||||
Fts5SegIter *pIter = &pNew->aSeg[1];
|
Fts5SegIter *pIter = &pNew->aSeg[1];
|
||||||
@ -2961,7 +2978,7 @@ static void fts5MultiIterNew2(
|
|||||||
** Return true if the iterator is at EOF or if an error has occurred.
|
** Return true if the iterator is at EOF or if an error has occurred.
|
||||||
** False otherwise.
|
** False otherwise.
|
||||||
*/
|
*/
|
||||||
static int fts5MultiIterEof(Fts5Index *p, Fts5IndexIter *pIter){
|
static int fts5MultiIterEof(Fts5Index *p, Fts5Iter *pIter){
|
||||||
assert( p->rc
|
assert( p->rc
|
||||||
|| (pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf==0)==pIter->bEof
|
|| (pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf==0)==pIter->bEof
|
||||||
);
|
);
|
||||||
@ -2973,7 +2990,7 @@ static int fts5MultiIterEof(Fts5Index *p, Fts5IndexIter *pIter){
|
|||||||
** to. If the iterator points to EOF when this function is called the
|
** to. If the iterator points to EOF when this function is called the
|
||||||
** results are undefined.
|
** results are undefined.
|
||||||
*/
|
*/
|
||||||
static i64 fts5MultiIterRowid(Fts5IndexIter *pIter){
|
static i64 fts5MultiIterRowid(Fts5Iter *pIter){
|
||||||
assert( pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf );
|
assert( pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf );
|
||||||
return pIter->aSeg[ pIter->aFirst[1].iFirst ].iRowid;
|
return pIter->aSeg[ pIter->aFirst[1].iFirst ].iRowid;
|
||||||
}
|
}
|
||||||
@ -2983,7 +3000,7 @@ static i64 fts5MultiIterRowid(Fts5IndexIter *pIter){
|
|||||||
*/
|
*/
|
||||||
static void fts5MultiIterNextFrom(
|
static void fts5MultiIterNextFrom(
|
||||||
Fts5Index *p,
|
Fts5Index *p,
|
||||||
Fts5IndexIter *pIter,
|
Fts5Iter *pIter,
|
||||||
i64 iMatch
|
i64 iMatch
|
||||||
){
|
){
|
||||||
while( 1 ){
|
while( 1 ){
|
||||||
@ -3000,7 +3017,7 @@ static void fts5MultiIterNextFrom(
|
|||||||
** Return a pointer to a buffer containing the term associated with the
|
** Return a pointer to a buffer containing the term associated with the
|
||||||
** entry that the iterator currently points to.
|
** entry that the iterator currently points to.
|
||||||
*/
|
*/
|
||||||
static const u8 *fts5MultiIterTerm(Fts5IndexIter *pIter, int *pn){
|
static const u8 *fts5MultiIterTerm(Fts5Iter *pIter, int *pn){
|
||||||
Fts5SegIter *p = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
|
Fts5SegIter *p = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
|
||||||
*pn = p->term.n;
|
*pn = p->term.n;
|
||||||
return p->term.p;
|
return p->term.p;
|
||||||
@ -3582,7 +3599,7 @@ static void fts5WriteInit(
|
|||||||
** incremental merge operation. This function is called if the incremental
|
** incremental merge operation. This function is called if the incremental
|
||||||
** merge step has finished but the input has not been completely exhausted.
|
** merge step has finished but the input has not been completely exhausted.
|
||||||
*/
|
*/
|
||||||
static void fts5TrimSegments(Fts5Index *p, Fts5IndexIter *pIter){
|
static void fts5TrimSegments(Fts5Index *p, Fts5Iter *pIter){
|
||||||
int i;
|
int i;
|
||||||
Fts5Buffer buf;
|
Fts5Buffer buf;
|
||||||
memset(&buf, 0, sizeof(Fts5Buffer));
|
memset(&buf, 0, sizeof(Fts5Buffer));
|
||||||
@ -3660,7 +3677,7 @@ static void fts5IndexMergeLevel(
|
|||||||
Fts5Structure *pStruct = *ppStruct;
|
Fts5Structure *pStruct = *ppStruct;
|
||||||
Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
|
Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
|
||||||
Fts5StructureLevel *pLvlOut;
|
Fts5StructureLevel *pLvlOut;
|
||||||
Fts5IndexIter *pIter = 0; /* Iterator to read input data */
|
Fts5Iter *pIter = 0; /* Iterator to read input data */
|
||||||
int nRem = pnRem ? *pnRem : 0; /* Output leaf pages left to write */
|
int nRem = pnRem ? *pnRem : 0; /* Output leaf pages left to write */
|
||||||
int nInput; /* Number of input segments */
|
int nInput; /* Number of input segments */
|
||||||
Fts5SegWriter writer; /* Writer object */
|
Fts5SegWriter writer; /* Writer object */
|
||||||
@ -4342,7 +4359,7 @@ static int fts5IndexExtractCol(
|
|||||||
static int fts5AppendRowid(
|
static int fts5AppendRowid(
|
||||||
Fts5Index *p,
|
Fts5Index *p,
|
||||||
i64 iDelta,
|
i64 iDelta,
|
||||||
Fts5IndexIter *pMulti,
|
Fts5Iter *pMulti,
|
||||||
Fts5Colset *pColset,
|
Fts5Colset *pColset,
|
||||||
Fts5Buffer *pBuf
|
Fts5Buffer *pBuf
|
||||||
){
|
){
|
||||||
@ -4367,7 +4384,7 @@ static int fts5AppendRowid(
|
|||||||
static int fts5AppendPoslist(
|
static int fts5AppendPoslist(
|
||||||
Fts5Index *p,
|
Fts5Index *p,
|
||||||
i64 iDelta,
|
i64 iDelta,
|
||||||
Fts5IndexIter *pMulti,
|
Fts5Iter *pMulti,
|
||||||
Fts5Colset *pColset,
|
Fts5Colset *pColset,
|
||||||
Fts5Buffer *pBuf
|
Fts5Buffer *pBuf
|
||||||
){
|
){
|
||||||
@ -4645,14 +4662,14 @@ static void fts5SetupPrefixIter(
|
|||||||
const u8 *pToken, /* Buffer containing prefix to match */
|
const u8 *pToken, /* Buffer containing prefix to match */
|
||||||
int nToken, /* Size of buffer pToken in bytes */
|
int nToken, /* Size of buffer pToken in bytes */
|
||||||
Fts5Colset *pColset, /* Restrict matches to these columns */
|
Fts5Colset *pColset, /* Restrict matches to these columns */
|
||||||
Fts5IndexIter **ppIter /* OUT: New iterator */
|
Fts5Iter **ppIter /* OUT: New iterator */
|
||||||
){
|
){
|
||||||
Fts5Structure *pStruct;
|
Fts5Structure *pStruct;
|
||||||
Fts5Buffer *aBuf;
|
Fts5Buffer *aBuf;
|
||||||
const int nBuf = 32;
|
const int nBuf = 32;
|
||||||
|
|
||||||
void (*xMerge)(Fts5Index*, Fts5Buffer*, Fts5Buffer*);
|
void (*xMerge)(Fts5Index*, Fts5Buffer*, Fts5Buffer*);
|
||||||
int (*xAppend)(Fts5Index*, i64, Fts5IndexIter*, Fts5Colset*, Fts5Buffer*);
|
int (*xAppend)(Fts5Index*, i64, Fts5Iter*, Fts5Colset*, Fts5Buffer*);
|
||||||
if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){
|
if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){
|
||||||
xMerge = fts5MergeRowidLists;
|
xMerge = fts5MergeRowidLists;
|
||||||
xAppend = fts5AppendRowid;
|
xAppend = fts5AppendRowid;
|
||||||
@ -4668,7 +4685,7 @@ static void fts5SetupPrefixIter(
|
|||||||
const int flags = FTS5INDEX_QUERY_SCAN;
|
const int flags = FTS5INDEX_QUERY_SCAN;
|
||||||
int i;
|
int i;
|
||||||
i64 iLastRowid = 0;
|
i64 iLastRowid = 0;
|
||||||
Fts5IndexIter *p1 = 0; /* Iterator used to gather data from index */
|
Fts5Iter *p1 = 0; /* Iterator used to gather data from index */
|
||||||
Fts5Data *pData;
|
Fts5Data *pData;
|
||||||
Fts5Buffer doclist;
|
Fts5Buffer doclist;
|
||||||
int bNewTerm = 1;
|
int bNewTerm = 1;
|
||||||
@ -4932,6 +4949,179 @@ int sqlite3Fts5IndexWrite(
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int fts5IndexExtractColset (
|
||||||
|
Fts5Colset *pColset, /* Colset to filter on */
|
||||||
|
const u8 *pPos, int nPos, /* Position list */
|
||||||
|
Fts5Buffer *pBuf /* Output buffer */
|
||||||
|
){
|
||||||
|
int rc = SQLITE_OK;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
fts5BufferZero(pBuf);
|
||||||
|
for(i=0; i<pColset->nCol; i++){
|
||||||
|
const u8 *pSub = pPos;
|
||||||
|
int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]);
|
||||||
|
if( nSub ){
|
||||||
|
fts5BufferAppendBlob(&rc, pBuf, nSub, pSub);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** xSetOutputs callback used by detail=none tables.
|
||||||
|
*/
|
||||||
|
static void fts5IterSetOutputs_None(Fts5Iter *pIter, Fts5SegIter *pSeg){
|
||||||
|
assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_NONE );
|
||||||
|
pIter->base.iRowid = pSeg->iRowid;
|
||||||
|
pIter->base.nData = pSeg->nPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** xSetOutputs callback used by detail=full and detail=col tables when no
|
||||||
|
** column filters are specified.
|
||||||
|
*/
|
||||||
|
static void fts5IterSetOutputs_Nocolset(Fts5Iter *pIter, Fts5SegIter *pSeg){
|
||||||
|
pIter->base.iRowid = pSeg->iRowid;
|
||||||
|
pIter->base.nData = pSeg->nPos;
|
||||||
|
|
||||||
|
assert( pIter->pIndex->pConfig->eDetail!=FTS5_DETAIL_NONE );
|
||||||
|
assert( pIter->pColset==0 || pIter->bFiltered );
|
||||||
|
|
||||||
|
if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){
|
||||||
|
/* All data is stored on the current page. Populate the output
|
||||||
|
** variables to point into the body of the page object. */
|
||||||
|
pIter->base.pData = &pSeg->pLeaf->p[pSeg->iLeafOffset];
|
||||||
|
}else{
|
||||||
|
/* The data is distributed over two or more pages. Copy it into the
|
||||||
|
** Fts5Iter.poslist buffer and then set the output pointer to point
|
||||||
|
** to this buffer. */
|
||||||
|
fts5BufferZero(&pIter->poslist);
|
||||||
|
fts5SegiterPoslist(pIter->pIndex, pSeg, 0, &pIter->poslist);
|
||||||
|
pIter->base.pData = pIter->poslist.p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** xSetOutputs callback used by detail=col when there is a column filter
|
||||||
|
** and there are 100 or more columns. Also called as a fallback from
|
||||||
|
** fts5IterSetOutputs_Col100 if the column-list spans more than one page.
|
||||||
|
*/
|
||||||
|
static void fts5IterSetOutputs_Col(Fts5Iter *pIter, Fts5SegIter *pSeg){
|
||||||
|
fts5BufferZero(&pIter->poslist);
|
||||||
|
fts5SegiterPoslist(pIter->pIndex, pSeg, pIter->pColset, &pIter->poslist);
|
||||||
|
pIter->base.iRowid = pSeg->iRowid;
|
||||||
|
pIter->base.pData = pIter->poslist.p;
|
||||||
|
pIter->base.nData = pIter->poslist.n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** xSetOutputs callback used when:
|
||||||
|
**
|
||||||
|
** * detail=col,
|
||||||
|
** * there is a column filter, and
|
||||||
|
** * the table contains 100 or fewer columns.
|
||||||
|
**
|
||||||
|
** The last point is to ensure all column numbers are stored as
|
||||||
|
** single-byte varints.
|
||||||
|
*/
|
||||||
|
static void fts5IterSetOutputs_Col100(Fts5Iter *pIter, Fts5SegIter *pSeg){
|
||||||
|
|
||||||
|
assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_COLUMNS );
|
||||||
|
assert( pIter->pColset );
|
||||||
|
|
||||||
|
if( pSeg->iLeafOffset+pSeg->nPos>pSeg->pLeaf->szLeaf ){
|
||||||
|
fts5IterSetOutputs_Col(pIter, pSeg);
|
||||||
|
}else{
|
||||||
|
u8 *a = (u8*)&pSeg->pLeaf->p[pSeg->iLeafOffset];
|
||||||
|
u8 *pEnd = (u8*)&a[pSeg->nPos];
|
||||||
|
int iPrev = 0;
|
||||||
|
int *aiCol = pIter->pColset->aiCol;
|
||||||
|
int *aiColEnd = &aiCol[pIter->pColset->nCol];
|
||||||
|
|
||||||
|
u8 *aOut = pIter->poslist.p;
|
||||||
|
int iPrevOut = 0;
|
||||||
|
|
||||||
|
pIter->base.iRowid = pSeg->iRowid;
|
||||||
|
|
||||||
|
while( a<pEnd ){
|
||||||
|
iPrev += (int)a++[0] - 2;
|
||||||
|
while( *aiCol<iPrev ){
|
||||||
|
aiCol++;
|
||||||
|
if( aiCol==aiColEnd ) goto setoutputs_col_out;
|
||||||
|
}
|
||||||
|
if( *aiCol==iPrev ){
|
||||||
|
*aOut++ = (iPrev - iPrevOut) + 2;
|
||||||
|
iPrevOut = iPrev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setoutputs_col_out:
|
||||||
|
pIter->base.pData = pIter->poslist.p;
|
||||||
|
pIter->base.nData = aOut - pIter->poslist.p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** xSetOutputs callback used by detail=full when there is a column filter.
|
||||||
|
*/
|
||||||
|
static void fts5IterSetOutputs_Full(Fts5Iter *pIter, Fts5SegIter *pSeg){
|
||||||
|
Fts5Colset *pColset = pIter->pColset;
|
||||||
|
pIter->base.iRowid = pSeg->iRowid;
|
||||||
|
|
||||||
|
assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_FULL );
|
||||||
|
assert( pColset );
|
||||||
|
|
||||||
|
if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){
|
||||||
|
/* All data is stored on the current page. Populate the output
|
||||||
|
** variables to point into the body of the page object. */
|
||||||
|
const u8 *a = &pSeg->pLeaf->p[pSeg->iLeafOffset];
|
||||||
|
if( pColset->nCol==1 ){
|
||||||
|
pIter->base.nData = fts5IndexExtractCol(&a, pSeg->nPos,pColset->aiCol[0]);
|
||||||
|
pIter->base.pData = a;
|
||||||
|
}else{
|
||||||
|
fts5BufferZero(&pIter->poslist);
|
||||||
|
fts5IndexExtractColset(pColset, a, pSeg->nPos, &pIter->poslist);
|
||||||
|
pIter->base.pData = pIter->poslist.p;
|
||||||
|
pIter->base.nData = pIter->poslist.n;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
/* The data is distributed over two or more pages. Copy it into the
|
||||||
|
** Fts5Iter.poslist buffer and then set the output pointer to point
|
||||||
|
** to this buffer. */
|
||||||
|
fts5BufferZero(&pIter->poslist);
|
||||||
|
fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist);
|
||||||
|
pIter->base.pData = pIter->poslist.p;
|
||||||
|
pIter->base.nData = pIter->poslist.n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fts5IterSetOutputCb(int *pRc, Fts5Iter *pIter){
|
||||||
|
Fts5Config *pConfig = pIter->pIndex->pConfig;
|
||||||
|
if( pConfig->eDetail==FTS5_DETAIL_NONE ){
|
||||||
|
pIter->xSetOutputs = fts5IterSetOutputs_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( pIter->pColset==0 || pIter->bFiltered ){
|
||||||
|
pIter->xSetOutputs = fts5IterSetOutputs_Nocolset;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( pConfig->eDetail==FTS5_DETAIL_FULL ){
|
||||||
|
pIter->xSetOutputs = fts5IterSetOutputs_Full;
|
||||||
|
}
|
||||||
|
|
||||||
|
else{
|
||||||
|
assert( pConfig->eDetail==FTS5_DETAIL_COLUMNS );
|
||||||
|
if( pConfig->nCol<=100 ){
|
||||||
|
pIter->xSetOutputs = fts5IterSetOutputs_Col100;
|
||||||
|
sqlite3Fts5BufferSize(pRc, &pIter->poslist, pConfig->nCol);
|
||||||
|
}else{
|
||||||
|
pIter->xSetOutputs = fts5IterSetOutputs_Col;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Open a new iterator to iterate though all rowid that match the
|
** Open a new iterator to iterate though all rowid that match the
|
||||||
** specified token or token prefix.
|
** specified token or token prefix.
|
||||||
@ -4944,22 +5134,27 @@ int sqlite3Fts5IndexQuery(
|
|||||||
Fts5IndexIter **ppIter /* OUT: New iterator object */
|
Fts5IndexIter **ppIter /* OUT: New iterator object */
|
||||||
){
|
){
|
||||||
Fts5Config *pConfig = p->pConfig;
|
Fts5Config *pConfig = p->pConfig;
|
||||||
Fts5IndexIter *pRet = 0;
|
Fts5Iter *pRet = 0;
|
||||||
int iIdx = 0;
|
|
||||||
Fts5Buffer buf = {0, 0, 0};
|
Fts5Buffer buf = {0, 0, 0};
|
||||||
|
|
||||||
/* If the QUERY_SCAN flag is set, all other flags must be clear. */
|
/* If the QUERY_SCAN flag is set, all other flags must be clear. */
|
||||||
assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN );
|
assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN );
|
||||||
|
|
||||||
if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){
|
if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){
|
||||||
|
int iIdx = 0; /* Index to search */
|
||||||
memcpy(&buf.p[1], pToken, nToken);
|
memcpy(&buf.p[1], pToken, nToken);
|
||||||
|
|
||||||
#ifdef SQLITE_DEBUG
|
/* Figure out which index to search and set iIdx accordingly. If this
|
||||||
/* If the QUERY_TEST_NOIDX flag was specified, then this must be a
|
** is a prefix query for which there is no prefix index, set iIdx to
|
||||||
|
** greater than pConfig->nPrefix to indicate that the query will be
|
||||||
|
** satisfied by scanning multiple terms in the main index.
|
||||||
|
**
|
||||||
|
** If the QUERY_TEST_NOIDX flag was specified, then this must be a
|
||||||
** prefix-query. Instead of using a prefix-index (if one exists),
|
** prefix-query. Instead of using a prefix-index (if one exists),
|
||||||
** evaluate the prefix query using the main FTS index. This is used
|
** evaluate the prefix query using the main FTS index. This is used
|
||||||
** for internal sanity checking by the integrity-check in debug
|
** for internal sanity checking by the integrity-check in debug
|
||||||
** mode only. */
|
** mode only. */
|
||||||
|
#ifdef SQLITE_DEBUG
|
||||||
if( pConfig->bPrefixIndex==0 || (flags & FTS5INDEX_QUERY_TEST_NOIDX) ){
|
if( pConfig->bPrefixIndex==0 || (flags & FTS5INDEX_QUERY_TEST_NOIDX) ){
|
||||||
assert( flags & FTS5INDEX_QUERY_PREFIX );
|
assert( flags & FTS5INDEX_QUERY_PREFIX );
|
||||||
iIdx = 1+pConfig->nPrefix;
|
iIdx = 1+pConfig->nPrefix;
|
||||||
@ -4973,6 +5168,7 @@ int sqlite3Fts5IndexQuery(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( iIdx<=pConfig->nPrefix ){
|
if( iIdx<=pConfig->nPrefix ){
|
||||||
|
/* Straight index lookup */
|
||||||
Fts5Structure *pStruct = fts5StructureRead(p);
|
Fts5Structure *pStruct = fts5StructureRead(p);
|
||||||
buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx);
|
buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx);
|
||||||
if( pStruct ){
|
if( pStruct ){
|
||||||
@ -4980,17 +5176,25 @@ int sqlite3Fts5IndexQuery(
|
|||||||
fts5StructureRelease(pStruct);
|
fts5StructureRelease(pStruct);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
|
/* Scan multiple terms in the main index */
|
||||||
int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0;
|
int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0;
|
||||||
buf.p[0] = FTS5_MAIN_PREFIX;
|
buf.p[0] = FTS5_MAIN_PREFIX;
|
||||||
fts5SetupPrefixIter(p, bDesc, buf.p, nToken+1, pColset, &pRet);
|
fts5SetupPrefixIter(p, bDesc, buf.p, nToken+1, pColset, &pRet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( p->rc==SQLITE_OK ){
|
||||||
|
Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst];
|
||||||
|
pRet->pColset = pColset;
|
||||||
|
fts5IterSetOutputCb(&p->rc, pRet);
|
||||||
|
if( p->rc==SQLITE_OK && pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg);
|
||||||
|
}
|
||||||
if( p->rc ){
|
if( p->rc ){
|
||||||
sqlite3Fts5IterClose(pRet);
|
sqlite3Fts5IterClose(&pRet->base);
|
||||||
pRet = 0;
|
pRet = 0;
|
||||||
fts5CloseReader(p);
|
fts5CloseReader(p);
|
||||||
}
|
}
|
||||||
*ppIter = pRet;
|
|
||||||
|
*ppIter = &pRet->base;
|
||||||
sqlite3Fts5BufferFree(&buf);
|
sqlite3Fts5BufferFree(&buf);
|
||||||
}
|
}
|
||||||
return fts5IndexReturn(p);
|
return fts5IndexReturn(p);
|
||||||
@ -5000,14 +5204,15 @@ int sqlite3Fts5IndexQuery(
|
|||||||
** Return true if the iterator passed as the only argument is at EOF.
|
** Return true if the iterator passed as the only argument is at EOF.
|
||||||
*/
|
*/
|
||||||
int sqlite3Fts5IterEof(Fts5IndexIter *pIter){
|
int sqlite3Fts5IterEof(Fts5IndexIter *pIter){
|
||||||
assert( pIter->pIndex->rc==SQLITE_OK );
|
assert( ((Fts5Iter*)pIter)->pIndex->rc==SQLITE_OK );
|
||||||
return pIter->bEof;
|
return ((Fts5Iter*)pIter)->bEof;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Move to the next matching rowid.
|
** Move to the next matching rowid.
|
||||||
*/
|
*/
|
||||||
int sqlite3Fts5IterNext(Fts5IndexIter *pIter){
|
int sqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){
|
||||||
|
Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
|
||||||
assert( pIter->pIndex->rc==SQLITE_OK );
|
assert( pIter->pIndex->rc==SQLITE_OK );
|
||||||
fts5MultiIterNext(pIter->pIndex, pIter, 0, 0);
|
fts5MultiIterNext(pIter->pIndex, pIter, 0, 0);
|
||||||
return fts5IndexReturn(pIter->pIndex);
|
return fts5IndexReturn(pIter->pIndex);
|
||||||
@ -5016,7 +5221,8 @@ int sqlite3Fts5IterNext(Fts5IndexIter *pIter){
|
|||||||
/*
|
/*
|
||||||
** Move to the next matching term/rowid. Used by the fts5vocab module.
|
** Move to the next matching term/rowid. Used by the fts5vocab module.
|
||||||
*/
|
*/
|
||||||
int sqlite3Fts5IterNextScan(Fts5IndexIter *pIter){
|
int sqlite3Fts5IterNextScan(Fts5IndexIter *pIndexIter){
|
||||||
|
Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
|
||||||
Fts5Index *p = pIter->pIndex;
|
Fts5Index *p = pIter->pIndex;
|
||||||
|
|
||||||
assert( pIter->pIndex->rc==SQLITE_OK );
|
assert( pIter->pIndex->rc==SQLITE_OK );
|
||||||
@ -5039,7 +5245,8 @@ int sqlite3Fts5IterNextScan(Fts5IndexIter *pIter){
|
|||||||
** definition of "at or after" depends on whether this iterator iterates
|
** definition of "at or after" depends on whether this iterator iterates
|
||||||
** in ascending or descending rowid order.
|
** in ascending or descending rowid order.
|
||||||
*/
|
*/
|
||||||
int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIter, i64 iMatch){
|
int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){
|
||||||
|
Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
|
||||||
fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch);
|
fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch);
|
||||||
return fts5IndexReturn(pIter->pIndex);
|
return fts5IndexReturn(pIter->pIndex);
|
||||||
}
|
}
|
||||||
@ -5047,121 +5254,26 @@ int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIter, i64 iMatch){
|
|||||||
/*
|
/*
|
||||||
** Return the current rowid.
|
** Return the current rowid.
|
||||||
*/
|
*/
|
||||||
i64 sqlite3Fts5IterRowid(Fts5IndexIter *pIter){
|
i64 sqlite3Fts5IterRowid(Fts5IndexIter *pIndexIter){
|
||||||
return fts5MultiIterRowid(pIter);
|
return fts5MultiIterRowid((Fts5Iter*)pIndexIter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Return the current term.
|
** Return the current term.
|
||||||
*/
|
*/
|
||||||
const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIter, int *pn){
|
const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){
|
||||||
int n;
|
int n;
|
||||||
const char *z = (const char*)fts5MultiIterTerm(pIter, &n);
|
const char *z = (const char*)fts5MultiIterTerm((Fts5Iter*)pIndexIter, &n);
|
||||||
*pn = n-1;
|
*pn = n-1;
|
||||||
return &z[1];
|
return &z[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int fts5IndexExtractColset (
|
|
||||||
Fts5Colset *pColset, /* Colset to filter on */
|
|
||||||
const u8 *pPos, int nPos, /* Position list */
|
|
||||||
Fts5Buffer *pBuf /* Output buffer */
|
|
||||||
){
|
|
||||||
int rc = SQLITE_OK;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
fts5BufferZero(pBuf);
|
|
||||||
for(i=0; i<pColset->nCol; i++){
|
|
||||||
const u8 *pSub = pPos;
|
|
||||||
int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]);
|
|
||||||
if( nSub ){
|
|
||||||
fts5BufferAppendBlob(&rc, pBuf, nSub, pSub);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Return a pointer to a buffer containing a copy of the position list for
|
|
||||||
** the current entry. Output variable *pn is set to the size of the buffer
|
|
||||||
** in bytes before returning.
|
|
||||||
**
|
|
||||||
** The returned position list does not include the "number of bytes" varint
|
|
||||||
** field that starts the position list on disk.
|
|
||||||
*/
|
|
||||||
int sqlite3Fts5IterPoslist(
|
|
||||||
Fts5IndexIter *pIter,
|
|
||||||
Fts5Colset *pColset, /* Column filter (or NULL) */
|
|
||||||
const u8 **pp, /* OUT: Pointer to position-list data */
|
|
||||||
int *pn, /* OUT: Size of position-list in bytes */
|
|
||||||
i64 *piRowid /* OUT: Current rowid */
|
|
||||||
){
|
|
||||||
Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
|
|
||||||
int eDetail = pIter->pIndex->pConfig->eDetail;
|
|
||||||
|
|
||||||
assert( pIter->pIndex->rc==SQLITE_OK );
|
|
||||||
*piRowid = pSeg->iRowid;
|
|
||||||
if( eDetail==FTS5_DETAIL_NONE ){
|
|
||||||
*pn = pSeg->nPos;
|
|
||||||
}else
|
|
||||||
if( eDetail==FTS5_DETAIL_FULL
|
|
||||||
&& pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf
|
|
||||||
){
|
|
||||||
u8 *pPos = &pSeg->pLeaf->p[pSeg->iLeafOffset];
|
|
||||||
if( pColset==0 || pIter->bFiltered ){
|
|
||||||
*pn = pSeg->nPos;
|
|
||||||
*pp = pPos;
|
|
||||||
}else if( pColset->nCol==1 ){
|
|
||||||
*pp = pPos;
|
|
||||||
*pn = fts5IndexExtractCol(pp, pSeg->nPos, pColset->aiCol[0]);
|
|
||||||
}else{
|
|
||||||
fts5BufferZero(&pIter->poslist);
|
|
||||||
fts5IndexExtractColset(pColset, pPos, pSeg->nPos, &pIter->poslist);
|
|
||||||
*pp = pIter->poslist.p;
|
|
||||||
*pn = pIter->poslist.n;
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
fts5BufferZero(&pIter->poslist);
|
|
||||||
fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist);
|
|
||||||
if( eDetail==FTS5_DETAIL_FULL ){
|
|
||||||
*pp = pIter->poslist.p;
|
|
||||||
}
|
|
||||||
*pn = pIter->poslist.n;
|
|
||||||
}
|
|
||||||
return fts5IndexReturn(pIter->pIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sqlite3Fts5IterCollist(
|
|
||||||
Fts5IndexIter *pIter,
|
|
||||||
const u8 **pp, /* OUT: Pointer to position-list data */
|
|
||||||
int *pn /* OUT: Size of position-list in bytes */
|
|
||||||
){
|
|
||||||
assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_COLUMNS );
|
|
||||||
*pp = pIter->poslist.p;
|
|
||||||
*pn = pIter->poslist.n;
|
|
||||||
return SQLITE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** This function is similar to sqlite3Fts5IterPoslist(), except that it
|
|
||||||
** copies the position list into the buffer supplied as the second
|
|
||||||
** argument.
|
|
||||||
*/
|
|
||||||
int sqlite3Fts5IterPoslistBuffer(Fts5IndexIter *pIter, Fts5Buffer *pBuf){
|
|
||||||
Fts5Index *p = pIter->pIndex;
|
|
||||||
Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
|
|
||||||
assert( p->rc==SQLITE_OK );
|
|
||||||
fts5BufferZero(pBuf);
|
|
||||||
fts5SegiterPoslist(p, pSeg, 0, pBuf);
|
|
||||||
return fts5IndexReturn(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery().
|
** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery().
|
||||||
*/
|
*/
|
||||||
void sqlite3Fts5IterClose(Fts5IndexIter *pIter){
|
void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){
|
||||||
if( pIter ){
|
if( pIndexIter ){
|
||||||
|
Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
|
||||||
Fts5Index *pIndex = pIter->pIndex;
|
Fts5Index *pIndex = pIter->pIndex;
|
||||||
fts5MultiIterFree(pIter->pIndex, pIter);
|
fts5MultiIterFree(pIter->pIndex, pIter);
|
||||||
fts5CloseReader(pIndex);
|
fts5CloseReader(pIndex);
|
||||||
@ -5328,35 +5440,30 @@ static int fts5QueryCksum(
|
|||||||
){
|
){
|
||||||
int eDetail = p->pConfig->eDetail;
|
int eDetail = p->pConfig->eDetail;
|
||||||
u64 cksum = *pCksum;
|
u64 cksum = *pCksum;
|
||||||
Fts5IndexIter *pIdxIter = 0;
|
Fts5IndexIter *pIter = 0;
|
||||||
Fts5Buffer buf = {0, 0, 0};
|
int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIter);
|
||||||
int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIdxIter);
|
|
||||||
|
|
||||||
while( rc==SQLITE_OK && 0==sqlite3Fts5IterEof(pIdxIter) ){
|
while( rc==SQLITE_OK && 0==sqlite3Fts5IterEof(pIter) ){
|
||||||
i64 rowid = sqlite3Fts5IterRowid(pIdxIter);
|
i64 rowid = sqlite3Fts5IterRowid(pIter);
|
||||||
|
|
||||||
if( eDetail==FTS5_DETAIL_NONE ){
|
if( eDetail==FTS5_DETAIL_NONE ){
|
||||||
cksum ^= sqlite3Fts5IndexEntryCksum(rowid, 0, 0, iIdx, z, n);
|
cksum ^= sqlite3Fts5IndexEntryCksum(rowid, 0, 0, iIdx, z, n);
|
||||||
}else{
|
}else{
|
||||||
rc = sqlite3Fts5IterPoslistBuffer(pIdxIter, &buf);
|
Fts5PoslistReader sReader;
|
||||||
if( rc==SQLITE_OK ){
|
for(sqlite3Fts5PoslistReaderInit(pIter->pData, pIter->nData, &sReader);
|
||||||
Fts5PoslistReader sReader;
|
sReader.bEof==0;
|
||||||
for(sqlite3Fts5PoslistReaderInit(buf.p, buf.n, &sReader);
|
sqlite3Fts5PoslistReaderNext(&sReader)
|
||||||
sReader.bEof==0;
|
){
|
||||||
sqlite3Fts5PoslistReaderNext(&sReader)
|
int iCol = FTS5_POS2COLUMN(sReader.iPos);
|
||||||
){
|
int iOff = FTS5_POS2OFFSET(sReader.iPos);
|
||||||
int iCol = FTS5_POS2COLUMN(sReader.iPos);
|
cksum ^= sqlite3Fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n);
|
||||||
int iOff = FTS5_POS2OFFSET(sReader.iPos);
|
|
||||||
cksum ^= sqlite3Fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
rc = sqlite3Fts5IterNext(pIdxIter);
|
rc = sqlite3Fts5IterNext(pIter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3Fts5IterClose(pIdxIter);
|
sqlite3Fts5IterClose(pIter);
|
||||||
fts5BufferFree(&buf);
|
|
||||||
|
|
||||||
*pCksum = cksum;
|
*pCksum = cksum;
|
||||||
return rc;
|
return rc;
|
||||||
@ -5661,7 +5768,7 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){
|
|||||||
int eDetail = p->pConfig->eDetail;
|
int eDetail = p->pConfig->eDetail;
|
||||||
u64 cksum2 = 0; /* Checksum based on contents of indexes */
|
u64 cksum2 = 0; /* Checksum based on contents of indexes */
|
||||||
Fts5Buffer poslist = {0,0,0}; /* Buffer used to hold a poslist */
|
Fts5Buffer poslist = {0,0,0}; /* Buffer used to hold a poslist */
|
||||||
Fts5IndexIter *pIter; /* Used to iterate through entire index */
|
Fts5Iter *pIter; /* Used to iterate through entire index */
|
||||||
Fts5Structure *pStruct; /* Index structure */
|
Fts5Structure *pStruct; /* Index structure */
|
||||||
|
|
||||||
#ifdef SQLITE_DEBUG
|
#ifdef SQLITE_DEBUG
|
||||||
|
@ -538,7 +538,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
|
|||||||
for(i=0; i<pInfo->nConstraint; i++){
|
for(i=0; i<pInfo->nConstraint; i++){
|
||||||
struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
|
struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
|
||||||
int j;
|
int j;
|
||||||
for(j=0; j<(int)ArraySize(aConstraint); j++){
|
for(j=0; j<ArraySize(aConstraint); j++){
|
||||||
struct Constraint *pC = &aConstraint[j];
|
struct Constraint *pC = &aConstraint[j];
|
||||||
if( p->iColumn==aColMap[pC->iCol] && p->op & pC->op ){
|
if( p->iColumn==aColMap[pC->iCol] && p->op & pC->op ){
|
||||||
if( p->usable ){
|
if( p->usable ){
|
||||||
@ -585,7 +585,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
|
|||||||
|
|
||||||
/* Assign argvIndex values to each constraint in use. */
|
/* Assign argvIndex values to each constraint in use. */
|
||||||
iNext = 1;
|
iNext = 1;
|
||||||
for(i=0; i<(int)ArraySize(aConstraint); i++){
|
for(i=0; i<ArraySize(aConstraint); i++){
|
||||||
struct Constraint *pC = &aConstraint[i];
|
struct Constraint *pC = &aConstraint[i];
|
||||||
if( pC->iConsIndex>=0 ){
|
if( pC->iConsIndex>=0 ){
|
||||||
pInfo->aConstraintUsage[pC->iConsIndex].argvIndex = iNext++;
|
pInfo->aConstraintUsage[pC->iConsIndex].argvIndex = iNext++;
|
||||||
|
@ -338,7 +338,7 @@ int sqlite3Fts5StorageClose(Fts5Storage *p){
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Finalize all SQL statements */
|
/* Finalize all SQL statements */
|
||||||
for(i=0; i<(int)ArraySize(p->aStmt); i++){
|
for(i=0; i<ArraySize(p->aStmt); i++){
|
||||||
sqlite3_finalize(p->aStmt[i]);
|
sqlite3_finalize(p->aStmt[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1220,7 +1220,7 @@ int sqlite3Fts5TokenizerInit(fts5_api *pApi){
|
|||||||
int rc = SQLITE_OK; /* Return code */
|
int rc = SQLITE_OK; /* Return code */
|
||||||
int i; /* To iterate through builtin functions */
|
int i; /* To iterate through builtin functions */
|
||||||
|
|
||||||
for(i=0; rc==SQLITE_OK && i<(int)ArraySize(aBuiltin); i++){
|
for(i=0; rc==SQLITE_OK && i<ArraySize(aBuiltin); i++){
|
||||||
rc = pApi->xCreateTokenizer(pApi,
|
rc = pApi->xCreateTokenizer(pApi,
|
||||||
aBuiltin[i].zName,
|
aBuiltin[i].zName,
|
||||||
(void*)pApi,
|
(void*)pApi,
|
||||||
|
@ -184,7 +184,7 @@ static int fts5VocabInitVtab(
|
|||||||
|
|
||||||
rc = fts5VocabTableType(zType, pzErr, &eType);
|
rc = fts5VocabTableType(zType, pzErr, &eType);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
assert( eType>=0 && eType<sizeof(azSchema)/sizeof(azSchema[0]) );
|
assert( eType>=0 && eType<ArraySize(azSchema) );
|
||||||
rc = sqlite3_declare_vtab(db, azSchema[eType]);
|
rc = sqlite3_declare_vtab(db, azSchema[eType]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,33 +407,33 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
|
|||||||
|
|
||||||
assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW );
|
assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW );
|
||||||
while( rc==SQLITE_OK ){
|
while( rc==SQLITE_OK ){
|
||||||
i64 dummy;
|
|
||||||
const u8 *pPos; int nPos; /* Position list */
|
const u8 *pPos; int nPos; /* Position list */
|
||||||
i64 iPos = 0; /* 64-bit position read from poslist */
|
i64 iPos = 0; /* 64-bit position read from poslist */
|
||||||
int iOff = 0; /* Current offset within position list */
|
int iOff = 0; /* Current offset within position list */
|
||||||
|
|
||||||
|
pPos = pCsr->pIter->pData;
|
||||||
|
nPos = pCsr->pIter->nData;
|
||||||
switch( pCsr->pConfig->eDetail ){
|
switch( pCsr->pConfig->eDetail ){
|
||||||
case FTS5_DETAIL_FULL:
|
case FTS5_DETAIL_FULL:
|
||||||
rc = sqlite3Fts5IterPoslist(pCsr->pIter, 0, &pPos, &nPos, &dummy);
|
pPos = pCsr->pIter->pData;
|
||||||
if( rc==SQLITE_OK ){
|
nPos = pCsr->pIter->nData;
|
||||||
if( pTab->eType==FTS5_VOCAB_ROW ){
|
if( pTab->eType==FTS5_VOCAB_ROW ){
|
||||||
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
|
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
|
||||||
pCsr->aCnt[0]++;
|
pCsr->aCnt[0]++;
|
||||||
}
|
}
|
||||||
pCsr->aDoc[0]++;
|
pCsr->aDoc[0]++;
|
||||||
}else{
|
}else{
|
||||||
int iCol = -1;
|
int iCol = -1;
|
||||||
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
|
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
|
||||||
int ii = FTS5_POS2COLUMN(iPos);
|
int ii = FTS5_POS2COLUMN(iPos);
|
||||||
pCsr->aCnt[ii]++;
|
pCsr->aCnt[ii]++;
|
||||||
if( iCol!=ii ){
|
if( iCol!=ii ){
|
||||||
if( ii>=nCol ){
|
if( ii>=nCol ){
|
||||||
rc = FTS5_CORRUPT;
|
rc = FTS5_CORRUPT;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
pCsr->aDoc[ii]++;
|
|
||||||
iCol = ii;
|
|
||||||
}
|
}
|
||||||
|
pCsr->aDoc[ii]++;
|
||||||
|
iCol = ii;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -443,19 +443,14 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
|
|||||||
if( pTab->eType==FTS5_VOCAB_ROW ){
|
if( pTab->eType==FTS5_VOCAB_ROW ){
|
||||||
pCsr->aDoc[0]++;
|
pCsr->aDoc[0]++;
|
||||||
}else{
|
}else{
|
||||||
Fts5Buffer buf = {0, 0, 0};
|
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff,&iPos) ){
|
||||||
rc = sqlite3Fts5IterPoslistBuffer(pCsr->pIter, &buf);
|
assert_nc( iPos>=0 && iPos<nCol );
|
||||||
if( rc==SQLITE_OK ){
|
if( iPos>=nCol ){
|
||||||
while( 0==sqlite3Fts5PoslistNext64(buf.p, buf.n, &iOff,&iPos) ){
|
rc = FTS5_CORRUPT;
|
||||||
assert_nc( iPos>=0 && iPos<nCol );
|
break;
|
||||||
if( iPos>=nCol ){
|
|
||||||
rc = FTS5_CORRUPT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pCsr->aDoc[iPos]++;
|
|
||||||
}
|
}
|
||||||
|
pCsr->aDoc[iPos]++;
|
||||||
}
|
}
|
||||||
sqlite3Fts5BufferFree(&buf);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -48,7 +48,8 @@ proc fts5_test_poslist2 {cmd} {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set res
|
#set res
|
||||||
|
sort_poslist $res
|
||||||
}
|
}
|
||||||
|
|
||||||
proc fts5_test_collist {cmd} {
|
proc fts5_test_collist {cmd} {
|
||||||
|
@ -158,8 +158,8 @@ foreach {tn2 sql} {
|
|||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
foreach {tn expr} {
|
foreach {tn expr} {
|
||||||
1.2 "a OR b"
|
|
||||||
1.1 "a AND b"
|
1.1 "a AND b"
|
||||||
|
1.2 "a OR b"
|
||||||
1.3 "o"
|
1.3 "o"
|
||||||
1.4 "b q"
|
1.4 "b q"
|
||||||
1.5 "e a e"
|
1.5 "e a e"
|
||||||
@ -250,7 +250,6 @@ foreach {tn2 sql} {
|
|||||||
FROM xx WHERE xx match $expr
|
FROM xx WHERE xx match $expr
|
||||||
} $res
|
} $res
|
||||||
|
|
||||||
|
|
||||||
set res [fts5_query_data $expr xx DESC]
|
set res [fts5_query_data $expr xx DESC]
|
||||||
do_execsql_test 1.$tn2.$tn.[llength $res].desc {
|
do_execsql_test 1.$tn2.$tn.[llength $res].desc {
|
||||||
SELECT rowid, fts5_test_poslist(xx), fts5_test_collist(xx)
|
SELECT rowid, fts5_test_poslist(xx), fts5_test_collist(xx)
|
||||||
|
44
ext/fts5/test/fts5simple3.test
Normal file
44
ext/fts5/test/fts5simple3.test
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
# 2015 September 05
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
#*************************************************************************
|
||||||
|
#
|
||||||
|
|
||||||
|
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||||
|
set testprefix fts5simple3
|
||||||
|
|
||||||
|
# If SQLITE_ENABLE_FTS5 is defined, omit this file.
|
||||||
|
ifcapable !fts5 {
|
||||||
|
finish_test
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fts5_aux_test_functions db
|
||||||
|
|
||||||
|
do_execsql_test 1.0 {
|
||||||
|
CREATE VIRTUAL TABLE t1 USING fts5(a, b, c, detail=col);
|
||||||
|
INSERT INTO t1 VALUES('a', 'b', 'c');
|
||||||
|
INSERT INTO t1 VALUES('x', 'x', 'x');
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test 1.1 {
|
||||||
|
SELECT rowid, fts5_test_collist(t1) FROM t1('a:a');
|
||||||
|
} {1 0.0}
|
||||||
|
|
||||||
|
do_execsql_test 1.2 {
|
||||||
|
SELECT rowid, fts5_test_collist(t1) FROM t1('b:x');
|
||||||
|
} {2 0.1}
|
||||||
|
|
||||||
|
do_execsql_test 1.3 {
|
||||||
|
SELECT rowid, fts5_test_collist(t1) FROM t1('b:a');
|
||||||
|
} {}
|
||||||
|
|
||||||
|
|
||||||
|
finish_test
|
||||||
|
|
@ -27,6 +27,21 @@ foreach_detail_mode $testprefix {
|
|||||||
fts5_tclnum_register db
|
fts5_tclnum_register db
|
||||||
fts5_aux_test_functions db
|
fts5_aux_test_functions db
|
||||||
|
|
||||||
|
proc fts5_test_bothlist {cmd} {
|
||||||
|
|
||||||
|
for {set i 0} {$i < [$cmd xPhraseCount]} {incr i} {
|
||||||
|
set bFirst 1
|
||||||
|
$cmd xPhraseColumnForeach $i c {
|
||||||
|
lappend CL $i.$c
|
||||||
|
if {$bFirst} { $cmd xPhraseForeach $i c o { lappend PL $i.$c.$o } }
|
||||||
|
set bFirst 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list [sort_poslist $PL] $CL
|
||||||
|
}
|
||||||
|
sqlite3_fts5_create_function db fts5_test_bothlist fts5_test_bothlist
|
||||||
|
|
||||||
proc fts5_rowid {cmd} { expr [$cmd xColumnText -1] }
|
proc fts5_rowid {cmd} { expr [$cmd xColumnText -1] }
|
||||||
sqlite3_fts5_create_function db fts5_rowid fts5_rowid
|
sqlite3_fts5_create_function db fts5_rowid fts5_rowid
|
||||||
|
|
||||||
@ -89,6 +104,8 @@ do_execsql_test 1.$tok.0.2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach {tn expr} {
|
foreach {tn expr} {
|
||||||
|
2.1 "one OR two OR three OR four"
|
||||||
|
|
||||||
1.1 "one" 1.2 "two" 1.3 "three" 1.4 "four"
|
1.1 "one" 1.2 "two" 1.3 "three" 1.4 "four"
|
||||||
1.5 "v" 1.6 "vi" 1.7 "vii" 1.8 "viii"
|
1.5 "v" 1.6 "vi" 1.7 "vii" 1.8 "viii"
|
||||||
1.9 "9" 1.10 "0" 1.11 "1" 1.12 "2"
|
1.9 "9" 1.10 "0" 1.11 "1" 1.12 "2"
|
||||||
@ -113,13 +130,31 @@ foreach {tn expr} {
|
|||||||
|
|
||||||
set res [fts5_query_data $expr ss ASC ::tclnum_syn]
|
set res [fts5_query_data $expr ss ASC ::tclnum_syn]
|
||||||
do_execsql_test 1.$tok.$tn.[llength $res].asc.1 {
|
do_execsql_test 1.$tok.$tn.[llength $res].asc.1 {
|
||||||
SELECT rowid, fts5_test_poslist(ss), fts5_test_collist(ss) FROM ss($expr)
|
SELECT rowid, fts5_test_poslist2(ss), fts5_test_collist(ss) FROM ss($expr)
|
||||||
} $res
|
} $res
|
||||||
|
|
||||||
do_execsql_test 1.$tok.$tn.[llength $res].asc.2 {
|
do_execsql_test 1.$tok.$tn.[llength $res].asc.2 {
|
||||||
SELECT rowid, fts5_test_poslist(ss), fts5_test_collist(ss) FROM ss($expr)
|
SELECT rowid, fts5_test_poslist(ss), fts5_test_collist(ss) FROM ss($expr)
|
||||||
|
} $res
|
||||||
|
|
||||||
|
do_execsql_test 1.$tok.$tn.[llength $res].asc.2 {
|
||||||
|
SELECT rowid, fts5_test_poslist2(ss), fts5_test_collist(ss) FROM ss($expr)
|
||||||
ORDER BY rank ASC
|
ORDER BY rank ASC
|
||||||
} $res
|
} $res
|
||||||
|
|
||||||
|
set res2 [list]
|
||||||
|
foreach {a b c} $res { lappend res2 $a $c $b }
|
||||||
|
do_execsql_test 1.$tok.$tn.[llength $res].asc.3 {
|
||||||
|
SELECT rowid, fts5_test_collist(ss), fts5_test_poslist2(ss) FROM ss($expr)
|
||||||
|
} $res2
|
||||||
|
|
||||||
|
set res3 [list]
|
||||||
|
foreach {a b c} $res { lappend res3 $a [list $b $c] }
|
||||||
|
do_execsql_test 1.$tok.$tn.[llength $res].asc.3 {
|
||||||
|
SELECT rowid, fts5_test_bothlist(ss) FROM ss($expr)
|
||||||
|
} $res3
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@ set Q {
|
|||||||
{1 "SELECT count(*) FROM t1 WHERE t1 MATCH 'c:t*'"}
|
{1 "SELECT count(*) FROM t1 WHERE t1 MATCH 'c:t*'"}
|
||||||
{1 "SELECT count(*) FROM t1 WHERE t1 MATCH 'a:t* OR b:t* OR c:t* OR d:t* OR e:t* OR f:t* OR g:t*'"}
|
{1 "SELECT count(*) FROM t1 WHERE t1 MATCH 'a:t* OR b:t* OR c:t* OR d:t* OR e:t* OR f:t* OR g:t*'"}
|
||||||
{1 "SELECT count(*) FROM t1 WHERE t1 MATCH 'a:t*'"}
|
{1 "SELECT count(*) FROM t1 WHERE t1 MATCH 'a:t*'"}
|
||||||
|
|
||||||
|
{2 "SELECT count(*) FROM t1 WHERE t1 MATCH 'c:the'"}
|
||||||
}
|
}
|
||||||
|
|
||||||
proc usage {} {
|
proc usage {} {
|
||||||
|
@ -1,13 +1,127 @@
|
|||||||
|
|
||||||
|
|
||||||
proc usage {} {
|
#-------------------------------------------------------------------------
|
||||||
puts stderr "$::argv0 ?OPTIONS? DATABASE FILE1..."
|
# Command line options processor.
|
||||||
|
#
|
||||||
|
proc command_line_error {O E {msg ""}} {
|
||||||
|
if {$msg != ""} {
|
||||||
|
puts stderr "Error: $msg"
|
||||||
|
puts stderr ""
|
||||||
|
}
|
||||||
|
|
||||||
|
set L [list]
|
||||||
|
foreach o $O {
|
||||||
|
if {[llength $o]==1} {
|
||||||
|
lappend L [string toupper $o]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
puts stderr "Usage: $::argv0 ?SWITCHES? $L"
|
||||||
puts stderr ""
|
puts stderr ""
|
||||||
puts stderr "Options are"
|
puts stderr "Switches are:"
|
||||||
puts stderr " -fts5"
|
foreach o $O {
|
||||||
puts stderr " -fts4"
|
if {[llength $o]==3} {
|
||||||
puts stderr " -colsize <list of column sizes>"
|
foreach {a b c} $o {}
|
||||||
puts stderr {
|
puts stderr [format " -%-15s %s (default \"%s\")" "$a VAL" $c $b]
|
||||||
|
} elseif {[llength $o]==2} {
|
||||||
|
foreach {a b} $o {}
|
||||||
|
puts stderr [format " -%-15s %s" $a $b]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
puts stderr ""
|
||||||
|
puts stderr $E
|
||||||
|
exit -1
|
||||||
|
}
|
||||||
|
|
||||||
|
proc process_command_line {avar lArgs O E} {
|
||||||
|
|
||||||
|
upvar $avar A
|
||||||
|
set zTrailing "" ;# True if ... is present in $O
|
||||||
|
set lPosargs [list]
|
||||||
|
|
||||||
|
# Populate A() with default values. Also, for each switch in the command
|
||||||
|
# line spec, set an entry in the idx() array as follows:
|
||||||
|
#
|
||||||
|
# {tblname t1 "table name to use"}
|
||||||
|
# -> [set idx(-tblname) {tblname t1 "table name to use"}
|
||||||
|
#
|
||||||
|
# For each position parameter, append its name to $lPosargs. If the ...
|
||||||
|
# specifier is present, set $zTrailing to the name of the prefix.
|
||||||
|
#
|
||||||
|
foreach o $O {
|
||||||
|
set nm [lindex $o 0]
|
||||||
|
set nArg [llength $o]
|
||||||
|
switch -- $nArg {
|
||||||
|
1 {
|
||||||
|
if {[string range $nm end-2 end]=="..."} {
|
||||||
|
set zTrailing [string range $nm 0 end-3]
|
||||||
|
} else {
|
||||||
|
lappend lPosargs $nm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2 {
|
||||||
|
set A($nm) 0
|
||||||
|
set idx(-$nm) $o
|
||||||
|
}
|
||||||
|
3 {
|
||||||
|
set A($nm) [lindex $o 1]
|
||||||
|
set idx(-$nm) $o
|
||||||
|
}
|
||||||
|
default {
|
||||||
|
error "Error in command line specification"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set explicitly specified option values
|
||||||
|
#
|
||||||
|
set nArg [llength $lArgs]
|
||||||
|
for {set i 0} {$i < $nArg} {incr i} {
|
||||||
|
set opt [lindex $lArgs $i]
|
||||||
|
if {[string range $opt 0 0]!="-" || $opt=="--"} break
|
||||||
|
set c [array names idx "${opt}*"]
|
||||||
|
if {[llength $c]==0} { command_line_error $O $E "Unrecognized option: $opt"}
|
||||||
|
if {[llength $c]>1} { command_line_error $O $E "Ambiguous option: $opt"}
|
||||||
|
|
||||||
|
if {[llength $idx($c)]==3} {
|
||||||
|
if {$i==[llength $lArgs]-1} {
|
||||||
|
command_line_error $O $E "Option requires argument: $c"
|
||||||
|
}
|
||||||
|
incr i
|
||||||
|
set A([lindex $idx($c) 0]) [lindex $lArgs $i]
|
||||||
|
} else {
|
||||||
|
set A([lindex $idx($c) 0]) 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Deal with position arguments.
|
||||||
|
#
|
||||||
|
set nPosarg [llength $lPosargs]
|
||||||
|
set nRem [expr $nArg - $i]
|
||||||
|
if {$nRem < $nPosarg || ($zTrailing=="" && $nRem > $nPosarg)} {
|
||||||
|
command_line_error $O $E
|
||||||
|
}
|
||||||
|
for {set j 0} {$j < $nPosarg} {incr j} {
|
||||||
|
set A([lindex $lPosargs $j]) [lindex $lArgs [expr $j+$i]]
|
||||||
|
}
|
||||||
|
if {$zTrailing!=""} {
|
||||||
|
set A($zTrailing) [lrange $lArgs [expr $j+$i] end]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# End of command line options processor.
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
process_command_line A $argv {
|
||||||
|
{fts5 "use fts5"}
|
||||||
|
{fts4 "use fts4"}
|
||||||
|
{colsize "10 10 10" "list of column sizes"}
|
||||||
|
{tblname "t1" "table name to create"}
|
||||||
|
{detail "full" "Fts5 detail mode to use"}
|
||||||
|
{repeat 1 "Load each file this many times"}
|
||||||
|
database
|
||||||
|
file...
|
||||||
|
} {
|
||||||
This script is designed to create fts4/5 tables with more than one column.
|
This script is designed to create fts4/5 tables with more than one column.
|
||||||
The -colsize option should be set to a Tcl list of integer values, one for
|
The -colsize option should be set to a Tcl list of integer values, one for
|
||||||
each column in the table. Each value is the number of tokens that will be
|
each column in the table. Each value is the number of tokens that will be
|
||||||
@ -22,59 +136,27 @@ of the -colsize list. The next N2 are used for the second column of the first
|
|||||||
row, and so on. Rows are added to the table until the entire list of tokens
|
row, and so on. Rows are added to the table until the entire list of tokens
|
||||||
is exhausted.
|
is exhausted.
|
||||||
}
|
}
|
||||||
exit -1
|
|
||||||
|
if {$A(fts4)} {
|
||||||
|
set A(fts) fts4
|
||||||
|
} else {
|
||||||
|
set A(fts) fts5
|
||||||
}
|
}
|
||||||
|
|
||||||
set O(aColSize) [list 10 10 10]
|
sqlite3 db $A(database)
|
||||||
set O(tblname) t1
|
|
||||||
set O(fts) fts5
|
|
||||||
|
|
||||||
|
|
||||||
set options_with_values {-colsize}
|
|
||||||
|
|
||||||
for {set i 0} {$i < [llength $argv]} {incr i} {
|
|
||||||
set opt [lindex $argv $i]
|
|
||||||
if {[string range $opt 0 0]!="-"} break
|
|
||||||
|
|
||||||
if {[lsearch $options_with_values $opt]>=0} {
|
|
||||||
incr i
|
|
||||||
if {$i==[llength $argv]} usage
|
|
||||||
set val [lindex $argv $i]
|
|
||||||
}
|
|
||||||
|
|
||||||
switch -- $opt {
|
|
||||||
-colsize {
|
|
||||||
set O(aColSize) $val
|
|
||||||
}
|
|
||||||
|
|
||||||
-fts4 {
|
|
||||||
set O(fts) fts4
|
|
||||||
}
|
|
||||||
|
|
||||||
-fts5 {
|
|
||||||
set O(fts) fts5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if {$i > [llength $argv]-2} usage
|
|
||||||
set O(db) [lindex $argv $i]
|
|
||||||
set O(files) [lrange $argv [expr $i+1] end]
|
|
||||||
|
|
||||||
sqlite3 db $O(db)
|
|
||||||
|
|
||||||
# Create the FTS table in the db. Return a list of the table columns.
|
# Create the FTS table in the db. Return a list of the table columns.
|
||||||
#
|
#
|
||||||
proc create_table {} {
|
proc create_table {} {
|
||||||
global O
|
global A
|
||||||
set cols [list a b c d e f g h i j k l m n o p q r s t u v w x y z]
|
set cols [list a b c d e f g h i j k l m n o p q r s t u v w x y z]
|
||||||
|
|
||||||
set nCol [llength $O(aColSize)]
|
set nCol [llength $A(colsize)]
|
||||||
set cols [lrange $cols 0 [expr $nCol-1]]
|
set cols [lrange $cols 0 [expr $nCol-1]]
|
||||||
|
|
||||||
set sql "CREATE VIRTUAL TABLE IF NOT EXISTS $O(tblname) USING $O(fts) ("
|
set sql "CREATE VIRTUAL TABLE IF NOT EXISTS $A(tblname) USING $A(fts) ("
|
||||||
append sql [join $cols ,]
|
append sql [join $cols ,]
|
||||||
append sql ");"
|
if {$A(fts)=="fts5"} { append sql ",detail=$A(detail));" }
|
||||||
|
|
||||||
db eval $sql
|
db eval $sql
|
||||||
return $cols
|
return $cols
|
||||||
@ -89,27 +171,35 @@ proc readfile {file} {
|
|||||||
split $data
|
split $data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc repeat {L n} {
|
||||||
|
set res [list]
|
||||||
|
for {set i 0} {$i < $n} {incr i} {
|
||||||
|
set res [concat $res $L]
|
||||||
|
}
|
||||||
|
set res
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# Load all the data into a big list of tokens.
|
# Load all the data into a big list of tokens.
|
||||||
#
|
#
|
||||||
set tokens [list]
|
set tokens [list]
|
||||||
foreach f $O(files) {
|
foreach f $A(file) {
|
||||||
set tokens [concat $tokens [readfile $f]]
|
set tokens [concat $tokens [repeat [readfile $f] $A(repeat)]]
|
||||||
}
|
}
|
||||||
|
|
||||||
set N [llength $tokens]
|
set N [llength $tokens]
|
||||||
set i 0
|
set i 0
|
||||||
set cols [create_table]
|
set cols [create_table]
|
||||||
set sql "INSERT INTO $O(tblname) VALUES(\$[lindex $cols 0]"
|
set sql "INSERT INTO $A(tblname) VALUES(\$R([lindex $cols 0])"
|
||||||
foreach c [lrange $cols 1 end] {
|
foreach c [lrange $cols 1 end] {
|
||||||
append sql ", \$A($c)"
|
append sql ", \$R($c)"
|
||||||
}
|
}
|
||||||
append sql ")"
|
append sql ")"
|
||||||
|
|
||||||
db eval BEGIN
|
db eval BEGIN
|
||||||
while {$i < $N} {
|
while {$i < $N} {
|
||||||
foreach c $cols s $O(aColSize) {
|
foreach c $cols s $A(colsize) {
|
||||||
set A($c) [lrange $tokens $i [expr $i+$s-1]]
|
set R($c) [lrange $tokens $i [expr $i+$s-1]]
|
||||||
incr i $s
|
incr i $s
|
||||||
}
|
}
|
||||||
db eval $sql
|
db eval $sql
|
||||||
|
@ -365,8 +365,8 @@ static int editdist1(const char *zA, const char *zB, int *pnMatch){
|
|||||||
int *m; /* The cost matrix */
|
int *m; /* The cost matrix */
|
||||||
char *cx; /* Corresponding character values */
|
char *cx; /* Corresponding character values */
|
||||||
int *toFree = 0; /* Malloced space */
|
int *toFree = 0; /* Malloced space */
|
||||||
int mStack[60+15]; /* Stack space to use if not too much is needed */
|
|
||||||
int nMatch = 0;
|
int nMatch = 0;
|
||||||
|
int mStack[60+15]; /* Stack space to use if not too much is needed */
|
||||||
|
|
||||||
/* Early out if either input is NULL */
|
/* Early out if either input is NULL */
|
||||||
if( zA==0 || zB==0 ) return -1;
|
if( zA==0 || zB==0 ) return -1;
|
||||||
@ -875,6 +875,17 @@ static void updateCost(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** How much stack space (int bytes) to use for Wagner matrix in
|
||||||
|
** editDist3Core(). If more space than this is required, the entire
|
||||||
|
** matrix is taken from the heap. To reduce the load on the memory
|
||||||
|
** allocator, make this value as large as practical for the
|
||||||
|
** architecture in use.
|
||||||
|
*/
|
||||||
|
#ifndef SQLITE_SPELLFIX_STACKALLOC_SZ
|
||||||
|
# define SQLITE_SPELLFIX_STACKALLOC_SZ (1024)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Compute the edit distance between two strings.
|
/* Compute the edit distance between two strings.
|
||||||
**
|
**
|
||||||
** If an error occurs, return a negative number which is the error code.
|
** If an error occurs, return a negative number which is the error code.
|
||||||
@ -899,15 +910,24 @@ static int editDist3Core(
|
|||||||
EditDist3FromString f = *pFrom;
|
EditDist3FromString f = *pFrom;
|
||||||
EditDist3To *a2;
|
EditDist3To *a2;
|
||||||
unsigned int *m;
|
unsigned int *m;
|
||||||
|
unsigned int *pToFree;
|
||||||
int szRow;
|
int szRow;
|
||||||
EditDist3Cost *p;
|
EditDist3Cost *p;
|
||||||
int res;
|
int res;
|
||||||
|
sqlite3_uint64 nByte;
|
||||||
|
unsigned int stackSpace[SQLITE_SPELLFIX_STACKALLOC_SZ/sizeof(unsigned int)];
|
||||||
|
|
||||||
/* allocate the Wagner matrix and the aTo[] array for the TO string */
|
/* allocate the Wagner matrix and the aTo[] array for the TO string */
|
||||||
n = (f.n+1)*(n2+1);
|
n = (f.n+1)*(n2+1);
|
||||||
n = (n+1)&~1;
|
n = (n+1)&~1;
|
||||||
m = sqlite3_malloc( n*sizeof(m[0]) + sizeof(a2[0])*n2 );
|
nByte = n*sizeof(m[0]) + sizeof(a2[0])*n2;
|
||||||
if( m==0 ) return -1; /* Out of memory */
|
if( nByte<=sizeof(stackSpace) ){
|
||||||
|
m = stackSpace;
|
||||||
|
pToFree = 0;
|
||||||
|
}else{
|
||||||
|
m = pToFree = sqlite3_malloc( nByte );
|
||||||
|
if( m==0 ) return -1; /* Out of memory */
|
||||||
|
}
|
||||||
a2 = (EditDist3To*)&m[n];
|
a2 = (EditDist3To*)&m[n];
|
||||||
memset(a2, 0, sizeof(a2[0])*n2);
|
memset(a2, 0, sizeof(a2[0])*n2);
|
||||||
|
|
||||||
@ -1029,7 +1049,7 @@ static int editDist3Core(
|
|||||||
|
|
||||||
editDist3Abort:
|
editDist3Abort:
|
||||||
for(i2=0; i2<n2; i2++) sqlite3_free(a2[i2].apIns);
|
for(i2=0; i2<n2; i2++) sqlite3_free(a2[i2].apIns);
|
||||||
sqlite3_free(m);
|
sqlite3_free(pToFree);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
100
manifest
100
manifest
@ -1,8 +1,8 @@
|
|||||||
C Add\sa\snew\shint\sbit\son\sthe\sflags\sparameter\sof\ssqlite3BtreeDelete().\s\sThe\snew\nBTREE_IDXDELETE\sbit\sindicates\sthat\sthe\scall\sis\sto\sdelete\san\sindex\sentry\s\ncorresponding\sto\sa\stable\srow\sthat\shas\salready\sbeen\sdeleted.
|
C Merge\sall\srecent\strunk\senhancements.
|
||||||
D 2016-01-21T17:06:33.267
|
D 2016-01-26T23:32:55.750
|
||||||
F Makefile.in 7be88f5b473891e3a8c07245ed60535fcda4f9ee
|
F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4
|
||||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||||
F Makefile.msc c5ead4aa22ff6f528c755b07ed1e31184ac5b3d2
|
F Makefile.msc 6fca5455aaecbd14479f33f091aa19df2d3d2969
|
||||||
F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7
|
F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7
|
||||||
F VERSION 866588d1edf0ccb5b0d33896974338f97564f719
|
F VERSION 866588d1edf0ccb5b0d33896974338f97564f719
|
||||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||||
@ -10,9 +10,10 @@ F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
|
|||||||
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
|
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
|
||||||
F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
|
F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
|
||||||
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
|
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
|
||||||
F autoconf/Makefile.am 089e5ecdb5761e64ea1013ded02feb4d8b29927d
|
F autoconf/Makefile.am 1c1657650775960804945dc392e14d9e43c5ed84
|
||||||
F autoconf/README 14458f1046c118efa721aadec5f227e876d3cd38
|
F autoconf/Makefile.msc 68ed752a809b611d97b95d8572a34fe6fd1196f1
|
||||||
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
|
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
|
||||||
|
F autoconf/README.txt e9757a381e5ce2553dbaa6247bb8ad00eb8d87aa w autoconf/README
|
||||||
F autoconf/configure.ac 7b1ea0dcaf49fafba262ce4b0ee8cb3281b555d1
|
F autoconf/configure.ac 7b1ea0dcaf49fafba262ce4b0ee8cb3281b555d1
|
||||||
F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd
|
F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd
|
||||||
F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873
|
F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873
|
||||||
@ -97,28 +98,28 @@ F ext/fts3/unicode/mkunicode.tcl 95cf7ec186e48d4985e433ff8a1c89090a774252
|
|||||||
F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95
|
F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95
|
||||||
F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
|
F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
|
||||||
F ext/fts5/fts5.h ff9c2782e8ed890b0de2f697a8d63971939e70c7
|
F ext/fts5/fts5.h ff9c2782e8ed890b0de2f697a8d63971939e70c7
|
||||||
F ext/fts5/fts5Int.h 5599703af9c13512900a9f22fec39d48078d619d
|
F ext/fts5/fts5Int.h 6e0f90eb4872654a5b98130dec16965716525c9a
|
||||||
F ext/fts5/fts5_aux.c 2dafc3aee0c70d643140c77d8d70daffa51a9e9e
|
F ext/fts5/fts5_aux.c b9bcce753ef5b451267b2232f0ca153ddeb3951d
|
||||||
F ext/fts5/fts5_buffer.c 7d3f6f01f8fdc45204e6a33925ef8478a67d28dd
|
F ext/fts5/fts5_buffer.c f6e0c6018ffc8e39fc0b333b5daa8b8d528ae6e4
|
||||||
F ext/fts5/fts5_config.c 0c384ebdd23fd055e2e50a93277b8d59da538238
|
F ext/fts5/fts5_config.c 0c384ebdd23fd055e2e50a93277b8d59da538238
|
||||||
F ext/fts5/fts5_expr.c 4ab4504c54bbe24689c83411d8588f4ec99136e9
|
F ext/fts5/fts5_expr.c a66b9694519d9c336d9bdbd46ea22e7e14aef412
|
||||||
F ext/fts5/fts5_hash.c 1b113977296cf4212c6ec667d5e3f2bd18036955
|
F ext/fts5/fts5_hash.c 1b113977296cf4212c6ec667d5e3f2bd18036955
|
||||||
F ext/fts5/fts5_index.c 716c301835a122ba36910b4f821c87d26ae9a5d9
|
F ext/fts5/fts5_index.c 5558bfbeaf364cc67f937e25753ceed8757cb6d1
|
||||||
F ext/fts5/fts5_main.c 833db0a3df10ab26e0221a9baa40cf871c450df3
|
F ext/fts5/fts5_main.c 3886bbfc5ac1d9df29979823ddf2b68241e1127e
|
||||||
F ext/fts5/fts5_storage.c fb2eaec3aa954b680d43096dc539f8270bd6390e
|
F ext/fts5/fts5_storage.c 2a1f44deae090cd711f02cec0c2af8e660360d24
|
||||||
F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966
|
F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966
|
||||||
F ext/fts5/fts5_test_mi.c 1ec66ffdf7632077fbd773b7a6df5153272ec070
|
F ext/fts5/fts5_test_mi.c 1ec66ffdf7632077fbd773b7a6df5153272ec070
|
||||||
F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be
|
F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be
|
||||||
F ext/fts5/fts5_tokenize.c 504984ac6993323247221eebe3cd55bead01b5f8
|
F ext/fts5/fts5_tokenize.c 4d5c4f183c7d07d144bc219b92da1ea0e962fae3
|
||||||
F ext/fts5/fts5_unicode2.c 78273fbd588d1d9bd0a7e4e0ccc9207348bae33c
|
F ext/fts5/fts5_unicode2.c 78273fbd588d1d9bd0a7e4e0ccc9207348bae33c
|
||||||
F ext/fts5/fts5_varint.c 3f86ce09cab152e3d45490d7586b7ed2e40c13f1
|
F ext/fts5/fts5_varint.c 3f86ce09cab152e3d45490d7586b7ed2e40c13f1
|
||||||
F ext/fts5/fts5_vocab.c ee6df1a3be103414d7b7af833ae1885c7b83a9d0
|
F ext/fts5/fts5_vocab.c 3ef401a8d6932db56368de32f446eb9fe73aa623
|
||||||
F ext/fts5/fts5parse.y 1647eba089b9b3fc058b4dc989d9da87d15b9580
|
F ext/fts5/fts5parse.y 1647eba089b9b3fc058b4dc989d9da87d15b9580
|
||||||
F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba
|
F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba
|
||||||
F ext/fts5/test/fts5_common.tcl 6d0d74b695c4be055a8ba1dd807f22a2abc95b5e
|
F ext/fts5/test/fts5_common.tcl 61ff0d1a29d98a91c4553b20b3f410d858834ee9
|
||||||
F ext/fts5/test/fts5aa.test 7e814df4a0e6c22a6fe2d84f210fdc0b5068a084
|
F ext/fts5/test/fts5aa.test 7e814df4a0e6c22a6fe2d84f210fdc0b5068a084
|
||||||
F ext/fts5/test/fts5ab.test 30325a89453280160106be411bba3acf138e6d1b
|
F ext/fts5/test/fts5ab.test 30325a89453280160106be411bba3acf138e6d1b
|
||||||
F ext/fts5/test/fts5ac.test d5073ca7bd2d9fe8aab0c82c6c75a7e4b0d70ced
|
F ext/fts5/test/fts5ac.test 55cad4275a1f5acabfe14d8442a8046b47e49e5f
|
||||||
F ext/fts5/test/fts5ad.test 0ddaa5b692ff220100ee396228838f4331399eaa
|
F ext/fts5/test/fts5ad.test 0ddaa5b692ff220100ee396228838f4331399eaa
|
||||||
F ext/fts5/test/fts5ae.test 612dcb51f4069226791ff14c17dbfb3138c56f20
|
F ext/fts5/test/fts5ae.test 612dcb51f4069226791ff14c17dbfb3138c56f20
|
||||||
F ext/fts5/test/fts5af.test be858a96b1f5de66ba6d64f0021bd8b2408e126c
|
F ext/fts5/test/fts5af.test be858a96b1f5de66ba6d64f0021bd8b2408e126c
|
||||||
@ -176,8 +177,9 @@ F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17
|
|||||||
F ext/fts5/test/fts5rowid.test 16908a99d6efc9ba21081b4f2b86b3fc699839a6
|
F ext/fts5/test/fts5rowid.test 16908a99d6efc9ba21081b4f2b86b3fc699839a6
|
||||||
F ext/fts5/test/fts5simple.test 2bc6451cbe887a9215f5b14ae307c70d850344c9
|
F ext/fts5/test/fts5simple.test 2bc6451cbe887a9215f5b14ae307c70d850344c9
|
||||||
F ext/fts5/test/fts5simple2.test 98377ae1ff7749a42c21fe1a139c1ed312522c46
|
F ext/fts5/test/fts5simple2.test 98377ae1ff7749a42c21fe1a139c1ed312522c46
|
||||||
|
F ext/fts5/test/fts5simple3.test e671b36bc4dbd4f5095e66cb04473cba9f680f53
|
||||||
F ext/fts5/test/fts5synonym.test 6475d189c2e20d60795808f83e36bf9318708d48
|
F ext/fts5/test/fts5synonym.test 6475d189c2e20d60795808f83e36bf9318708d48
|
||||||
F ext/fts5/test/fts5synonym2.test eadb00c73ef0653258873e756b7e9102e0687539
|
F ext/fts5/test/fts5synonym2.test aa4c43bd3b691ff80f658cb064f5ab40690e834e
|
||||||
F ext/fts5/test/fts5tok1.test beb894c6f3468f10a574302f69ebe4436b0287c7
|
F ext/fts5/test/fts5tok1.test beb894c6f3468f10a574302f69ebe4436b0287c7
|
||||||
F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2
|
F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2
|
||||||
F ext/fts5/test/fts5tokenizer.test ea4df698b35cc427ebf2ba22829d0e28386d8c89
|
F ext/fts5/test/fts5tokenizer.test ea4df698b35cc427ebf2ba22829d0e28386d8c89
|
||||||
@ -188,8 +190,8 @@ F ext/fts5/test/fts5unindexed.test e9539d5b78c677315e7ed8ea911d4fd25437c680
|
|||||||
F ext/fts5/test/fts5update.test 57c7012a7919889048947addae10e0613df45529
|
F ext/fts5/test/fts5update.test 57c7012a7919889048947addae10e0613df45529
|
||||||
F ext/fts5/test/fts5version.test 978f59541d8cef7e8591f8be2115ec5ccb863e2e
|
F ext/fts5/test/fts5version.test 978f59541d8cef7e8591f8be2115ec5ccb863e2e
|
||||||
F ext/fts5/test/fts5vocab.test 480d780aa6b699816c5066225fbd86f3a0239477
|
F ext/fts5/test/fts5vocab.test 480d780aa6b699816c5066225fbd86f3a0239477
|
||||||
F ext/fts5/tool/fts5speed.tcl aaee41894b552df8fbf8616aad003b2ea9ba3221
|
F ext/fts5/tool/fts5speed.tcl 47f0031e6ac564964f4f4805e439ea665e848df2
|
||||||
F ext/fts5/tool/fts5txt2db.tcl c374c4c4797e8cdfadabdfaeeb5412dcd6686e84
|
F ext/fts5/tool/fts5txt2db.tcl ae308338b2da1646dea456ab66706acdde8c714e
|
||||||
F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093
|
F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093
|
||||||
F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45
|
F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45
|
||||||
F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c
|
F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c
|
||||||
@ -210,7 +212,7 @@ F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
|
|||||||
F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
|
F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
|
||||||
F ext/misc/series.c b8fb7befd85b3a9b4a10e701b30b2b79ca92b6d4
|
F ext/misc/series.c b8fb7befd85b3a9b4a10e701b30b2b79ca92b6d4
|
||||||
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
|
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
|
||||||
F ext/misc/spellfix.c df6efb90eb668d1860c9b59e4320e985e46dffa7
|
F ext/misc/spellfix.c db4cc4b7aa12384e6c19a289a39cd232d355413d
|
||||||
F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
|
F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
|
||||||
F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
|
F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
|
||||||
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
|
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
|
||||||
@ -291,16 +293,16 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73
|
|||||||
F src/btree.c 97cf881292e085ee71faf44f7167b6312965b562
|
F src/btree.c 97cf881292e085ee71faf44f7167b6312965b562
|
||||||
F src/btree.h c5dfbbc59226fa5fcc2b03befa85fe10ef23c1b5
|
F src/btree.h c5dfbbc59226fa5fcc2b03befa85fe10ef23c1b5
|
||||||
F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5
|
F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5
|
||||||
F src/build.c 31af80bba31ac159967951ef58f3144cc7db9d70
|
F src/build.c b4eba1e84752ec9cae7ff3dacd5a8b6d1ab8deb9
|
||||||
F src/callback.c 29ae4faba226c7ebb9aee93016b5ce8a8f071261
|
F src/callback.c 29ae4faba226c7ebb9aee93016b5ce8a8f071261
|
||||||
F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
|
F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
|
||||||
F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198
|
F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198
|
||||||
F src/date.c 997651e3ee6c2818fbf7fcdb7156cef9eb3ece20
|
F src/date.c 997651e3ee6c2818fbf7fcdb7156cef9eb3ece20
|
||||||
F src/dbstat.c ffd63fc8ba7541476ced189b95e95d7f2bc63f78
|
F src/dbstat.c b2ec6793eef97aebb4d171d490a4ffdfa9f2475c
|
||||||
F src/delete.c f02e46234c5fc86f6c03ae34dc0ba48e93cd5029
|
F src/delete.c f02e46234c5fc86f6c03ae34dc0ba48e93cd5029
|
||||||
F src/expr.c df0d7c3230d59abd679da22ff5ce4cfd0e3a0e63
|
F src/expr.c d10c1cdef5810cdbf73adc9f9b383684230b360a
|
||||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||||
F src/fkey.c e18b3dff7d47c7bcac5ac4fc178a89b9fd322b44
|
F src/fkey.c c66d3e5b35d4d95b5c1e2ee6c12f5df13a7f9ad6
|
||||||
F src/func.c ba6c03f9e440f5693086c08ee88e6e60212b3504
|
F src/func.c ba6c03f9e440f5693086c08ee88e6e60212b3504
|
||||||
F src/global.c bd5a0af3f30b0c01be6db756c626cd3c33a3d260
|
F src/global.c bd5a0af3f30b0c01be6db756c626cd3c33a3d260
|
||||||
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
|
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
|
||||||
@ -316,7 +318,7 @@ F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
|||||||
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
|
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
|
||||||
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
|
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
|
||||||
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
|
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
|
||||||
F src/mem5.c 71f81a11fc5e29a57428761ab38a7bf2ef4ee19d
|
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
|
||||||
F src/memjournal.c 3eb2c0b51adbd869cb6a44780323f05fa904dc85
|
F src/memjournal.c 3eb2c0b51adbd869cb6a44780323f05fa904dc85
|
||||||
F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495
|
F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495
|
||||||
F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c
|
F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c
|
||||||
@ -329,10 +331,10 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8
|
|||||||
F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf
|
F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf
|
||||||
F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e
|
F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e
|
||||||
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
||||||
F src/os_unix.c b509b49b40a269e7b75ab511b6e92b2dc9444359
|
F src/os_unix.c 5bb20172d0c9a6afcfa829a88c406970593c848d
|
||||||
F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811
|
F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811
|
||||||
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
||||||
F src/pager.c f4e9ac39fbb1e0fde97af85c0f4e00eb90764b67
|
F src/pager.c 2916c66aee50f69d9ec56a7619b62d9c6a3bee61
|
||||||
F src/pager.h 1c2a49143dfba9e69cc8159ef019f472ed8d260b
|
F src/pager.h 1c2a49143dfba9e69cc8159ef019f472ed8d260b
|
||||||
F src/parse.y caad1e98edeca6960493d0c60d31b76820dd7776
|
F src/parse.y caad1e98edeca6960493d0c60d31b76820dd7776
|
||||||
F src/pcache.c 73895411fa6b7bd6f0091212feabbe833b358d23
|
F src/pcache.c 73895411fa6b7bd6f0091212feabbe833b358d23
|
||||||
@ -340,21 +342,21 @@ F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545
|
|||||||
F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051
|
F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051
|
||||||
F src/pragma.c ea290193369faa0a26ae2f924e7b86289b4a7987
|
F src/pragma.c ea290193369faa0a26ae2f924e7b86289b4a7987
|
||||||
F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c
|
F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c
|
||||||
F src/prepare.c 74855ddbdfad6a1c4a4d5c4b0913ebb01174ba19
|
F src/prepare.c 8ca7237428f372a04717d558555ea67ee1c5df93
|
||||||
F src/printf.c af589a27b7d40f6f4f704e9eea99f02f18ad6d32
|
F src/printf.c af589a27b7d40f6f4f704e9eea99f02f18ad6d32
|
||||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||||
F src/resolve.c 9f7ce3a3c087afb7597b7c916c99126ff3f12f0c
|
F src/resolve.c 9f7ce3a3c087afb7597b7c916c99126ff3f12f0c
|
||||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||||
F src/select.c 718954db86277d696c520fe671148db1e9c4ed3c
|
F src/select.c c34292c8ce7fe69c7cf890d933834a22572bd301
|
||||||
F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4
|
F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4
|
||||||
F src/sqlite.h.in 214476a62012e578f42133a9a3b4f97a9aa421a3
|
F src/sqlite.h.in 214476a62012e578f42133a9a3b4f97a9aa421a3
|
||||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||||
F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d
|
F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d
|
||||||
F src/sqliteInt.h 46e0bac7a3cdab96e8b5afd1436accc25d2c3d6a
|
F src/sqliteInt.h 0faffdeed20201bedb202cf6ec07f14b29158c66
|
||||||
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
|
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
|
||||||
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
|
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
|
||||||
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
|
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
|
||||||
F src/tclsqlite.c 82979239a896992f9b78efec81cfda05d316a7d0
|
F src/tclsqlite.c 94ef6e2794220c5b6064d4c78ec7169a8c5cc45d
|
||||||
F src/test1.c 4f1b42699068b7806af3111786f5ad760c2c1ff7
|
F src/test1.c 4f1b42699068b7806af3111786f5ad760c2c1ff7
|
||||||
F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b
|
F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b
|
||||||
F src/test3.c a8887dabbbee3059af338f20d290084a63ed1b0f
|
F src/test3.c a8887dabbbee3059af338f20d290084a63ed1b0f
|
||||||
@ -405,22 +407,22 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
|||||||
F src/threads.c bbfb74450643cb5372a43ad4f6cffd7e9dfcecb0
|
F src/threads.c bbfb74450643cb5372a43ad4f6cffd7e9dfcecb0
|
||||||
F src/tokenize.c 5606871a377f390af7040ec3c12e0d183512d785
|
F src/tokenize.c 5606871a377f390af7040ec3c12e0d183512d785
|
||||||
F src/treeview.c 78842e90c1f71269e7a73a1d4221b6fe360bab66
|
F src/treeview.c 78842e90c1f71269e7a73a1d4221b6fe360bab66
|
||||||
F src/trigger.c 056e51182a3677434423e3be0c74e61b90b4a663
|
F src/trigger.c 72d876b2d0c66604a112362bdae07dae9b104816
|
||||||
F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3
|
F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3
|
||||||
F src/utf.c 32d7f82aa921322f3e1c956f4b58f019ebd2c6b3
|
F src/utf.c 32d7f82aa921322f3e1c956f4b58f019ebd2c6b3
|
||||||
F src/util.c e802e8e311a0d6c48cd1b3e89db164f6f0248d70
|
F src/util.c 72d40df0a52d3f30b462a15f0e094fcbade6dc82
|
||||||
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
|
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
|
||||||
F src/vdbe.c e21a506d17a7397cba16c162d8c9c96e9769c68e
|
F src/vdbe.c 6039096edea4ed25f7b1e28aa5d46b0ee3ba73ef
|
||||||
F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337
|
F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337
|
||||||
F src/vdbeInt.h 42eefa4f9e7432b9968d321b44e48821ec13b189
|
F src/vdbeInt.h 42eefa4f9e7432b9968d321b44e48821ec13b189
|
||||||
F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e
|
F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e
|
||||||
F src/vdbeaux.c 07f8f485a6cbc0a62da660f14e303061d45d5cb6
|
F src/vdbeaux.c 757f86e6fef8efb3dd4226cb31e2e82b9c44c883
|
||||||
F src/vdbeblob.c 37c3d11a753e403698c69e17383d282e1ae73e75
|
F src/vdbeblob.c 37c3d11a753e403698c69e17383d282e1ae73e75
|
||||||
F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0
|
F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0
|
||||||
F src/vdbesort.c 0971557e5d3c289e46f56a52aed2197c13251de7
|
F src/vdbesort.c 3bb1f1f03162e6d223da623714d8e93fcaeac658
|
||||||
F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0
|
F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0
|
||||||
F src/vtab.c 320682cca733115b4cbe71320b5c5eeb1074ebde
|
F src/vtab.c 320682cca733115b4cbe71320b5c5eeb1074ebde
|
||||||
F src/vxworks.h 974e7d9a98f602d6310d563e1dc4e08f9fc48e47
|
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||||
F src/wal.c d21b99fd1458159d0b1ecdccc8ee6ada4fdc4c54
|
F src/wal.c d21b99fd1458159d0b1ecdccc8ee6ada4fdc4c54
|
||||||
F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c
|
F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c
|
||||||
F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354
|
F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354
|
||||||
@ -924,7 +926,7 @@ F test/orderby6.test 8b38138ab0972588240b3fca0985d2e400432859
|
|||||||
F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da
|
F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da
|
||||||
F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd
|
F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd
|
||||||
F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3
|
F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3
|
||||||
F test/oserror.test 361346396ae18462c7393c1ac5c3f17237bd89b2
|
F test/oserror.test b32dc34f2363ef18532e3a0a7358e3e7e321974f
|
||||||
F test/ovfl.test 4f7ca651cba5c059a12d8c67dddd49bec5747799
|
F test/ovfl.test 4f7ca651cba5c059a12d8c67dddd49bec5747799
|
||||||
F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa
|
F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa
|
||||||
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
|
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
|
||||||
@ -1052,7 +1054,7 @@ F test/spellfix3.test f7bf7b3482971473d32b6b00f6944c5c066cff97
|
|||||||
F test/sqldiff1.test 8f6bc7c6a5b3585d350d779c6078869ba402f8f5
|
F test/sqldiff1.test 8f6bc7c6a5b3585d350d779c6078869ba402f8f5
|
||||||
F test/sqllimits1.test a74ee2a3740b9f9c2437c246d8fb77354862a142
|
F test/sqllimits1.test a74ee2a3740b9f9c2437c246d8fb77354862a142
|
||||||
F test/sqllog.test a8faa2df39610a037dd372ed872d124260d32953
|
F test/sqllog.test a8faa2df39610a037dd372ed872d124260d32953
|
||||||
F test/stat.test 8de91498c99f5298b303f70f1d1f3b9557af91bf
|
F test/stat.test fafe6e82dfdb97d8c8be31cd83e36e973079ce0f
|
||||||
F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1
|
F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1
|
||||||
F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
|
F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
|
||||||
F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f
|
F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f
|
||||||
@ -1061,9 +1063,9 @@ F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
|
|||||||
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
|
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
|
||||||
F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8
|
F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8
|
||||||
F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2
|
F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2
|
||||||
F test/symlink.test cbf6cb8c6c4b63a39e9f0f6b0d5c99e249dbc102
|
F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849
|
||||||
F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85
|
F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85
|
||||||
F test/syscall.test 2aa9e111b79fb385681ff8940124def6f8faab87
|
F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c
|
||||||
F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04
|
F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04
|
||||||
F test/tabfunc01.test cc33684f9480fcf1fd5ce287ac28d22971cad1cc
|
F test/tabfunc01.test cc33684f9480fcf1fd5ce287ac28d22971cad1cc
|
||||||
F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f
|
F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f
|
||||||
@ -1376,8 +1378,9 @@ F tool/lemon.c 799e73e19a33b8dd7767a7fa34618ed2a9c2397d
|
|||||||
F tool/lempar.c 3ec1463a034b37d87d782be5f6b8b10a3b1ecbe7
|
F tool/lempar.c 3ec1463a034b37d87d782be5f6b8b10a3b1ecbe7
|
||||||
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
|
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
|
||||||
F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6
|
F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6
|
||||||
F tool/mkautoconfamal.sh 5a5441280b509d2bb3bdc71bfb63781b0d570373
|
F tool/mkautoconfamal.sh a29b14d54302b33fd892958f6895582ea90e4a45
|
||||||
F tool/mkkeywordhash.c 06ec0b78bd4fa68c12d90ef2bdfe76b039133ff8
|
F tool/mkkeywordhash.c 06ec0b78bd4fa68c12d90ef2bdfe76b039133ff8
|
||||||
|
F tool/mkmsvcmin.tcl 93167a9e73383465b5716aa8dfa407409fccef1d
|
||||||
F tool/mkopcodec.tcl edde8adc42621b5e598127f8cdc6d52cfe21f52b
|
F tool/mkopcodec.tcl edde8adc42621b5e598127f8cdc6d52cfe21f52b
|
||||||
F tool/mkopcodeh.tcl e04177031532b7aa9379ded50e820231ac4abd6e
|
F tool/mkopcodeh.tcl e04177031532b7aa9379ded50e820231ac4abd6e
|
||||||
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
|
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
|
||||||
@ -1419,10 +1422,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
||||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||||
P a3cec529f0238e4ca1196fec420f2de80d28db78
|
P ac2cbadd8000947c097da5b00c00090fe58fdcff a3d7b8ac53f94d29a11362f193fd1967f30583df
|
||||||
R 76198b2176fddd32b1fb9b7a5f18b4c8
|
R 7855243eb7d1aae3e5a98345ca05c333
|
||||||
T *branch * btree-fordelete-flag
|
|
||||||
T *sym-btree-fordelete-flag *
|
|
||||||
T -sym-trunk *
|
|
||||||
U drh
|
U drh
|
||||||
Z c987d8ca8053309611f1f75e6c6acde5
|
Z 6eda54656ca87ef44dc31ff7472a92ee
|
||||||
|
@ -1 +1 @@
|
|||||||
ac2cbadd8000947c097da5b00c00090fe58fdcff
|
9a71d56dcea953cb965f1fdda9a8b8f158cdeff6
|
@ -1708,8 +1708,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
|
|||||||
if( pTab->iPKey>=0 ){
|
if( pTab->iPKey>=0 ){
|
||||||
ExprList *pList;
|
ExprList *pList;
|
||||||
Token ipkToken;
|
Token ipkToken;
|
||||||
ipkToken.z = pTab->aCol[pTab->iPKey].zName;
|
sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zName);
|
||||||
ipkToken.n = sqlite3Strlen30(ipkToken.z);
|
|
||||||
pList = sqlite3ExprListAppend(pParse, 0,
|
pList = sqlite3ExprListAppend(pParse, 0,
|
||||||
sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0));
|
sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0));
|
||||||
if( pList==0 ) return;
|
if( pList==0 ) return;
|
||||||
@ -3057,8 +3056,7 @@ Index *sqlite3CreateIndex(
|
|||||||
*/
|
*/
|
||||||
if( pList==0 ){
|
if( pList==0 ){
|
||||||
Token prevCol;
|
Token prevCol;
|
||||||
prevCol.z = pTab->aCol[pTab->nCol-1].zName;
|
sqlite3TokenInit(&prevCol, pTab->aCol[pTab->nCol-1].zName);
|
||||||
prevCol.n = sqlite3Strlen30(prevCol.z);
|
|
||||||
pList = sqlite3ExprListAppend(pParse, 0,
|
pList = sqlite3ExprListAppend(pParse, 0,
|
||||||
sqlite3ExprAlloc(db, TK_ID, &prevCol, 0));
|
sqlite3ExprAlloc(db, TK_ID, &prevCol, 0));
|
||||||
if( pList==0 ) goto exit_create_index;
|
if( pList==0 ) goto exit_create_index;
|
||||||
|
@ -149,7 +149,9 @@ static int statConnect(
|
|||||||
int iDb;
|
int iDb;
|
||||||
|
|
||||||
if( argc>=4 ){
|
if( argc>=4 ){
|
||||||
iDb = sqlite3FindDbName(db, argv[3]);
|
Token nm;
|
||||||
|
sqlite3TokenInit(&nm, (char*)argv[3]);
|
||||||
|
iDb = sqlite3FindDb(db, &nm);
|
||||||
if( iDb<0 ){
|
if( iDb<0 ){
|
||||||
*pzErr = sqlite3_mprintf("no such database: %s", argv[3]);
|
*pzErr = sqlite3_mprintf("no such database: %s", argv[3]);
|
||||||
return SQLITE_ERROR;
|
return SQLITE_ERROR;
|
||||||
|
@ -85,8 +85,7 @@ Expr *sqlite3ExprAddCollateToken(
|
|||||||
Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
|
Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
|
||||||
Token s;
|
Token s;
|
||||||
assert( zC!=0 );
|
assert( zC!=0 );
|
||||||
s.z = zC;
|
sqlite3TokenInit(&s, (char*)zC);
|
||||||
s.n = sqlite3Strlen30(s.z);
|
|
||||||
return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0);
|
return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1192,11 +1192,9 @@ static Trigger *fkActionTrigger(
|
|||||||
assert( iFromCol>=0 );
|
assert( iFromCol>=0 );
|
||||||
assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKey<pTab->nCol) );
|
assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKey<pTab->nCol) );
|
||||||
assert( pIdx==0 || pIdx->aiColumn[i]>=0 );
|
assert( pIdx==0 || pIdx->aiColumn[i]>=0 );
|
||||||
tToCol.z = pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName;
|
sqlite3TokenInit(&tToCol,
|
||||||
tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName;
|
pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName);
|
||||||
|
sqlite3TokenInit(&tFromCol, pFKey->pFrom->aCol[iFromCol].zName);
|
||||||
tToCol.n = sqlite3Strlen30(tToCol.z);
|
|
||||||
tFromCol.n = sqlite3Strlen30(tFromCol.z);
|
|
||||||
|
|
||||||
/* Create the expression "OLD.zToCol = zFromCol". It is important
|
/* Create the expression "OLD.zToCol = zFromCol". It is important
|
||||||
** that the "OLD.zToCol" term is on the LHS of the = operator, so
|
** that the "OLD.zToCol" term is on the LHS of the = operator, so
|
||||||
|
@ -322,11 +322,11 @@ static void memsys5FreeUnsafe(void *pOld){
|
|||||||
int iBuddy;
|
int iBuddy;
|
||||||
if( (iBlock>>iLogsize) & 1 ){
|
if( (iBlock>>iLogsize) & 1 ){
|
||||||
iBuddy = iBlock - size;
|
iBuddy = iBlock - size;
|
||||||
|
assert( iBuddy>=0 );
|
||||||
}else{
|
}else{
|
||||||
iBuddy = iBlock + size;
|
iBuddy = iBlock + size;
|
||||||
|
if( iBuddy>=mem5.nBlock ) break;
|
||||||
}
|
}
|
||||||
assert( iBuddy>=0 );
|
|
||||||
if( (iBuddy+(1<<iLogsize))>mem5.nBlock ) break;
|
|
||||||
if( mem5.aCtrl[iBuddy]!=(CTRL_FREE | iLogsize) ) break;
|
if( mem5.aCtrl[iBuddy]!=(CTRL_FREE | iLogsize) ) break;
|
||||||
memsys5Unlink(iBuddy, iLogsize);
|
memsys5Unlink(iBuddy, iLogsize);
|
||||||
iLogsize++;
|
iLogsize++;
|
||||||
|
153
src/os_unix.c
153
src/os_unix.c
@ -149,6 +149,11 @@
|
|||||||
*/
|
*/
|
||||||
#define MAX_PATHNAME 512
|
#define MAX_PATHNAME 512
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Maximum supported symbolic links
|
||||||
|
*/
|
||||||
|
#define SQLITE_MAX_SYMLINKS 100
|
||||||
|
|
||||||
/* Always cast the getpid() return type for compatibility with
|
/* Always cast the getpid() return type for compatibility with
|
||||||
** kernel modules in VxWorks. */
|
** kernel modules in VxWorks. */
|
||||||
#define osGetpid(X) (pid_t)getpid()
|
#define osGetpid(X) (pid_t)getpid()
|
||||||
@ -475,6 +480,12 @@ static struct unix_syscall {
|
|||||||
#endif
|
#endif
|
||||||
#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[26].pCurrent)
|
#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[26].pCurrent)
|
||||||
|
|
||||||
|
#if defined(HAVE_LSTAT)
|
||||||
|
{ "lstat", (sqlite3_syscall_ptr)lstat, 0 },
|
||||||
|
#else
|
||||||
|
{ "lstat", (sqlite3_syscall_ptr)0, 0 },
|
||||||
|
#endif
|
||||||
|
#define osLstat ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent)
|
||||||
|
|
||||||
}; /* End of the overrideable system calls */
|
}; /* End of the overrideable system calls */
|
||||||
|
|
||||||
@ -5927,6 +5938,32 @@ static int unixAccess(
|
|||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
static int mkFullPathname(
|
||||||
|
const char *zPath, /* Input path */
|
||||||
|
char *zOut, /* Output buffer */
|
||||||
|
int nOut /* Allocated size of buffer zOut */
|
||||||
|
){
|
||||||
|
int nPath = sqlite3Strlen30(zPath);
|
||||||
|
int iOff = 0;
|
||||||
|
if( zPath[0]!='/' ){
|
||||||
|
if( osGetcwd(zOut, nOut-2)==0 ){
|
||||||
|
return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
|
||||||
|
}
|
||||||
|
iOff = sqlite3Strlen30(zOut);
|
||||||
|
zOut[iOff++] = '/';
|
||||||
|
}
|
||||||
|
if( (iOff+nPath+1)>nOut ){
|
||||||
|
/* SQLite assumes that xFullPathname() nul-terminates the output buffer
|
||||||
|
** even if it returns an error. */
|
||||||
|
zOut[iOff] = '\0';
|
||||||
|
return SQLITE_CANTOPEN_BKPT;
|
||||||
|
}
|
||||||
|
sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath);
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Turn a relative pathname into a full pathname. The relative path
|
** Turn a relative pathname into a full pathname. The relative path
|
||||||
@ -5943,7 +5980,17 @@ static int unixFullPathname(
|
|||||||
int nOut, /* Size of output buffer in bytes */
|
int nOut, /* Size of output buffer in bytes */
|
||||||
char *zOut /* Output buffer */
|
char *zOut /* Output buffer */
|
||||||
){
|
){
|
||||||
|
#if !defined(HAVE_READLINK) || !defined(HAVE_LSTAT)
|
||||||
|
return mkFullPathname(zPath, zOut, nOut);
|
||||||
|
#else
|
||||||
|
int rc = SQLITE_OK;
|
||||||
int nByte;
|
int nByte;
|
||||||
|
int nLink = 1; /* Number of symbolic links followed so far */
|
||||||
|
const char *zIn = zPath; /* Input path for each iteration of loop */
|
||||||
|
char *zDel = 0;
|
||||||
|
|
||||||
|
assert( pVfs->mxPathname==MAX_PATHNAME );
|
||||||
|
UNUSED_PARAMETER(pVfs);
|
||||||
|
|
||||||
/* It's odd to simulate an io-error here, but really this is just
|
/* It's odd to simulate an io-error here, but really this is just
|
||||||
** using the io-error infrastructure to test that SQLite handles this
|
** using the io-error infrastructure to test that SQLite handles this
|
||||||
@ -5952,60 +5999,62 @@ static int unixFullPathname(
|
|||||||
*/
|
*/
|
||||||
SimulateIOError( return SQLITE_ERROR );
|
SimulateIOError( return SQLITE_ERROR );
|
||||||
|
|
||||||
assert( pVfs->mxPathname==MAX_PATHNAME );
|
do {
|
||||||
UNUSED_PARAMETER(pVfs);
|
|
||||||
|
|
||||||
#if defined(HAVE_READLINK)
|
/* Call stat() on path zIn. Set bLink to true if the path is a symbolic
|
||||||
/* Attempt to resolve the path as if it were a symbolic link. If it is
|
** link, or false otherwise. */
|
||||||
** a symbolic link, the resolved path is stored in buffer zOut[]. Or, if
|
int bLink = 0;
|
||||||
** the identified file is not a symbolic link or does not exist, then
|
struct stat buf;
|
||||||
** zPath is copied directly into zOut. Either way, nByte is left set to
|
if( osLstat(zIn, &buf)!=0 ){
|
||||||
** the size of the string copied into zOut[] in bytes. */
|
if( errno!=ENOENT ){
|
||||||
nByte = osReadlink(zPath, zOut, nOut-1);
|
rc = unixLogError(SQLITE_CANTOPEN_BKPT, "lstat", zIn);
|
||||||
if( nByte<0 ){
|
}
|
||||||
if( errno!=EINVAL && errno!=ENOENT ){
|
}else{
|
||||||
return unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zPath);
|
bLink = S_ISLNK(buf.st_mode);
|
||||||
}
|
}
|
||||||
sqlite3_snprintf(nOut, zOut, "%s", zPath);
|
|
||||||
nByte = sqlite3Strlen30(zOut);
|
|
||||||
}else{
|
|
||||||
zOut[nByte] = '\0';
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* If buffer zOut[] now contains an absolute path there is nothing more
|
if( bLink ){
|
||||||
** to do. If it contains a relative path, do the following:
|
if( zDel==0 ){
|
||||||
**
|
zDel = sqlite3_malloc(nOut);
|
||||||
** * move the relative path string so that it is at the end of th
|
if( zDel==0 ) rc = SQLITE_NOMEM;
|
||||||
** zOut[] buffer.
|
}else if( ++nLink>SQLITE_MAX_SYMLINKS ){
|
||||||
** * Call getcwd() to read the path of the current working directory
|
rc = SQLITE_CANTOPEN_BKPT;
|
||||||
** into the start of the zOut[] buffer.
|
}
|
||||||
** * Append a '/' character to the cwd string and move the
|
|
||||||
** relative path back within the buffer so that it immediately
|
if( rc==SQLITE_OK ){
|
||||||
** follows the '/'.
|
nByte = osReadlink(zIn, zDel, nOut-1);
|
||||||
**
|
if( nByte<0 ){
|
||||||
** This code is written so that if the combination of the CWD and relative
|
rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zIn);
|
||||||
** path are larger than the allocated size of zOut[] the CWD is silently
|
}else{
|
||||||
** truncated to make it fit. This is Ok, as SQLite refuses to open any
|
if( zDel[0]!='/' ){
|
||||||
** file for which this function returns a full path larger than (nOut-8)
|
int n;
|
||||||
** bytes in size. */
|
for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--);
|
||||||
testcase( nByte==nOut-5 );
|
if( nByte+n+1>nOut ){
|
||||||
testcase( nByte==nOut-4 );
|
rc = SQLITE_CANTOPEN_BKPT;
|
||||||
if( zOut[0]!='/' && nByte<nOut-4 ){
|
}else{
|
||||||
int nCwd;
|
memmove(&zDel[n], zDel, nByte+1);
|
||||||
int nRem = nOut-nByte-1;
|
memcpy(zDel, zIn, n);
|
||||||
memmove(&zOut[nRem], zOut, nByte+1);
|
nByte += n;
|
||||||
zOut[nRem-1] = '\0';
|
}
|
||||||
if( osGetcwd(zOut, nRem-1)==0 ){
|
}
|
||||||
return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
|
zDel[nByte] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zIn = zDel;
|
||||||
}
|
}
|
||||||
nCwd = sqlite3Strlen30(zOut);
|
|
||||||
assert( nCwd<=nRem-1 );
|
|
||||||
zOut[nCwd] = '/';
|
|
||||||
memmove(&zOut[nCwd+1], &zOut[nRem], nByte+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return SQLITE_OK;
|
assert( rc!=SQLITE_OK || zIn!=zOut || zIn[0]=='/' );
|
||||||
|
if( rc==SQLITE_OK && zIn!=zOut ){
|
||||||
|
rc = mkFullPathname(zIn, zOut, nOut);
|
||||||
|
}
|
||||||
|
if( bLink==0 ) break;
|
||||||
|
zIn = zOut;
|
||||||
|
}while( rc==SQLITE_OK );
|
||||||
|
|
||||||
|
sqlite3_free(zDel);
|
||||||
|
return rc;
|
||||||
|
#endif /* HAVE_READLINK && HAVE_LSTAT */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -6187,7 +6236,7 @@ static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 /* Not used */
|
#ifndef SQLITE_OMIT_DEPRECATED
|
||||||
/*
|
/*
|
||||||
** Find the current time (in Universal Coordinated Time). Write the
|
** Find the current time (in Universal Coordinated Time). Write the
|
||||||
** current time and date as a Julian Day number into *prNow and
|
** current time and date as a Julian Day number into *prNow and
|
||||||
@ -6205,7 +6254,7 @@ static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){
|
|||||||
# define unixCurrentTime 0
|
# define unixCurrentTime 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0 /* Not used */
|
#ifndef SQLITE_OMIT_DEPRECATED
|
||||||
/*
|
/*
|
||||||
** We added the xGetLastError() method with the intention of providing
|
** We added the xGetLastError() method with the intention of providing
|
||||||
** better low-level error messages when operating-system problems come up
|
** better low-level error messages when operating-system problems come up
|
||||||
@ -7504,7 +7553,7 @@ int sqlite3_os_init(void){
|
|||||||
|
|
||||||
/* Double-check that the aSyscall[] array has been constructed
|
/* Double-check that the aSyscall[] array has been constructed
|
||||||
** correctly. See ticket [bb3a86e890c8e96ab] */
|
** correctly. See ticket [bb3a86e890c8e96ab] */
|
||||||
assert( ArraySize(aSyscall)==27 );
|
assert( ArraySize(aSyscall)==28 );
|
||||||
|
|
||||||
/* Register all VFSes defined in the aVfs[] array */
|
/* Register all VFSes defined in the aVfs[] array */
|
||||||
for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
|
for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
|
||||||
|
17
src/pager.c
17
src/pager.c
@ -428,6 +428,20 @@ int sqlite3PagerTrace=1; /* True to enable tracing */
|
|||||||
*/
|
*/
|
||||||
#define MAX_SECTOR_SIZE 0x10000
|
#define MAX_SECTOR_SIZE 0x10000
|
||||||
|
|
||||||
|
/*
|
||||||
|
** If the option SQLITE_EXTRA_DURABLE option is set at compile-time, then
|
||||||
|
** SQLite will do extra fsync() operations when synchronous==FULL to help
|
||||||
|
** ensure that transactions are durable across a power failure. Most
|
||||||
|
** applications are happy as long as transactions are consistent across
|
||||||
|
** a power failure, and are perfectly willing to lose the last transaction
|
||||||
|
** in exchange for the extra performance of avoiding directory syncs.
|
||||||
|
** And so the default SQLITE_EXTRA_DURABLE setting is off.
|
||||||
|
*/
|
||||||
|
#ifndef SQLITE_EXTRA_DURABLE
|
||||||
|
# define SQLITE_EXTRA_DURABLE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** An instance of the following structure is allocated for each active
|
** An instance of the following structure is allocated for each active
|
||||||
** savepoint and statement transaction in the system. All such structures
|
** savepoint and statement transaction in the system. All such structures
|
||||||
@ -1983,7 +1997,8 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
|
|||||||
);
|
);
|
||||||
sqlite3OsClose(pPager->jfd);
|
sqlite3OsClose(pPager->jfd);
|
||||||
if( bDelete ){
|
if( bDelete ){
|
||||||
rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
|
rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal,
|
||||||
|
pPager->fullSync && SQLITE_EXTRA_DURABLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -525,7 +525,7 @@ static int sqlite3Prepare(
|
|||||||
}
|
}
|
||||||
pParse->pReprepare = pReprepare;
|
pParse->pReprepare = pReprepare;
|
||||||
assert( ppStmt && *ppStmt==0 );
|
assert( ppStmt && *ppStmt==0 );
|
||||||
assert( !db->mallocFailed );
|
/* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */
|
||||||
assert( sqlite3_mutex_held(db->mutex) );
|
assert( sqlite3_mutex_held(db->mutex) );
|
||||||
|
|
||||||
/* Check to verify that it is possible to get a read lock on all
|
/* Check to verify that it is possible to get a read lock on all
|
||||||
|
12
src/select.c
12
src/select.c
@ -1860,10 +1860,8 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
|
|||||||
sqlite3ExprCode(pParse, p->pOffset, iOffset);
|
sqlite3ExprCode(pParse, p->pOffset, iOffset);
|
||||||
sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v);
|
sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v);
|
||||||
VdbeComment((v, "OFFSET counter"));
|
VdbeComment((v, "OFFSET counter"));
|
||||||
sqlite3VdbeAddOp3(v, OP_SetIfNotPos, iOffset, iOffset, 0);
|
sqlite3VdbeAddOp3(v, OP_OffsetLimit, iLimit, iOffset+1, iOffset);
|
||||||
sqlite3VdbeAddOp3(v, OP_Add, iLimit, iOffset, iOffset+1);
|
|
||||||
VdbeComment((v, "LIMIT+OFFSET"));
|
VdbeComment((v, "LIMIT+OFFSET"));
|
||||||
sqlite3VdbeAddOp3(v, OP_SetIfNotPos, iLimit, iOffset+1, -1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2280,9 +2278,8 @@ static int multiSelect(
|
|||||||
addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
|
addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
|
||||||
VdbeComment((v, "Jump ahead if LIMIT reached"));
|
VdbeComment((v, "Jump ahead if LIMIT reached"));
|
||||||
if( p->iOffset ){
|
if( p->iOffset ){
|
||||||
sqlite3VdbeAddOp3(v, OP_SetIfNotPos, p->iOffset, p->iOffset, 0);
|
sqlite3VdbeAddOp3(v, OP_OffsetLimit,
|
||||||
sqlite3VdbeAddOp3(v, OP_Add, p->iLimit, p->iOffset, p->iOffset+1);
|
p->iLimit, p->iOffset+1, p->iOffset);
|
||||||
sqlite3VdbeAddOp3(v, OP_SetIfNotPos, p->iLimit, p->iOffset+1, -1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
explainSetInteger(iSub2, pParse->iNextSelectId);
|
explainSetInteger(iSub2, pParse->iNextSelectId);
|
||||||
@ -4438,8 +4435,7 @@ static int selectExpander(Walker *pWalker, Select *p){
|
|||||||
pExpr = pRight;
|
pExpr = pRight;
|
||||||
}
|
}
|
||||||
pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
|
pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
|
||||||
sColname.z = zColname;
|
sqlite3TokenInit(&sColname, zColname);
|
||||||
sColname.n = sqlite3Strlen30(zColname);
|
|
||||||
sqlite3ExprListSetName(pParse, pNew, &sColname, 0);
|
sqlite3ExprListSetName(pParse, pNew, &sColname, 0);
|
||||||
if( pNew && (p->selFlags & SF_NestedFrom)!=0 ){
|
if( pNew && (p->selFlags & SF_NestedFrom)!=0 ){
|
||||||
struct ExprList_item *pX = &pNew->a[pNew->nExpr-1];
|
struct ExprList_item *pX = &pNew->a[pNew->nExpr-1];
|
||||||
|
@ -39,9 +39,11 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|||||||
* Icon
|
* Icon
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if !defined(RC_VERONLY)
|
||||||
#define IDI_SQLITE 101
|
#define IDI_SQLITE 101
|
||||||
|
|
||||||
IDI_SQLITE ICON "..\\art\\sqlite370.ico"
|
IDI_SQLITE ICON "..\\art\\sqlite370.ico"
|
||||||
|
#endif /* !defined(RC_VERONLY) */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Version
|
* Version
|
||||||
|
@ -3325,6 +3325,7 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
|
|||||||
void sqlite3SetString(char **, sqlite3*, const char*);
|
void sqlite3SetString(char **, sqlite3*, const char*);
|
||||||
void sqlite3ErrorMsg(Parse*, const char*, ...);
|
void sqlite3ErrorMsg(Parse*, const char*, ...);
|
||||||
int sqlite3Dequote(char*);
|
int sqlite3Dequote(char*);
|
||||||
|
void sqlite3TokenInit(Token*,char*);
|
||||||
int sqlite3KeywordCode(const unsigned char*, int);
|
int sqlite3KeywordCode(const unsigned char*, int);
|
||||||
int sqlite3RunParser(Parse*, const char*, char **);
|
int sqlite3RunParser(Parse*, const char*, char **);
|
||||||
void sqlite3FinishCoding(Parse*);
|
void sqlite3FinishCoding(Parse*);
|
||||||
|
@ -153,6 +153,7 @@ struct SqliteDb {
|
|||||||
IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */
|
IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */
|
||||||
int nStep, nSort, nIndex; /* Statistics for most recent operation */
|
int nStep, nSort, nIndex; /* Statistics for most recent operation */
|
||||||
int nTransaction; /* Number of nested [transaction] methods */
|
int nTransaction; /* Number of nested [transaction] methods */
|
||||||
|
int openFlags; /* Flags used to open. (SQLITE_OPEN_URI) */
|
||||||
#ifdef SQLITE_TEST
|
#ifdef SQLITE_TEST
|
||||||
int bLegacyPrepare; /* True to use sqlite3_prepare() */
|
int bLegacyPrepare; /* True to use sqlite3_prepare() */
|
||||||
#endif
|
#endif
|
||||||
@ -1750,7 +1751,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
|||||||
Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME");
|
Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME");
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
rc = sqlite3_open(zDestFile, &pDest);
|
rc = sqlite3_open_v2(zDestFile, &pDest,
|
||||||
|
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE| pDb->openFlags, 0);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
Tcl_AppendResult(interp, "cannot open target database: ",
|
Tcl_AppendResult(interp, "cannot open target database: ",
|
||||||
sqlite3_errmsg(pDest), (char*)0);
|
sqlite3_errmsg(pDest), (char*)0);
|
||||||
@ -2613,7 +2615,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
|||||||
Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME");
|
Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME");
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
rc = sqlite3_open_v2(zSrcFile, &pSrc, SQLITE_OPEN_READONLY, 0);
|
rc = sqlite3_open_v2(zSrcFile, &pSrc,
|
||||||
|
SQLITE_OPEN_READONLY | pDb->openFlags, 0);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
Tcl_AppendResult(interp, "cannot open source database: ",
|
Tcl_AppendResult(interp, "cannot open source database: ",
|
||||||
sqlite3_errmsg(pSrc), (char*)0);
|
sqlite3_errmsg(pSrc), (char*)0);
|
||||||
@ -3088,6 +3091,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
|||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
p->maxStmt = NUM_PREPARED_STMTS;
|
p->maxStmt = NUM_PREPARED_STMTS;
|
||||||
|
p->openFlags = flags & SQLITE_OPEN_URI;
|
||||||
p->interp = interp;
|
p->interp = interp;
|
||||||
zArg = Tcl_GetStringFromObj(objv[1], 0);
|
zArg = Tcl_GetStringFromObj(objv[1], 0);
|
||||||
if( DbUseNre() ){
|
if( DbUseNre() ){
|
||||||
|
@ -287,8 +287,7 @@ void sqlite3FinishTrigger(
|
|||||||
pStepList->pTrig = pTrig;
|
pStepList->pTrig = pTrig;
|
||||||
pStepList = pStepList->pNext;
|
pStepList = pStepList->pNext;
|
||||||
}
|
}
|
||||||
nameToken.z = pTrig->zName;
|
sqlite3TokenInit(&nameToken, pTrig->zName);
|
||||||
nameToken.n = sqlite3Strlen30(nameToken.z);
|
|
||||||
sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken);
|
sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken);
|
||||||
if( sqlite3FixTriggerStep(&sFix, pTrig->step_list)
|
if( sqlite3FixTriggerStep(&sFix, pTrig->step_list)
|
||||||
|| sqlite3FixExpr(&sFix, pTrig->pWhen)
|
|| sqlite3FixExpr(&sFix, pTrig->pWhen)
|
||||||
|
@ -234,6 +234,14 @@ int sqlite3Dequote(char *z){
|
|||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Generate a Token object from a string
|
||||||
|
*/
|
||||||
|
void sqlite3TokenInit(Token *p, char *z){
|
||||||
|
p->z = z;
|
||||||
|
p->n = sqlite3Strlen30(z);
|
||||||
|
}
|
||||||
|
|
||||||
/* Convenient short-hand */
|
/* Convenient short-hand */
|
||||||
#define UpperToLower sqlite3UpperToLower
|
#define UpperToLower sqlite3UpperToLower
|
||||||
|
|
||||||
|
33
src/vdbe.c
33
src/vdbe.c
@ -5766,20 +5766,31 @@ case OP_IfPos: { /* jump, in1 */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: SetIfNotPos P1 P2 P3 * *
|
/* Opcode: OffsetLimit P1 P2 P3 * *
|
||||||
** Synopsis: if r[P1]<=0 then r[P2]=P3
|
** Synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)
|
||||||
**
|
**
|
||||||
** Register P1 must contain an integer.
|
** This opcode performs a commonly used computation associated with
|
||||||
** If the value of register P1 is not positive (if it is less than 1) then
|
** LIMIT and OFFSET process. r[P1] holds the limit counter. r[P3]
|
||||||
** set the value of register P2 to be the integer P3.
|
** holds the offset counter. The opcode computes the combined value
|
||||||
|
** of the LIMIT and OFFSET and stores that value in r[P2]. The r[P2]
|
||||||
|
** value computed is the total number of rows that will need to be
|
||||||
|
** visited in order to complete the query.
|
||||||
|
**
|
||||||
|
** If r[P3] is zero or negative, that means there is no OFFSET
|
||||||
|
** and r[P2] is set to be the value of the LIMIT, r[P1].
|
||||||
|
**
|
||||||
|
** if r[P1] is zero or negative, that means there is no LIMIT
|
||||||
|
** and r[P2] is set to -1.
|
||||||
|
**
|
||||||
|
** Otherwise, r[P2] is set to the sum of r[P1] and r[P3].
|
||||||
*/
|
*/
|
||||||
case OP_SetIfNotPos: { /* in1, in2 */
|
case OP_OffsetLimit: { /* in1, out2, in3 */
|
||||||
pIn1 = &aMem[pOp->p1];
|
pIn1 = &aMem[pOp->p1];
|
||||||
assert( pIn1->flags&MEM_Int );
|
pIn3 = &aMem[pOp->p3];
|
||||||
if( pIn1->u.i<=0 ){
|
pOut = out2Prerelease(p, pOp);
|
||||||
pOut = out2Prerelease(p, pOp);
|
assert( pIn1->flags & MEM_Int );
|
||||||
pOut->u.i = pOp->p3;
|
assert( pIn3->flags & MEM_Int );
|
||||||
}
|
pOut->u.i = pIn1->u.i<=0 ? -1 : pIn1->u.i+(pIn3->u.i>0?pIn3->u.i:0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
119
src/vdbeaux.c
119
src/vdbeaux.c
@ -1721,41 +1721,43 @@ void sqlite3VdbeIOTraceSql(Vdbe *p){
|
|||||||
}
|
}
|
||||||
#endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */
|
#endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */
|
||||||
|
|
||||||
/*
|
/* An instance of this object describes bulk memory available for use
|
||||||
** Allocate space from a fixed size buffer and return a pointer to
|
** by subcomponents of a prepared statement. Space is allocated out
|
||||||
** that space. If insufficient space is available, return NULL.
|
** of a ReusableSpace object by the allocSpace() routine below.
|
||||||
|
*/
|
||||||
|
struct ReusableSpace {
|
||||||
|
u8 *pSpace; /* Available memory */
|
||||||
|
int nFree; /* Bytes of available memory */
|
||||||
|
int nNeeded; /* Total bytes that could not be allocated */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Try to allocate nByte bytes of 8-byte aligned bulk memory for pBuf
|
||||||
|
** from the ReusableSpace object. Return a pointer to the allocated
|
||||||
|
** memory on success. If insufficient memory is available in the
|
||||||
|
** ReusableSpace object, increase the ReusableSpace.nNeeded
|
||||||
|
** value by the amount needed and return NULL.
|
||||||
**
|
**
|
||||||
** The pBuf parameter is the initial value of a pointer which will
|
** If pBuf is not initially NULL, that means that the memory has already
|
||||||
** receive the new memory. pBuf is normally NULL. If pBuf is not
|
** been allocated by a prior call to this routine, so just return a copy
|
||||||
** NULL, it means that memory space has already been allocated and that
|
** of pBuf and leave ReusableSpace unchanged.
|
||||||
** this routine should not allocate any new memory. When pBuf is not
|
|
||||||
** NULL simply return pBuf. Only allocate new memory space when pBuf
|
|
||||||
** is NULL.
|
|
||||||
**
|
**
|
||||||
** nByte is the number of bytes of space needed.
|
** This allocator is employed to repurpose unused slots at the end of the
|
||||||
**
|
** opcode array of prepared state for other memory needs of the prepared
|
||||||
** pFrom points to *pnFrom bytes of available space. New space is allocated
|
** statement.
|
||||||
** from the end of the pFrom buffer and *pnFrom is decremented.
|
|
||||||
**
|
|
||||||
** *pnNeeded is a counter of the number of bytes of space that have failed
|
|
||||||
** to allocate. If there is insufficient space in pFrom to satisfy the
|
|
||||||
** request, then increment *pnNeeded by the amount of the request.
|
|
||||||
*/
|
*/
|
||||||
static void *allocSpace(
|
static void *allocSpace(
|
||||||
void *pBuf, /* Where return pointer will be stored */
|
struct ReusableSpace *p, /* Bulk memory available for allocation */
|
||||||
int nByte, /* Number of bytes to allocate */
|
void *pBuf, /* Pointer to a prior allocation */
|
||||||
u8 *pFrom, /* Memory available for allocation */
|
int nByte /* Bytes of memory needed */
|
||||||
int *pnFrom, /* IN/OUT: Space available at pFrom */
|
|
||||||
int *pnNeeded /* If allocation cannot be made, increment *pnByte */
|
|
||||||
){
|
){
|
||||||
assert( EIGHT_BYTE_ALIGNMENT(pFrom) );
|
assert( EIGHT_BYTE_ALIGNMENT(p->pSpace) );
|
||||||
if( pBuf==0 ){
|
if( pBuf==0 ){
|
||||||
nByte = ROUND8(nByte);
|
nByte = ROUND8(nByte);
|
||||||
if( nByte <= *pnFrom ){
|
if( nByte <= p->nFree ){
|
||||||
*pnFrom -= nByte;
|
p->nFree -= nByte;
|
||||||
pBuf = &pFrom[*pnFrom];
|
pBuf = &p->pSpace[p->nFree];
|
||||||
}else{
|
}else{
|
||||||
*pnNeeded += nByte;
|
p->nNeeded += nByte;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert( EIGHT_BYTE_ALIGNMENT(pBuf) );
|
assert( EIGHT_BYTE_ALIGNMENT(pBuf) );
|
||||||
@ -1831,9 +1833,7 @@ void sqlite3VdbeMakeReady(
|
|||||||
int nArg; /* Number of arguments in subprograms */
|
int nArg; /* Number of arguments in subprograms */
|
||||||
int nOnce; /* Number of OP_Once instructions */
|
int nOnce; /* Number of OP_Once instructions */
|
||||||
int n; /* Loop counter */
|
int n; /* Loop counter */
|
||||||
int nFree; /* Available free space */
|
struct ReusableSpace x; /* Reusable bulk memory */
|
||||||
u8 *zCsr; /* Memory available for allocation */
|
|
||||||
int nByte; /* How much extra memory is needed */
|
|
||||||
|
|
||||||
assert( p!=0 );
|
assert( p!=0 );
|
||||||
assert( p->nOp>0 );
|
assert( p->nOp>0 );
|
||||||
@ -1851,7 +1851,7 @@ void sqlite3VdbeMakeReady(
|
|||||||
|
|
||||||
/* For each cursor required, also allocate a memory cell. Memory
|
/* For each cursor required, also allocate a memory cell. Memory
|
||||||
** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by
|
** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by
|
||||||
** the vdbe program. Instead they are used to allocate space for
|
** the vdbe program. Instead they are used to allocate memory for
|
||||||
** VdbeCursor/BtCursor structures. The blob of memory associated with
|
** VdbeCursor/BtCursor structures. The blob of memory associated with
|
||||||
** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1)
|
** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1)
|
||||||
** stores the blob of memory associated with cursor 1, etc.
|
** stores the blob of memory associated with cursor 1, etc.
|
||||||
@ -1860,20 +1860,18 @@ void sqlite3VdbeMakeReady(
|
|||||||
*/
|
*/
|
||||||
nMem += nCursor;
|
nMem += nCursor;
|
||||||
|
|
||||||
/* zCsr will initially point to nFree bytes of unused space at the
|
/* Figure out how much reusable memory is available at the end of the
|
||||||
** end of the opcode array, p->aOp. The computation of nFree is
|
** opcode array. This extra memory will be reallocated for other elements
|
||||||
** conservative - it might be smaller than the true number of free
|
** of the prepared statement.
|
||||||
** bytes, but never larger. nFree must be a multiple of 8 - it is
|
|
||||||
** rounded down if is not.
|
|
||||||
*/
|
*/
|
||||||
n = ROUND8(sizeof(Op)*p->nOp); /* Bytes of opcode space used */
|
n = ROUND8(sizeof(Op)*p->nOp); /* Bytes of opcode memory used */
|
||||||
zCsr = &((u8*)p->aOp)[n]; /* Unused opcode space */
|
x.pSpace = &((u8*)p->aOp)[n]; /* Unused opcode memory */
|
||||||
assert( EIGHT_BYTE_ALIGNMENT(zCsr) );
|
assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) );
|
||||||
nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused space */
|
x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused memory */
|
||||||
assert( nFree>=0 );
|
assert( x.nFree>=0 );
|
||||||
if( nFree>0 ){
|
if( x.nFree>0 ){
|
||||||
memset(zCsr, 0, nFree);
|
memset(x.pSpace, 0, x.nFree);
|
||||||
assert( EIGHT_BYTE_ALIGNMENT(&zCsr[nFree]) );
|
assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) );
|
||||||
}
|
}
|
||||||
|
|
||||||
resolveP2Values(p, &nArg);
|
resolveP2Values(p, &nArg);
|
||||||
@ -1883,33 +1881,30 @@ void sqlite3VdbeMakeReady(
|
|||||||
}
|
}
|
||||||
p->expired = 0;
|
p->expired = 0;
|
||||||
|
|
||||||
/* Memory for registers, parameters, cursor, etc, is allocated in two
|
/* Memory for registers, parameters, cursor, etc, is allocated in one or two
|
||||||
** passes. On the first pass, we try to reuse unused space at the
|
** passes. On the first pass, we try to reuse unused memory at the
|
||||||
** end of the opcode array. If we are unable to satisfy all memory
|
** end of the opcode array. If we are unable to satisfy all memory
|
||||||
** requirements by reusing the opcode array tail, then the second
|
** requirements by reusing the opcode array tail, then the second
|
||||||
** pass will fill in the rest using a fresh allocation.
|
** pass will fill in the remainder using a fresh memory allocation.
|
||||||
**
|
**
|
||||||
** This two-pass approach that reuses as much memory as possible from
|
** This two-pass approach that reuses as much memory as possible from
|
||||||
** the leftover space at the end of the opcode array can significantly
|
** the leftover memory at the end of the opcode array. This can significantly
|
||||||
** reduce the amount of memory held by a prepared statement.
|
** reduce the amount of memory held by a prepared statement.
|
||||||
*/
|
*/
|
||||||
do {
|
do {
|
||||||
nByte = 0;
|
x.nNeeded = 0;
|
||||||
p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), zCsr, &nFree, &nByte);
|
p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem));
|
||||||
p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), zCsr, &nFree, &nByte);
|
p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem));
|
||||||
p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), zCsr, &nFree, &nByte);
|
p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*));
|
||||||
p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*),
|
p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
|
||||||
zCsr, &nFree, &nByte);
|
p->aOnceFlag = allocSpace(&x, p->aOnceFlag, nOnce);
|
||||||
p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, zCsr, &nFree, &nByte);
|
|
||||||
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
|
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
|
||||||
p->anExec = allocSpace(p->anExec, p->nOp*sizeof(i64), zCsr, &nFree, &nByte);
|
p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64));
|
||||||
#endif
|
#endif
|
||||||
if( nByte ){
|
if( x.nNeeded==0 ) break;
|
||||||
p->pFree = sqlite3DbMallocZero(db, nByte);
|
x.pSpace = p->pFree = sqlite3DbMallocZero(db, x.nNeeded);
|
||||||
}
|
x.nFree = x.nNeeded;
|
||||||
zCsr = p->pFree;
|
}while( !db->mallocFailed );
|
||||||
nFree = nByte;
|
|
||||||
}while( nByte && !db->mallocFailed );
|
|
||||||
|
|
||||||
p->nCursor = nCursor;
|
p->nCursor = nCursor;
|
||||||
p->nOnceFlag = nOnce;
|
p->nOnceFlag = nOnce;
|
||||||
|
@ -1837,7 +1837,9 @@ int sqlite3VdbeSorterWrite(
|
|||||||
|
|
||||||
pNew = (SorterRecord*)&pSorter->list.aMemory[pSorter->iMemory];
|
pNew = (SorterRecord*)&pSorter->list.aMemory[pSorter->iMemory];
|
||||||
pSorter->iMemory += ROUND8(nReq);
|
pSorter->iMemory += ROUND8(nReq);
|
||||||
pNew->u.iNext = (int)((u8*)(pSorter->list.pList) - pSorter->list.aMemory);
|
if( pSorter->list.pList ){
|
||||||
|
pNew->u.iNext = (int)((u8*)(pSorter->list.pList) - pSorter->list.aMemory);
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
pNew = (SorterRecord *)sqlite3Malloc(nReq);
|
pNew = (SorterRecord *)sqlite3Malloc(nReq);
|
||||||
if( pNew==0 ){
|
if( pNew==0 ){
|
||||||
|
@ -28,4 +28,5 @@
|
|||||||
#define OS_VXWORKS 0
|
#define OS_VXWORKS 0
|
||||||
#define HAVE_FCHOWN 1
|
#define HAVE_FCHOWN 1
|
||||||
#define HAVE_READLINK 1
|
#define HAVE_READLINK 1
|
||||||
|
#define HAVE_LSTAT 1
|
||||||
#endif /* defined(_WRS_KERNEL) */
|
#endif /* defined(_WRS_KERNEL) */
|
||||||
|
@ -95,7 +95,7 @@ do_test 1.4.1 {
|
|||||||
|
|
||||||
do_re_test 1.4.2 {
|
do_re_test 1.4.2 {
|
||||||
lindex $::log 0
|
lindex $::log 0
|
||||||
} {^os_unix.c:\d*: \(\d+\) (open|readlink)\(.*test.db\) - }
|
} {^os_unix.c:\d*: \(\d+\) (open|readlink|lstat)\(.*test.db\) - }
|
||||||
|
|
||||||
#--------------------------------------------------------------------------
|
#--------------------------------------------------------------------------
|
||||||
# Tests oserror-1.* test failures in the unlink() system call.
|
# Tests oserror-1.* test failures in the unlink() system call.
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
|
set testprefix stat
|
||||||
|
|
||||||
ifcapable !vtab||!compound {
|
ifcapable !vtab||!compound {
|
||||||
finish_test
|
finish_test
|
||||||
@ -184,4 +185,69 @@ do_catchsql_test stat-6.1 {
|
|||||||
CREATE VIRTUAL TABLE temp.s2 USING dbstat(mainx);
|
CREATE VIRTUAL TABLE temp.s2 USING dbstat(mainx);
|
||||||
} {1 {no such database: mainx}}
|
} {1 {no such database: mainx}}
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
# Test that the argument passed to the dbstat constructor is dequoted
|
||||||
|
# before it is matched against the names of attached databases.
|
||||||
|
#
|
||||||
|
forcedelete test.db2
|
||||||
|
do_execsql_test 7.1 {
|
||||||
|
ATTACH 'test.db2' AS '123';
|
||||||
|
CREATE TABLE "123".x1(a, b);
|
||||||
|
INSERT INTO x1 VALUES(1, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test 7.1.1 {
|
||||||
|
SELECT * FROM dbstat('123');
|
||||||
|
} {
|
||||||
|
sqlite_master / 1 leaf 1 37 875 37 0 1024
|
||||||
|
x1 / 2 leaf 1 4 1008 4 1024 1024
|
||||||
|
}
|
||||||
|
do_execsql_test 7.1.2 {
|
||||||
|
SELECT * FROM dbstat(123);
|
||||||
|
} {
|
||||||
|
sqlite_master / 1 leaf 1 37 875 37 0 1024
|
||||||
|
x1 / 2 leaf 1 4 1008 4 1024 1024
|
||||||
|
}
|
||||||
|
do_execsql_test 7.1.3 {
|
||||||
|
CREATE VIRTUAL TABLE x2 USING dbstat('123');
|
||||||
|
SELECT * FROM x2;
|
||||||
|
} {
|
||||||
|
sqlite_master / 1 leaf 1 37 875 37 0 1024
|
||||||
|
x1 / 2 leaf 1 4 1008 4 1024 1024
|
||||||
|
}
|
||||||
|
do_execsql_test 7.1.4 {
|
||||||
|
CREATE VIRTUAL TABLE x3 USING dbstat(123);
|
||||||
|
SELECT * FROM x3;
|
||||||
|
} {
|
||||||
|
sqlite_master / 1 leaf 1 37 875 37 0 1024
|
||||||
|
x1 / 2 leaf 1 4 1008 4 1024 1024
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test 7.2 {
|
||||||
|
DETACH 123;
|
||||||
|
DROP TABLE x2;
|
||||||
|
DROP TABLE x3;
|
||||||
|
ATTACH 'test.db2' AS '123corp';
|
||||||
|
}
|
||||||
|
do_execsql_test 7.2.1 {
|
||||||
|
SELECT * FROM dbstat('123corp');
|
||||||
|
} {
|
||||||
|
sqlite_master / 1 leaf 1 37 875 37 0 1024
|
||||||
|
x1 / 2 leaf 1 4 1008 4 1024 1024
|
||||||
|
}
|
||||||
|
do_catchsql_test 7.2.2 {
|
||||||
|
SELECT * FROM dbstat(123corp);
|
||||||
|
} {1 {unrecognized token: "123corp"}}
|
||||||
|
do_execsql_test 7.2.3 {
|
||||||
|
CREATE VIRTUAL TABLE x2 USING dbstat('123corp');
|
||||||
|
SELECT * FROM x2;
|
||||||
|
} {
|
||||||
|
sqlite_master / 1 leaf 1 37 875 37 0 1024
|
||||||
|
x1 / 2 leaf 1 4 1008 4 1024 1024
|
||||||
|
}
|
||||||
|
do_catchsql_test 7.2.4 {
|
||||||
|
CREATE VIRTUAL TABLE x3 USING dbstat(123corp);
|
||||||
|
SELECT * FROM x3;
|
||||||
|
} {1 {unrecognized token: "123corp"}}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
@ -83,38 +83,49 @@ do_test 1.5 {
|
|||||||
do_test 2.0 {
|
do_test 2.0 {
|
||||||
catch { db close }
|
catch { db close }
|
||||||
catch { db2 close }
|
catch { db2 close }
|
||||||
forcedelete test.db test.db2
|
forcedelete test.db test.db2 test.db3
|
||||||
sqlite3 db test.db
|
sqlite3 db test.db
|
||||||
execsql { CREATE TABLE t1(x) }
|
execsql { CREATE TABLE t1(x) }
|
||||||
file link test.db2 test.db
|
file link test.db2 test.db
|
||||||
sqlite3 db2 test.db2
|
file link test.db3 test.db2
|
||||||
file exists test.db-journal
|
set {} {}
|
||||||
} 0
|
} {}
|
||||||
|
|
||||||
do_test 2.1 {
|
foreach {tn f} {1 test.db2 2 test.db3} {
|
||||||
execsql {
|
do_test 2.$tn.1 {
|
||||||
BEGIN;
|
sqlite3 db2 $f
|
||||||
INSERT INTO t1 VALUES(1);
|
file exists test.db-journal
|
||||||
} db2
|
} 0
|
||||||
file exists test.db-journal
|
do_test 2.$tn.2 {
|
||||||
} 1
|
execsql {
|
||||||
do_test 2.2 {
|
BEGIN;
|
||||||
file exists test.db2-journal
|
INSERT INTO t1 VALUES(1);
|
||||||
} 0
|
} db2
|
||||||
do_test 2.3 {
|
file exists test.db-journal
|
||||||
execsql {
|
} 1
|
||||||
COMMIT;
|
do_test 2.$tn.3 {
|
||||||
PRAGMA journal_mode = wal;
|
list [file exists test2.db-journal] [file exists test3.db-journal]
|
||||||
INSERT INTO t1 VALUES(2);
|
} {0 0}
|
||||||
} db2
|
do_test 2.$tn.4 {
|
||||||
file exists test.db-wal
|
execsql {
|
||||||
} 1
|
COMMIT;
|
||||||
do_test 2.4 {
|
PRAGMA journal_mode = wal;
|
||||||
file exists test.db2-wal
|
INSERT INTO t1 VALUES(2);
|
||||||
} 0
|
} db2
|
||||||
do_execsql_test 2.5 {
|
file exists test.db-wal
|
||||||
SELECT * FROM t1;
|
} 1
|
||||||
} {1 2}
|
do_test 2.$tn.5 {
|
||||||
|
list [file exists test2.db-wal] [file exists test3.db-wal]
|
||||||
|
} {0 0}
|
||||||
|
do_execsql_test 2.$tn.6 {
|
||||||
|
SELECT * FROM t1;
|
||||||
|
} {1 2}
|
||||||
|
db2 close
|
||||||
|
do_execsql_test 2.$tn.7 {
|
||||||
|
DELETE FROM t1;
|
||||||
|
PRAGMA journal_mode = delete;
|
||||||
|
} delete
|
||||||
|
}
|
||||||
|
|
||||||
# Try to open a ridiculously long pathname. Bug found by
|
# Try to open a ridiculously long pathname. Bug found by
|
||||||
# Kostya Serebryany using libFuzzer on 2015-11-30.
|
# Kostya Serebryany using libFuzzer on 2015-11-30.
|
||||||
@ -125,5 +136,56 @@ do_test 3.1 {
|
|||||||
set res
|
set res
|
||||||
} {unable to open database file}
|
} {unable to open database file}
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
# Test that relative symlinks that are not located in the cwd work.
|
||||||
|
#
|
||||||
|
do_test 4.1 {
|
||||||
|
forcedelete x y z
|
||||||
|
file mkdir x
|
||||||
|
file mkdir y
|
||||||
|
file mkdir z
|
||||||
|
sqlite3 db x/test.db
|
||||||
|
file link y/test.db ../x/test.db
|
||||||
|
file link z/test.db ../y/test.db
|
||||||
|
execsql {
|
||||||
|
PRAGMA journal_mode = wal;
|
||||||
|
CREATE TABLE t1(x, y);
|
||||||
|
INSERT INTO t1 VALUES('hello', 'world');
|
||||||
|
}
|
||||||
|
} {wal}
|
||||||
|
|
||||||
|
do_test 4.2.1 {
|
||||||
|
db close
|
||||||
|
sqlite3 db y/test.db
|
||||||
|
db eval { SELECT * FROM t1 }
|
||||||
|
} {hello world}
|
||||||
|
do_test 4.2.2 {
|
||||||
|
list [file exists x/test.db-wal] [file exists y/test.db-wal]
|
||||||
|
} {1 0}
|
||||||
|
|
||||||
|
do_test 4.3.1 {
|
||||||
|
db close
|
||||||
|
sqlite3 db z/test.db
|
||||||
|
db eval { SELECT * FROM t1 }
|
||||||
|
} {hello world}
|
||||||
|
do_test 4.3.2 {
|
||||||
|
list [file exists x/test.db-wal] [file exists y/test.db-wal] \
|
||||||
|
[file exists z/test.db-wal]
|
||||||
|
} {1 0 0}
|
||||||
|
|
||||||
|
do_test 4.4.0 {
|
||||||
|
forcedelete w
|
||||||
|
file mkdir w
|
||||||
|
file link w/test.db [file join [pwd] x/test.db]
|
||||||
|
set {} {}
|
||||||
|
} {}
|
||||||
|
do_test 4.4.1 {
|
||||||
|
db close
|
||||||
|
sqlite3 db w/test.db
|
||||||
|
db eval { SELECT * FROM t1 }
|
||||||
|
} {hello world}
|
||||||
|
do_test 4.4.2 {
|
||||||
|
list [file exists x/test.db-wal] [file exists w/test.db-wal]
|
||||||
|
} {1 0}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
@ -61,7 +61,7 @@ foreach s {
|
|||||||
fcntl read pread write pwrite fchmod fallocate
|
fcntl read pread write pwrite fchmod fallocate
|
||||||
pread64 pwrite64 unlink openDirectory mkdir rmdir
|
pread64 pwrite64 unlink openDirectory mkdir rmdir
|
||||||
statvfs fchown geteuid umask mmap munmap mremap
|
statvfs fchown geteuid umask mmap munmap mremap
|
||||||
getpagesize readlink
|
getpagesize readlink lstat
|
||||||
} {
|
} {
|
||||||
if {[test_syscall exists $s]} {lappend syscall_list $s}
|
if {[test_syscall exists $s]} {lappend syscall_list $s}
|
||||||
}
|
}
|
||||||
|
@ -34,14 +34,14 @@ set -e
|
|||||||
ARTIFACT=`printf "3%.2d%.2d%.2d" $xx $yy $zz`
|
ARTIFACT=`printf "3%.2d%.2d%.2d" $xx $yy $zz`
|
||||||
|
|
||||||
rm -rf $TMPSPACE
|
rm -rf $TMPSPACE
|
||||||
cp -R $TOP/autoconf $TMPSPACE
|
cp -R $TOP/autoconf $TMPSPACE
|
||||||
|
cp sqlite3.c $TMPSPACE
|
||||||
cp sqlite3.c $TMPSPACE
|
cp sqlite3.h $TMPSPACE
|
||||||
cp sqlite3.h $TMPSPACE
|
cp sqlite3ext.h $TMPSPACE
|
||||||
cp sqlite3ext.h $TMPSPACE
|
cp $TOP/sqlite3.1 $TMPSPACE
|
||||||
cp $TOP/sqlite3.1 $TMPSPACE
|
cp $TOP/sqlite3.pc.in $TMPSPACE
|
||||||
cp $TOP/sqlite3.pc.in $TMPSPACE
|
cp $TOP/src/shell.c $TMPSPACE
|
||||||
cp $TOP/src/shell.c $TMPSPACE
|
cp $TOP/src/sqlite3.rc $TMPSPACE
|
||||||
|
|
||||||
cat $TMPSPACE/configure.ac |
|
cat $TMPSPACE/configure.ac |
|
||||||
sed "s/--SQLITE-VERSION--/$VERSION/" > $TMPSPACE/tmp
|
sed "s/--SQLITE-VERSION--/$VERSION/" > $TMPSPACE/tmp
|
||||||
|
98
tool/mkmsvcmin.tcl
Normal file
98
tool/mkmsvcmin.tcl
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
#!/usr/bin/tcl
|
||||||
|
#
|
||||||
|
# This script reads the regular MSVC makefile (../Makefile.msc) and outputs
|
||||||
|
# a revised version of that Makefile that is "minimal" in the sense that
|
||||||
|
# it uses the sqlite3.c amalgamation as input and does not require tclsh.
|
||||||
|
# The resulting "../Makefile.min.msc" is suitable for use in the amalgamation
|
||||||
|
# tarballs.
|
||||||
|
#
|
||||||
|
if {$argc==0} {
|
||||||
|
set basedir [file dir [file dir [file normalize $argv0]]]
|
||||||
|
set fromFileName [file join $basedir Makefile.msc]
|
||||||
|
set toFileName [file join $basedir autoconf Makefile.msc]
|
||||||
|
} else {
|
||||||
|
set fromFileName [lindex $argv 0]
|
||||||
|
if {![file exists $fromFileName]} {
|
||||||
|
error "input file \"$fromFileName\" does not exist"
|
||||||
|
}
|
||||||
|
set toFileName [lindex $argv 1]
|
||||||
|
if {[file exists $toFileName]} {
|
||||||
|
error "output file \"$toFileName\" already exists"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
proc readFile { fileName } {
|
||||||
|
set file_id [open $fileName RDONLY]
|
||||||
|
fconfigure $file_id -encoding binary -translation binary
|
||||||
|
set result [read $file_id]
|
||||||
|
close $file_id
|
||||||
|
return $result
|
||||||
|
}
|
||||||
|
|
||||||
|
proc writeFile { fileName data } {
|
||||||
|
set file_id [open $fileName {WRONLY CREAT TRUNC}]
|
||||||
|
fconfigure $file_id -encoding binary -translation binary
|
||||||
|
puts -nonewline $file_id $data
|
||||||
|
close $file_id
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
proc escapeSubSpec { data } {
|
||||||
|
regsub -all -- {&} $data {\\\&} data
|
||||||
|
regsub -all -- {\\(\d+)} $data {\\\\\1} data
|
||||||
|
return $data
|
||||||
|
}
|
||||||
|
|
||||||
|
proc substVars { data } {
|
||||||
|
return [uplevel 1 [list subst -nocommands -nobackslashes $data]]
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# NOTE: This block is used to replace the section marked <<block1>> in
|
||||||
|
# the Makefile, if it exists.
|
||||||
|
#
|
||||||
|
set blocks(1) [string trimleft [string map [list \\\\ \\] {
|
||||||
|
_HASHCHAR=^#
|
||||||
|
!IF ![echo !IFNDEF VERSION > rcver.vc] && \\
|
||||||
|
![for /F "delims=" %V in ('type "$(SQLITE3H)" ^| find "$(_HASHCHAR)define SQLITE_VERSION "') do (echo VERSION = ^^%V >> rcver.vc)] && \\
|
||||||
|
![echo !ENDIF >> rcver.vc]
|
||||||
|
!INCLUDE rcver.vc
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
RESOURCE_VERSION = $(VERSION:^#=)
|
||||||
|
RESOURCE_VERSION = $(RESOURCE_VERSION:define=)
|
||||||
|
RESOURCE_VERSION = $(RESOURCE_VERSION:SQLITE_VERSION=)
|
||||||
|
RESOURCE_VERSION = $(RESOURCE_VERSION:"=)
|
||||||
|
RESOURCE_VERSION = $(RESOURCE_VERSION:.=,)
|
||||||
|
|
||||||
|
$(LIBRESOBJS): $(TOP)\sqlite3.rc rcver.vc $(SQLITE3H)
|
||||||
|
echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h
|
||||||
|
echo #define SQLITE_RESOURCE_VERSION $(RESOURCE_VERSION) >> sqlite3rc.h
|
||||||
|
echo #endif >> sqlite3rc.h
|
||||||
|
$(LTRCOMPILE) -fo $(LIBRESOBJS) -DRC_VERONLY $(TOP)\sqlite3.rc
|
||||||
|
}]]
|
||||||
|
|
||||||
|
set data "#### DO NOT EDIT ####\n"
|
||||||
|
append data "# This makefile is automatically "
|
||||||
|
append data "generated from the [file tail $fromFileName] at\n"
|
||||||
|
append data "# the root of the canonical SQLite source tree (not the\n"
|
||||||
|
append data "# amalgamation tarball) using the tool/[file tail $argv0]\n"
|
||||||
|
append data "# script.\n#\n\n"
|
||||||
|
append data [readFile $fromFileName]
|
||||||
|
|
||||||
|
regsub -all -- {# <<mark>>\n.*?# <</mark>>\n} \
|
||||||
|
$data "" data
|
||||||
|
|
||||||
|
foreach i [lsort -integer [array names blocks]] {
|
||||||
|
regsub -all -- [substVars \
|
||||||
|
{# <<block${i}>>\n.*?# <</block${i}>>\n}] \
|
||||||
|
$data [escapeSubSpec $blocks($i)] data
|
||||||
|
}
|
||||||
|
|
||||||
|
set data [string map [list " -I\$(TOP)\\src" ""] $data]
|
||||||
|
set data [string map [list " /DEF:sqlite3.def" ""] $data]
|
||||||
|
set data [string map [list " sqlite3.def" ""] $data]
|
||||||
|
set data [string map [list " libtclsqlite3.lib" ""] $data]
|
||||||
|
set data [string map [list "\$(TOP)\\src\\" "\$(TOP)\\"] $data]
|
||||||
|
|
||||||
|
writeFile $toFileName $data
|
Loading…
Reference in New Issue
Block a user