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)
|
||||
$(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)
|
||||
$(LTINSTALL) sqlite3$(BEXE) $(DESTDIR)$(bindir)
|
||||
$(LTINSTALL) sqlite3$(TEXE) $(DESTDIR)$(bindir)
|
||||
$(INSTALL) -d $(DESTDIR)$(includedir)
|
||||
$(INSTALL) -m 0644 sqlite3.h $(DESTDIR)$(includedir)
|
||||
$(INSTALL) -m 0644 $(TOP)/src/sqlite3ext.h $(DESTDIR)$(includedir)
|
||||
|
297
Makefile.msc
297
Makefile.msc
@ -10,11 +10,13 @@
|
||||
#
|
||||
TOP = .
|
||||
|
||||
# <<mark>>
|
||||
# Set this non-0 to create and use the SQLite amalgamation file.
|
||||
#
|
||||
!IFNDEF USE_AMALGAMATION
|
||||
USE_AMALGAMATION = 1
|
||||
!ENDIF
|
||||
# <</mark>>
|
||||
|
||||
# Set this non-0 to enable full warnings (-W4, etc) when compiling.
|
||||
#
|
||||
@ -68,11 +70,13 @@ USE_WP81_OPTS = 0
|
||||
SPLIT_AMALGAMATION = 0
|
||||
!ENDIF
|
||||
|
||||
# <<mark>>
|
||||
# Set this non-0 to use the International Components for Unicode (ICU).
|
||||
#
|
||||
!IFNDEF USE_ICU
|
||||
USE_ICU = 0
|
||||
!ENDIF
|
||||
# <</mark>>
|
||||
|
||||
# Set this non-0 to dynamically link to the MSVC runtime library.
|
||||
#
|
||||
@ -130,12 +134,20 @@ FOR_WINRT = 0
|
||||
FOR_UAP = 0
|
||||
!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
|
||||
# runtime library.
|
||||
#
|
||||
!IFNDEF NO_TCL
|
||||
NO_TCL = 0
|
||||
!ENDIF
|
||||
# <</mark>>
|
||||
|
||||
# Set this to non-0 to create and use PDBs.
|
||||
#
|
||||
@ -186,6 +198,49 @@ DEBUG = 0
|
||||
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.
|
||||
#
|
||||
@ -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
|
||||
!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 ################################
|
||||
###############################################################################
|
||||
@ -327,9 +395,18 @@ TCC = $(CC) -nologo -W4 -DINCLUDE_MSVC_H=1 $(CCOPTS) $(TCCOPTS)
|
||||
TCC = $(CC) -nologo -W3 $(CCOPTS) $(TCCOPTS)
|
||||
!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)
|
||||
|
||||
# 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
|
||||
@ -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
|
||||
# an explicit calling convention, which results in "cdecl").
|
||||
#
|
||||
!IF $(USE_STDCALL)!=0
|
||||
!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
|
||||
@ -358,7 +435,7 @@ SHELL_CCONV_OPTS =
|
||||
# These are additional compiler options used for the core library.
|
||||
#
|
||||
!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)
|
||||
!ELSE
|
||||
CORE_COMPILE_OPTS = $(CORE_CCONV_OPTS)
|
||||
@ -369,7 +446,7 @@ CORE_COMPILE_OPTS = $(CORE_CCONV_OPTS)
|
||||
# when linking.
|
||||
#
|
||||
!IFNDEF CORE_LINK_DEP
|
||||
!IF $(DYNAMIC_SHELL)!=0
|
||||
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
|
||||
CORE_LINK_DEP =
|
||||
!ELSE
|
||||
CORE_LINK_DEP = sqlite3.def
|
||||
@ -379,7 +456,7 @@ CORE_LINK_DEP = sqlite3.def
|
||||
# These are additional linker options used for the core library.
|
||||
#
|
||||
!IFNDEF CORE_LINK_OPTS
|
||||
!IF $(DYNAMIC_SHELL)!=0
|
||||
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
|
||||
CORE_LINK_OPTS =
|
||||
!ELSE
|
||||
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.
|
||||
#
|
||||
!IFNDEF SHELL_COMPILE_OPTS
|
||||
!IF $(DYNAMIC_SHELL)!=0
|
||||
SHELL_COMPILE_OPTS = -DSQLITE_SHELL_JSON1 $(SHELL_CCONV_OPTS) -DSQLITE_API=__declspec(dllimport)
|
||||
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
|
||||
SHELL_COMPILE_OPTS = $(SHELL_CCONV_OPTS) -DSQLITE_API=__declspec(dllimport)
|
||||
!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
|
||||
|
||||
# This is the core library that the shell executable should depend on.
|
||||
#
|
||||
!IFNDEF SHELL_CORE_DEP
|
||||
!IF $(DYNAMIC_SHELL)!=0
|
||||
SHELL_CORE_DEP = sqlite3.dll
|
||||
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
|
||||
SHELL_CORE_DEP = $(SQLITE3DLL)
|
||||
!ELSE
|
||||
SHELL_CORE_DEP = libsqlite3.lib
|
||||
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
|
||||
SHELL_CORE_LIB = sqlite3.lib
|
||||
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
|
||||
SHELL_CORE_LIB = $(SQLITE3LIB)
|
||||
!ELSE
|
||||
SHELL_CORE_LIB = libsqlite3.lib
|
||||
SHELL_CORE_LIB =
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
@ -441,12 +529,19 @@ 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 || $(USE_CRT_DLL)!=0
|
||||
!IF $(FOR_WINRT)!=0 || $(FOR_WIN10)!=0 || $(USE_CRT_DLL)!=0
|
||||
!IF $(DEBUG)>1
|
||||
TCC = $(TCC) -MDd
|
||||
BCC = $(BCC) -MDd
|
||||
@ -464,6 +559,7 @@ BCC = $(BCC) -MT
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
# <<mark>>
|
||||
# The mksqlite3c.tcl and mksqlite3h.tcl scripts will pull in
|
||||
# any extension header files by default. For non-amalgamation
|
||||
# builds, we need to make sure the compiler can find these.
|
||||
@ -487,6 +583,7 @@ MKSQLITE3C_ARGS = --linemacros
|
||||
MKSQLITE3C_ARGS =
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
# <</mark>>
|
||||
|
||||
# Define -DNDEBUG to compile without debugging (i.e., for production usage)
|
||||
# Omitting the define will cause extra debugging code to be inserted and
|
||||
@ -498,7 +595,7 @@ BCC = $(BCC) -DNDEBUG
|
||||
RCC = $(RCC) -DNDEBUG
|
||||
!ENDIF
|
||||
|
||||
!IF $(DEBUG)>0 || $(API_ARMOR)!=0
|
||||
!IF $(DEBUG)>0 || $(API_ARMOR)!=0 || $(FOR_WIN10)!=0
|
||||
TCC = $(TCC) -DSQLITE_ENABLE_API_ARMOR=1
|
||||
RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR=1
|
||||
!ENDIF
|
||||
@ -551,6 +648,7 @@ RCC = $(RCC) -DSQLITE_WIN32_MALLOC_VALIDATE=1
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
# <<mark>>
|
||||
# The locations of the Tcl header and library files. Also, the library that
|
||||
# non-stubs enabled programs using Tcl must link against. These variables
|
||||
# (TCLINCDIR, TCLLIBDIR, and LIBTCL) may be overridden via the environment
|
||||
@ -602,6 +700,7 @@ LIBICU = icuuc.lib icuin.lib
|
||||
!IFNDEF TCLSH_CMD
|
||||
TCLSH_CMD = tclsh85
|
||||
!ENDIF
|
||||
# <</mark>>
|
||||
|
||||
# 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
|
||||
# lines used to invoke the MSVC code and resource compilers.
|
||||
#
|
||||
TCC = $(TCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS)
|
||||
RCC = $(RCC) $(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) $(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"
|
||||
@ -700,6 +799,7 @@ TCC = $(TCC) -Zi
|
||||
BCC = $(BCC) -Zi
|
||||
!ENDIF
|
||||
|
||||
# <<mark>>
|
||||
# If ICU support is enabled, add the compiler options for it.
|
||||
#
|
||||
!IF $(USE_ICU)!=0
|
||||
@ -710,6 +810,7 @@ RCC = $(RCC) -I$(TOP)\ext\icu
|
||||
TCC = $(TCC) -I$(ICUINCDIR)
|
||||
RCC = $(RCC) -I$(ICUINCDIR)
|
||||
!ENDIF
|
||||
# <</mark>>
|
||||
|
||||
# Command line prefixes for compiling code, compiling resources,
|
||||
# linking, etc.
|
||||
@ -805,6 +906,7 @@ LDFLAGS = /DEBUG $(LDOPTS)
|
||||
LDFLAGS = $(LDOPTS)
|
||||
!ENDIF
|
||||
|
||||
# <<mark>>
|
||||
# Start with the Tcl related linker options.
|
||||
#
|
||||
!IF $(NO_TCL)==0
|
||||
@ -818,10 +920,12 @@ LTLIBS = $(LIBTCL)
|
||||
LTLIBPATHS = $(LTLIBPATHS) /LIBPATH:$(ICULIBDIR)
|
||||
LTLIBS = $(LTLIBS) $(LIBICU)
|
||||
!ENDIF
|
||||
# <</mark>>
|
||||
|
||||
# You should not have to change anything below this line
|
||||
###############################################################################
|
||||
|
||||
# <<mark>>
|
||||
# Object files for the SQLite library (non-amalgamation).
|
||||
#
|
||||
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 \
|
||||
vdbetrace.lo wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \
|
||||
utf.lo vtab.lo
|
||||
# <</mark>>
|
||||
|
||||
# Object files for the amalgamation.
|
||||
#
|
||||
@ -852,11 +957,15 @@ LIBOBJS1 = sqlite3.lo
|
||||
|
||||
# Determine the real value of LIBOBJ based on the 'configure' script
|
||||
#
|
||||
# <<mark>>
|
||||
!IF $(USE_AMALGAMATION)==0
|
||||
LIBOBJ = $(LIBOBJS0)
|
||||
!ELSE
|
||||
# <</mark>>
|
||||
LIBOBJ = $(LIBOBJS1)
|
||||
# <<mark>>
|
||||
!ENDIF
|
||||
# <</mark>>
|
||||
|
||||
# Determine if embedded resource compilation and usage are enabled.
|
||||
#
|
||||
@ -866,6 +975,7 @@ LIBRESOBJS = sqlite3res.lo
|
||||
LIBRESOBJS =
|
||||
!ENDIF
|
||||
|
||||
# <<mark>>
|
||||
# All of the source code files.
|
||||
#
|
||||
SRC1 = \
|
||||
@ -1024,7 +1134,7 @@ SRC5 = \
|
||||
opcodes.h \
|
||||
parse.c \
|
||||
parse.h \
|
||||
sqlite3.h
|
||||
$(SQLITE3H)
|
||||
|
||||
# All source code files.
|
||||
#
|
||||
@ -1168,7 +1278,7 @@ HDR = \
|
||||
$(TOP)\src\pcache.h \
|
||||
parse.h \
|
||||
$(TOP)\src\pragma.h \
|
||||
sqlite3.h \
|
||||
$(SQLITE3H) \
|
||||
$(TOP)\src\sqlite3ext.h \
|
||||
$(TOP)\src\sqliteInt.h \
|
||||
$(TOP)\src\sqliteLimit.h \
|
||||
@ -1203,7 +1313,7 @@ EXTHDR = $(EXTHDR) \
|
||||
#
|
||||
TESTPROGS = \
|
||||
testfixture.exe \
|
||||
sqlite3.exe \
|
||||
$(SQLITE3EXE) \
|
||||
sqlite3_analyzer.exe \
|
||||
sqldiff.exe
|
||||
|
||||
@ -1214,45 +1324,75 @@ FUZZDATA = \
|
||||
$(TOP)\test\fuzzdata2.db \
|
||||
$(TOP)\test\fuzzdata3.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
|
||||
FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
|
||||
|
||||
# Standard options to testfixture
|
||||
# Standard options to testfixture.
|
||||
#
|
||||
TESTOPTS = --verbose=file --output=test-out.txt
|
||||
# <</mark>>
|
||||
|
||||
# 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 sqlite3.exe libtclsqlite3.lib
|
||||
all: dll libsqlite3.lib shell libtclsqlite3.lib
|
||||
|
||||
# Dynamic link library section.
|
||||
#
|
||||
dll: $(SQLITE3DLL)
|
||||
|
||||
# Shell executable.
|
||||
#
|
||||
shell: $(SQLITE3EXE)
|
||||
|
||||
libsqlite3.lib: $(LIBOBJ)
|
||||
$(LTLIB) $(LTLIBOPTS) /OUT:$@ $(LIBOBJ) $(TLIBS)
|
||||
|
||||
# <<mark>>
|
||||
libtclsqlite3.lib: tclsqlite.lo libsqlite3.lib
|
||||
$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCLSTUB) $(TLIBS)
|
||||
# <</mark>>
|
||||
|
||||
sqlite3.exe: $(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
|
||||
$(LTLINK) $(SHELL_COMPILE_OPTS) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\src\shell.c \
|
||||
/link /pdb:sqlite3sh.pdb $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
|
||||
$(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
|
||||
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
||||
|
||||
sqldiff.exe: $(TOP)\tool\sqldiff.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) $(NO_WARN) $(TOP)\tool\sqldiff.c sqlite3.c /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
# <<mark>>
|
||||
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
|
||||
$(LTLINK) $(NO_WARN) $(FUZZERSHELL_COMPILE_OPTS) \
|
||||
$(TOP)\tool\fuzzershell.c sqlite3.c /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
$(SQLITE3EXE): $(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H)
|
||||
$(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\src\shell.c $(SHELL_CORE_SRC) \
|
||||
/link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
|
||||
|
||||
fuzzcheck.exe: $(TOP)\test\fuzzcheck.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(TOP)\test\fuzzcheck.c sqlite3.c /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
# <<mark>>
|
||||
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
|
||||
$(LTLINK) $(NO_WARN) $(SHELL_COMPILE_OPTS) $(TOP)\mptest\mptest.c \
|
||||
/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(SHELL_LINK_OPTS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
|
||||
fuzzershell.exe: $(TOP)\tool\fuzzershell.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(FUZZERSHELL_COMPILE_OPTS) $(TOP)\tool\fuzzershell.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
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
|
||||
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
|
||||
$(TCLSH_CMD) $(TOP)\tool\split-sqlite3c.tcl
|
||||
|
||||
# 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
|
||||
# <</mark>>
|
||||
|
||||
# Rule to build the amalgamation
|
||||
#
|
||||
sqlite3.lo: $(SQLITE3C)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(SQLITE3C)
|
||||
|
||||
# <<mark>>
|
||||
# Rules to build the LEMON compiler generator
|
||||
#
|
||||
lempar.c: $(TOP)\tool\lempar.c
|
||||
@ -1330,11 +1463,13 @@ parse.lo: parse.c $(HDR)
|
||||
|
||||
opcodes.lo: opcodes.c
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c opcodes.c
|
||||
# <</mark>>
|
||||
|
||||
# Rule to build the Win32 resources object file.
|
||||
#
|
||||
!IF $(USE_RC)!=0
|
||||
$(LIBRESOBJS): $(TOP)\src\sqlite3.rc $(HDR)
|
||||
# <<block1>>
|
||||
$(LIBRESOBJS): $(TOP)\src\sqlite3.rc $(SQLITE3H)
|
||||
echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h
|
||||
for /F %%V in ('type "$(TOP)\VERSION"') do ( \
|
||||
echo #define SQLITE_RESOURCE_VERSION %%V \
|
||||
@ -1342,8 +1477,10 @@ $(LIBRESOBJS): $(TOP)\src\sqlite3.rc $(HDR)
|
||||
)
|
||||
echo #endif >> sqlite3rc.h
|
||||
$(LTRCOMPILE) -fo $(LIBRESOBJS) $(TOP)\src\sqlite3.rc
|
||||
# <</block1>>
|
||||
!ENDIF
|
||||
|
||||
# <<mark>>
|
||||
# Rules to build individual *.lo files from files in the src directory.
|
||||
#
|
||||
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)
|
||||
$(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)
|
||||
|
||||
# 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
|
||||
del /Q parse.y parse.h parse.h.temp 2>NUL
|
||||
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
|
||||
$(TCLSH_CMD) $(TOP)\tool\addopcodes.tcl parse.h.temp > parse.h
|
||||
|
||||
sqlite3.h: $(TOP)\src\sqlite.h.in $(TOP)\manifest.uuid $(TOP)\VERSION
|
||||
$(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > sqlite3.h
|
||||
$(SQLITE3H): $(TOP)\src\sqlite.h.in $(TOP)\manifest.uuid $(TOP)\VERSION
|
||||
$(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > $(SQLITE3H)
|
||||
|
||||
sqlite3ext.h: .target_source
|
||||
copy tsrc\sqlite3ext.h .
|
||||
|
||||
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)
|
||||
|
||||
keywordhash.h: $(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe
|
||||
@ -1698,7 +1835,7 @@ FTS5_SRC = \
|
||||
fts5parse.c: $(TOP)\ext\fts5\fts5parse.y lemon.exe
|
||||
copy $(TOP)\ext\fts5\fts5parse.y .
|
||||
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
|
||||
|
||||
@ -1737,7 +1874,7 @@ TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0)
|
||||
TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC1)
|
||||
!ENDIF
|
||||
|
||||
testfixture.exe: $(TESTFIXTURE_SRC) $(LIBRESOBJS) $(HDR)
|
||||
testfixture.exe: $(TESTFIXTURE_SRC) $(SQLITE3H) $(LIBRESOBJS) $(HDR)
|
||||
$(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \
|
||||
-DBUILD_sqlite -I$(TCLINCDIR) \
|
||||
$(TESTFIXTURE_SRC) \
|
||||
@ -1759,7 +1896,7 @@ fulltestonly: $(TESTPROGS) fuzztest
|
||||
@set PATH=$(LIBTCLPATH);$(PATH)
|
||||
.\testfixture.exe $(TOP)\test\full.test
|
||||
|
||||
queryplantest: testfixture.exe sqlite3.exe
|
||||
queryplantest: testfixture.exe shell
|
||||
@set PATH=$(LIBTCLPATH);$(PATH)
|
||||
.\testfixture.exe $(TOP)\test\permutations.test queryplanner $(TESTOPTS)
|
||||
|
||||
@ -1786,7 +1923,7 @@ smoketest: $(TESTPROGS)
|
||||
@set PATH=$(LIBTCLPATH);$(PATH)
|
||||
.\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 SQLITE_ENABLE_DBSTAT_VTAB 1 >> $@
|
||||
copy $@ + $(SQLITE3C) + $(TOP)\src\tclsqlite.c $@
|
||||
@ -1805,49 +1942,51 @@ testloadext.lo: $(TOP)\src\test_loadext.c
|
||||
testloadext.dll: 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$@ \
|
||||
$(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$@ \
|
||||
$(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$@ \
|
||||
$(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$@ \
|
||||
$(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$@ \
|
||||
$(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$@ \
|
||||
$(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)
|
||||
|
||||
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$@ \
|
||||
$(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$@ \
|
||||
$(TOP)\test\speedtest1.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
rbu.exe: $(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU -Fe$@ $(TOP)\ext\rbu\rbu.c $(SQLITE3C) \
|
||||
/link $(LDFLAGS) $(LTLINKOPTS)
|
||||
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) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
# <</mark>>
|
||||
|
||||
clean:
|
||||
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 sqlite3.h opcodes.c opcodes.h 2>NUL
|
||||
del /Q *.bsc *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL
|
||||
# <<mark>>
|
||||
del /Q $(SQLITE3C) $(SQLITE3H) opcodes.c opcodes.h 2>NUL
|
||||
del /Q lemon.* lempar.c parse.* 2>NUL
|
||||
del /Q mkkeywordhash.* keywordhash.h 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 showjournal.exe showstat4.exe showwal.exe speedtest1.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 sqlite3rc.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 fuzzershell.exe fuzzcheck.exe sqldiff.exe 2>NUL
|
||||
del /Q fts5.* fts5parse.* 2>NUL
|
||||
|
||||
# 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)
|
||||
# <</mark>>
|
||||
|
@ -14,7 +14,7 @@ sqlite3_CFLAGS = $(AM_CFLAGS)
|
||||
|
||||
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
|
||||
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_uint64 u64;
|
||||
|
||||
#define ArraySize(x) (sizeof(x) / sizeof(x[0]))
|
||||
#define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0])))
|
||||
|
||||
#define testcase(x)
|
||||
#define ALWAYS(x) 1
|
||||
@ -225,8 +225,8 @@ int sqlite3Fts5ConfigParseRank(const char*, char**, char**);
|
||||
typedef struct Fts5Buffer Fts5Buffer;
|
||||
struct Fts5Buffer {
|
||||
u8 *p;
|
||||
u32 n;
|
||||
u32 nSpace;
|
||||
int n;
|
||||
int nSpace;
|
||||
};
|
||||
|
||||
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 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) \
|
||||
)
|
||||
|
||||
@ -315,6 +315,12 @@ void sqlite3Fts5TermsetFree(Fts5Termset*);
|
||||
typedef struct Fts5Index Fts5Index;
|
||||
typedef struct Fts5IndexIter Fts5IndexIter;
|
||||
|
||||
struct Fts5IndexIter {
|
||||
i64 iRowid;
|
||||
const u8 *pData;
|
||||
int nData;
|
||||
};
|
||||
|
||||
/*
|
||||
** Values used as part of the flags argument passed to IndexQuery().
|
||||
*/
|
||||
@ -382,8 +388,6 @@ int sqlite3Fts5IterEof(Fts5IndexIter*);
|
||||
int sqlite3Fts5IterNext(Fts5IndexIter*);
|
||||
int sqlite3Fts5IterNextFrom(Fts5IndexIter*, i64 iMatch);
|
||||
i64 sqlite3Fts5IterRowid(Fts5IndexIter*);
|
||||
int sqlite3Fts5IterPoslist(Fts5IndexIter*,Fts5Colset*, const u8**, int*, i64*);
|
||||
int sqlite3Fts5IterPoslistBuffer(Fts5IndexIter *pIter, Fts5Buffer *pBuf);
|
||||
|
||||
/*
|
||||
** Close an iterator opened by sqlite3Fts5IndexQuery().
|
||||
@ -469,8 +473,6 @@ int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge);
|
||||
|
||||
int sqlite3Fts5IndexLoadConfig(Fts5Index *p);
|
||||
|
||||
int sqlite3Fts5IterCollist(Fts5IndexIter*, const u8 **, int*);
|
||||
|
||||
/*
|
||||
** 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 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,
|
||||
aBuiltin[i].zFunc,
|
||||
aBuiltin[i].pUserData,
|
||||
|
@ -322,7 +322,7 @@ int sqlite3Fts5TermsetAdd(
|
||||
*pbPresent = 0;
|
||||
if( p ){
|
||||
int i;
|
||||
int hash = 13;
|
||||
u32 hash = 13;
|
||||
Fts5TermsetEntry *pEntry;
|
||||
|
||||
/* Calculate a hash value for this term. This is the same hash checksum
|
||||
@ -363,7 +363,7 @@ int sqlite3Fts5TermsetAdd(
|
||||
|
||||
void sqlite3Fts5TermsetFree(Fts5Termset *p){
|
||||
if( p ){
|
||||
int i;
|
||||
u32 i;
|
||||
for(i=0; i<ArraySize(p->apHash); i++){
|
||||
Fts5TermsetEntry *pEntry = p->apHash[i];
|
||||
while( pEntry ){
|
||||
|
@ -306,7 +306,7 @@ static int fts5ExprSynonymList(
|
||||
int bCollist,
|
||||
Fts5Colset *pColset,
|
||||
i64 iRowid,
|
||||
int *pbDel, /* OUT: Caller should sqlite3_free(*pa) */
|
||||
Fts5Buffer *pBuf, /* Use this buffer for space if required */
|
||||
u8 **pa, int *pn
|
||||
){
|
||||
Fts5PoslistReader aStatic[4];
|
||||
@ -320,18 +320,7 @@ static int fts5ExprSynonymList(
|
||||
for(p=pTerm; p; p=p->pSynonym){
|
||||
Fts5IndexIter *pIter = p->pIter;
|
||||
if( sqlite3Fts5IterEof(pIter)==0 && sqlite3Fts5IterRowid(pIter)==iRowid ){
|
||||
const u8 *a;
|
||||
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( pIter->nData==0 ) continue;
|
||||
if( nIter==nAlloc ){
|
||||
int nByte = sizeof(Fts5PoslistReader) * nAlloc * 2;
|
||||
Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc(nByte);
|
||||
@ -344,20 +333,19 @@ static int fts5ExprSynonymList(
|
||||
if( aIter!=aStatic ) sqlite3_free(aIter);
|
||||
aIter = aNew;
|
||||
}
|
||||
sqlite3Fts5PoslistReaderInit(a, n, &aIter[nIter]);
|
||||
sqlite3Fts5PoslistReaderInit(pIter->pData, pIter->nData, &aIter[nIter]);
|
||||
assert( aIter[nIter].bEof==0 );
|
||||
nIter++;
|
||||
}
|
||||
}
|
||||
|
||||
assert( *pbDel==0 );
|
||||
if( nIter==1 ){
|
||||
*pa = (u8*)aIter[0].a;
|
||||
*pn = aIter[0].n;
|
||||
}else{
|
||||
Fts5PoslistWriter writer = {0};
|
||||
Fts5Buffer buf = {0,0,0};
|
||||
i64 iPrev = -1;
|
||||
fts5BufferZero(pBuf);
|
||||
while( 1 ){
|
||||
int i;
|
||||
i64 iMin = FTS5_LARGEST_INT64;
|
||||
@ -372,15 +360,12 @@ static int fts5ExprSynonymList(
|
||||
}
|
||||
}
|
||||
if( iMin==FTS5_LARGEST_INT64 || rc!=SQLITE_OK ) break;
|
||||
rc = sqlite3Fts5PoslistWriterAppend(&buf, &writer, iMin);
|
||||
rc = sqlite3Fts5PoslistWriterAppend(pBuf, &writer, iMin);
|
||||
iPrev = iMin;
|
||||
}
|
||||
if( rc ){
|
||||
sqlite3_free(buf.p);
|
||||
}else{
|
||||
*pa = buf.p;
|
||||
*pn = buf.n;
|
||||
*pbDel = 1;
|
||||
if( rc==SQLITE_OK ){
|
||||
*pa = pBuf->p;
|
||||
*pn = pBuf->n;
|
||||
}
|
||||
}
|
||||
|
||||
@ -417,7 +402,7 @@ static int fts5ExprPhraseIsMatch(
|
||||
|
||||
/* If the aStatic[] array is not large enough, allocate a large array
|
||||
** using sqlite3_malloc(). This approach could be improved upon. */
|
||||
if( pPhrase->nTerm>(int)ArraySize(aStatic) ){
|
||||
if( pPhrase->nTerm>ArraySize(aStatic) ){
|
||||
int nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm;
|
||||
aIter = (Fts5PoslistReader*)sqlite3_malloc(nByte);
|
||||
if( !aIter ) return SQLITE_NOMEM;
|
||||
@ -427,18 +412,23 @@ static int fts5ExprPhraseIsMatch(
|
||||
/* Initialize a term iterator for each term in the phrase */
|
||||
for(i=0; i<pPhrase->nTerm; i++){
|
||||
Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
|
||||
i64 dummy;
|
||||
int n = 0;
|
||||
int bFlag = 0;
|
||||
const u8 *a = 0;
|
||||
u8 *a = 0;
|
||||
if( pTerm->pSynonym ){
|
||||
Fts5Buffer buf = {0, 0, 0};
|
||||
rc = fts5ExprSynonymList(
|
||||
pTerm, 0, pColset, pNode->iRowid, &bFlag, (u8**)&a, &n
|
||||
pTerm, 0, pColset, pNode->iRowid, &buf, &a, &n
|
||||
);
|
||||
}else{
|
||||
rc = sqlite3Fts5IterPoslist(pTerm->pIter, pColset, &a, &n, &dummy);
|
||||
if( rc ){
|
||||
sqlite3_free(a);
|
||||
goto ismatch_out;
|
||||
}
|
||||
if( a==buf.p ) bFlag = 1;
|
||||
}else{
|
||||
a = (u8*)pTerm->pIter->pData;
|
||||
n = pTerm->pIter->nData;
|
||||
}
|
||||
if( rc!=SQLITE_OK ) goto ismatch_out;
|
||||
sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
|
||||
aIter[i].bFlag = (u8)bFlag;
|
||||
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
|
||||
** 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;
|
||||
a = (Fts5NearTrimmer*)sqlite3Fts5MallocZero(&rc, nByte);
|
||||
}else{
|
||||
@ -775,6 +765,7 @@ static int fts5ExprNearTest(
|
||||
for(pTerm=&pPhrase->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){
|
||||
Fts5IndexIter *pIter = pTerm->pIter;
|
||||
if( sqlite3Fts5IterEof(pIter)==0 ){
|
||||
#if 0
|
||||
int n;
|
||||
i64 iRowid;
|
||||
rc = sqlite3Fts5IterPoslist(pIter, pNear->pColset, 0, &n, &iRowid);
|
||||
@ -784,6 +775,10 @@ static int fts5ExprNearTest(
|
||||
}else if( iRowid==pNode->iRowid && n>0 ){
|
||||
pPhrase->poslist.n = 1;
|
||||
}
|
||||
#endif
|
||||
if( pIter->iRowid==pNode->iRowid && pIter->nData>0 ){
|
||||
pPhrase->poslist.n = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return pPhrase->poslist.n;
|
||||
@ -800,9 +795,13 @@ static int fts5ExprNearTest(
|
||||
rc = fts5ExprPhraseIsMatch(pNode, pNear->pColset, pPhrase, &bMatch);
|
||||
if( bMatch==0 ) break;
|
||||
}else{
|
||||
Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
|
||||
fts5BufferSet(&rc, &pPhrase->poslist, pIter->nData, pIter->pData);
|
||||
#if 0
|
||||
rc = sqlite3Fts5IterPoslistBuffer(
|
||||
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
|
||||
** a new poslist the way we have to for more complicated phrase or NEAR
|
||||
** expressions. */
|
||||
Fts5ExprNearset *pNear = pNode->pNear;
|
||||
Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
|
||||
Fts5ExprPhrase *pPhrase = pNode->pNear->apPhrase[0];
|
||||
Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
|
||||
Fts5Colset *pColset = pNear->pColset;
|
||||
int rc;
|
||||
|
||||
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 );
|
||||
|
||||
rc = sqlite3Fts5IterPoslist(pIter, pColset,
|
||||
(const u8**)&pPhrase->poslist.p, (int*)&pPhrase->poslist.n, &pNode->iRowid
|
||||
);
|
||||
pPhrase->poslist.n = pIter->nData;
|
||||
if( pExpr->pConfig->eDetail==FTS5_DETAIL_FULL ){
|
||||
pPhrase->poslist.p = (u8*)pIter->pData;
|
||||
}
|
||||
pNode->iRowid = pIter->iRowid;
|
||||
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];
|
||||
sqlite3_free(pTerm->zTerm);
|
||||
sqlite3Fts5IterClose(pTerm->pIter);
|
||||
|
||||
for(pSyn=pTerm->pSynonym; pSyn; pSyn=pNext){
|
||||
pNext = pSyn->pSynonym;
|
||||
sqlite3Fts5IterClose(pSyn->pIter);
|
||||
fts5BufferFree((Fts5Buffer*)&pSyn[1]);
|
||||
sqlite3_free(pSyn);
|
||||
}
|
||||
}
|
||||
@ -1461,13 +1459,13 @@ static int fts5ParseTokenize(
|
||||
assert( pPhrase==0 || pPhrase->nTerm>0 );
|
||||
if( pPhrase && (tflags & FTS5_TOKEN_COLOCATED) ){
|
||||
Fts5ExprTerm *pSyn;
|
||||
int nByte = sizeof(Fts5ExprTerm) + nToken+1;
|
||||
int nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1;
|
||||
pSyn = (Fts5ExprTerm*)sqlite3_malloc(nByte);
|
||||
if( pSyn==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
memset(pSyn, 0, nByte);
|
||||
pSyn->zTerm = (char*)&pSyn[1];
|
||||
pSyn->zTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer);
|
||||
memcpy(pSyn->zTerm, pToken, nToken);
|
||||
pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym;
|
||||
pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn;
|
||||
@ -2246,7 +2244,7 @@ int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){
|
||||
int rc = SQLITE_OK;
|
||||
void *pCtx = (void*)pGlobal;
|
||||
|
||||
for(i=0; rc==SQLITE_OK && i<(int)ArraySize(aFunc); i++){
|
||||
for(i=0; rc==SQLITE_OK && i<ArraySize(aFunc); i++){
|
||||
struct Fts5ExprFunc *p = &aFunc[i];
|
||||
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;
|
||||
|
||||
assert( iPhrase>=0 && iPhrase<pExpr->nPhrase );
|
||||
assert( pExpr->pConfig->eDetail==FTS5_DETAIL_COLUMNS );
|
||||
|
||||
if( pNode->bEof==0
|
||||
&& pNode->iRowid==pExpr->pRoot->iRowid
|
||||
&& pPhrase->poslist.n>0
|
||||
){
|
||||
Fts5ExprTerm *pTerm = &pPhrase->aTerm[0];
|
||||
if( pTerm->pSynonym ){
|
||||
int bDel = 0;
|
||||
u8 *a;
|
||||
Fts5Buffer *pBuf = (Fts5Buffer*)&pTerm->pSynonym[1];
|
||||
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{
|
||||
sqlite3Fts5IterCollist(pPhrase->aTerm[0].pIter, ppCollist, pnCollist);
|
||||
*ppCollist = pPhrase->aTerm[0].pIter->pData;
|
||||
*pnCollist = pPhrase->aTerm[0].pIter->nData;
|
||||
}
|
||||
}else{
|
||||
*ppCollist = 0;
|
||||
|
@ -261,6 +261,7 @@ typedef struct Fts5Data Fts5Data;
|
||||
typedef struct Fts5DlidxIter Fts5DlidxIter;
|
||||
typedef struct Fts5DlidxLvl Fts5DlidxLvl;
|
||||
typedef struct Fts5DlidxWriter Fts5DlidxWriter;
|
||||
typedef struct Fts5Iter Fts5Iter;
|
||||
typedef struct Fts5PageWriter Fts5PageWriter;
|
||||
typedef struct Fts5SegIter Fts5SegIter;
|
||||
typedef struct Fts5DoclistIter Fts5DoclistIter;
|
||||
@ -503,10 +504,16 @@ struct Fts5SegIter {
|
||||
** Used by sqlite3Fts5IterPoslist() when the poslist needs to be buffered.
|
||||
** 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 */
|
||||
Fts5Structure *pStruct; /* Database structure for this iterator */
|
||||
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 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
|
||||
** position-list.
|
||||
*/
|
||||
static int fts5MultiIterIsEmpty(Fts5Index *p, Fts5IndexIter *pIter){
|
||||
static int fts5MultiIterIsEmpty(Fts5Index *p, Fts5Iter *pIter){
|
||||
Fts5SegIter *pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst];
|
||||
return (p->rc==SQLITE_OK && pSeg->pLeaf && pSeg->nPos==0);
|
||||
}
|
||||
@ -2406,7 +2413,7 @@ static void fts5SegIterClear(Fts5SegIter *pIter){
|
||||
** two iterators.
|
||||
*/
|
||||
static void fts5AssertComparisonResult(
|
||||
Fts5IndexIter *pIter,
|
||||
Fts5Iter *pIter,
|
||||
Fts5SegIter *p1,
|
||||
Fts5SegIter *p2,
|
||||
Fts5CResult *pRes
|
||||
@ -2447,7 +2454,7 @@ static void fts5AssertComparisonResult(
|
||||
** statement used to verify that the contents of the pIter->aFirst[] array
|
||||
** are correct.
|
||||
*/
|
||||
static void fts5AssertMultiIterSetup(Fts5Index *p, Fts5IndexIter *pIter){
|
||||
static void fts5AssertMultiIterSetup(Fts5Index *p, Fts5Iter *pIter){
|
||||
if( p->rc==SQLITE_OK ){
|
||||
Fts5SegIter *pFirst = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
|
||||
int i;
|
||||
@ -2492,7 +2499,7 @@ static void fts5AssertMultiIterSetup(Fts5Index *p, Fts5IndexIter *pIter){
|
||||
** to a key that is a duplicate of another, higher priority,
|
||||
** 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 i2; /* Index of right-hand Fts5SegIter */
|
||||
int iRes;
|
||||
@ -2638,7 +2645,7 @@ static void fts5SegIterNextFrom(
|
||||
/*
|
||||
** 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 ){
|
||||
int i;
|
||||
for(i=0; i<pIter->nSeg; i++){
|
||||
@ -2652,7 +2659,7 @@ static void fts5MultiIterFree(Fts5Index *p, Fts5IndexIter *pIter){
|
||||
|
||||
static void fts5MultiIterAdvanced(
|
||||
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 iMinset /* Minimum entry in aFirst[] to set */
|
||||
){
|
||||
@ -2680,8 +2687,9 @@ static void fts5MultiIterAdvanced(
|
||||
*/
|
||||
static int fts5MultiIterAdvanceRowid(
|
||||
Fts5Index *p, /* FTS5 backend to iterate within */
|
||||
Fts5IndexIter *pIter, /* Iterator to update aFirst[] array for */
|
||||
int iChanged /* Index of sub-iterator just advanced */
|
||||
Fts5Iter *pIter, /* Iterator to update aFirst[] array for */
|
||||
int iChanged, /* Index of sub-iterator just advanced */
|
||||
Fts5SegIter **ppFirst
|
||||
){
|
||||
Fts5SegIter *pNew = &pIter->aSeg[iChanged];
|
||||
|
||||
@ -2714,13 +2722,14 @@ static int fts5MultiIterAdvanceRowid(
|
||||
}
|
||||
}
|
||||
|
||||
*ppFirst = pNew;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** 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 ];
|
||||
pIter->bEof = pSeg->pLeaf==0;
|
||||
pIter->iSwitchRowid = pSeg->iRowid;
|
||||
@ -2735,13 +2744,12 @@ static void fts5MultiIterSetEof(Fts5IndexIter *pIter){
|
||||
*/
|
||||
static void fts5MultiIterNext(
|
||||
Fts5Index *p,
|
||||
Fts5IndexIter *pIter,
|
||||
Fts5Iter *pIter,
|
||||
int bFrom, /* True if argument iFrom is valid */
|
||||
i64 iFrom /* Advance at least as far as this */
|
||||
){
|
||||
if( p->rc==SQLITE_OK ){
|
||||
int bUseFrom = bFrom;
|
||||
do {
|
||||
while( p->rc==SQLITE_OK ){
|
||||
int iFirst = pIter->aFirst[1].iFirst;
|
||||
int bNewTerm = 0;
|
||||
Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
|
||||
@ -2753,21 +2761,27 @@ static void fts5MultiIterNext(
|
||||
}
|
||||
|
||||
if( pSeg->pLeaf==0 || bNewTerm
|
||||
|| fts5MultiIterAdvanceRowid(p, pIter, iFirst)
|
||||
|| fts5MultiIterAdvanceRowid(p, pIter, iFirst, &pSeg)
|
||||
){
|
||||
fts5MultiIterAdvanced(p, pIter, iFirst, 1);
|
||||
fts5MultiIterSetEof(pIter);
|
||||
pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst];
|
||||
if( pSeg->pLeaf==0 ) return;
|
||||
}
|
||||
fts5AssertMultiIterSetup(p, pIter);
|
||||
|
||||
fts5AssertMultiIterSetup(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;
|
||||
}while( pIter->bSkipEmpty && fts5MultiIterIsEmpty(p, pIter) );
|
||||
}
|
||||
}
|
||||
|
||||
static void fts5MultiIterNext2(
|
||||
Fts5Index *p,
|
||||
Fts5IndexIter *pIter,
|
||||
Fts5Iter *pIter,
|
||||
int *pbNewTerm /* OUT: True if *might* be new term */
|
||||
){
|
||||
assert( pIter->bSkipEmpty );
|
||||
@ -2780,7 +2794,7 @@ static void fts5MultiIterNext2(
|
||||
assert( p->rc==SQLITE_OK );
|
||||
pSeg->xNext(p, pSeg, &bNewTerm);
|
||||
if( pSeg->pLeaf==0 || bNewTerm
|
||||
|| fts5MultiIterAdvanceRowid(p, pIter, iFirst)
|
||||
|| fts5MultiIterAdvanceRowid(p, pIter, iFirst, &pSeg)
|
||||
){
|
||||
fts5MultiIterAdvanced(p, pIter, iFirst, 1);
|
||||
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 */
|
||||
int nSeg
|
||||
){
|
||||
Fts5IndexIter *pNew;
|
||||
Fts5Iter *pNew;
|
||||
int nSlot; /* Power of two >= nSeg */
|
||||
|
||||
for(nSlot=2; nSlot<nSeg; nSlot=nSlot*2);
|
||||
pNew = fts5IdxMalloc(p,
|
||||
sizeof(Fts5IndexIter) + /* pNew */
|
||||
sizeof(Fts5Iter) + /* pNew */
|
||||
sizeof(Fts5SegIter) * (nSlot-1) + /* pNew->aSeg[] */
|
||||
sizeof(Fts5CResult) * nSlot /* pNew->aFirst[] */
|
||||
);
|
||||
@ -2812,12 +2828,13 @@ static Fts5IndexIter *fts5MultiIterAlloc(
|
||||
pNew->nSeg = nSlot;
|
||||
pNew->aFirst = (Fts5CResult*)&pNew->aSeg[nSlot];
|
||||
pNew->pIndex = p;
|
||||
pNew->xSetOutputs = fts5IterSetOutputs_Noop;
|
||||
}
|
||||
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.
|
||||
** 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) */
|
||||
int iLevel, /* Level to iterate (-1 for all) */
|
||||
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 iIter = 0; /* */
|
||||
int iSeg; /* Used to iterate through segments */
|
||||
Fts5Buffer buf = {0,0,0}; /* Buffer used by fts5SegIterSeekInit() */
|
||||
Fts5StructureLevel *pLvl;
|
||||
Fts5IndexIter *pNew;
|
||||
Fts5Iter *pNew;
|
||||
|
||||
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.
|
||||
*/
|
||||
static void fts5MultiIterNew2(
|
||||
Fts5Index *p, /* FTS5 backend to iterate within */
|
||||
Fts5Data *pData, /* Doclist to iterate through */
|
||||
int bDesc, /* True for descending rowid order */
|
||||
Fts5IndexIter **ppOut /* New object */
|
||||
Fts5Iter **ppOut /* New object */
|
||||
){
|
||||
Fts5IndexIter *pNew;
|
||||
Fts5Iter *pNew;
|
||||
pNew = fts5MultiIterAlloc(p, 2);
|
||||
if( pNew ){
|
||||
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.
|
||||
** False otherwise.
|
||||
*/
|
||||
static int fts5MultiIterEof(Fts5Index *p, Fts5IndexIter *pIter){
|
||||
static int fts5MultiIterEof(Fts5Index *p, Fts5Iter *pIter){
|
||||
assert( p->rc
|
||||
|| (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
|
||||
** results are undefined.
|
||||
*/
|
||||
static i64 fts5MultiIterRowid(Fts5IndexIter *pIter){
|
||||
static i64 fts5MultiIterRowid(Fts5Iter *pIter){
|
||||
assert( pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf );
|
||||
return pIter->aSeg[ pIter->aFirst[1].iFirst ].iRowid;
|
||||
}
|
||||
@ -2983,7 +3000,7 @@ static i64 fts5MultiIterRowid(Fts5IndexIter *pIter){
|
||||
*/
|
||||
static void fts5MultiIterNextFrom(
|
||||
Fts5Index *p,
|
||||
Fts5IndexIter *pIter,
|
||||
Fts5Iter *pIter,
|
||||
i64 iMatch
|
||||
){
|
||||
while( 1 ){
|
||||
@ -3000,7 +3017,7 @@ static void fts5MultiIterNextFrom(
|
||||
** Return a pointer to a buffer containing the term associated with the
|
||||
** 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 ];
|
||||
*pn = p->term.n;
|
||||
return p->term.p;
|
||||
@ -3582,7 +3599,7 @@ static void fts5WriteInit(
|
||||
** incremental merge operation. This function is called if the incremental
|
||||
** 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;
|
||||
Fts5Buffer buf;
|
||||
memset(&buf, 0, sizeof(Fts5Buffer));
|
||||
@ -3660,7 +3677,7 @@ static void fts5IndexMergeLevel(
|
||||
Fts5Structure *pStruct = *ppStruct;
|
||||
Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
|
||||
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 nInput; /* Number of input segments */
|
||||
Fts5SegWriter writer; /* Writer object */
|
||||
@ -4342,7 +4359,7 @@ static int fts5IndexExtractCol(
|
||||
static int fts5AppendRowid(
|
||||
Fts5Index *p,
|
||||
i64 iDelta,
|
||||
Fts5IndexIter *pMulti,
|
||||
Fts5Iter *pMulti,
|
||||
Fts5Colset *pColset,
|
||||
Fts5Buffer *pBuf
|
||||
){
|
||||
@ -4367,7 +4384,7 @@ static int fts5AppendRowid(
|
||||
static int fts5AppendPoslist(
|
||||
Fts5Index *p,
|
||||
i64 iDelta,
|
||||
Fts5IndexIter *pMulti,
|
||||
Fts5Iter *pMulti,
|
||||
Fts5Colset *pColset,
|
||||
Fts5Buffer *pBuf
|
||||
){
|
||||
@ -4645,14 +4662,14 @@ static void fts5SetupPrefixIter(
|
||||
const u8 *pToken, /* Buffer containing prefix to match */
|
||||
int nToken, /* Size of buffer pToken in bytes */
|
||||
Fts5Colset *pColset, /* Restrict matches to these columns */
|
||||
Fts5IndexIter **ppIter /* OUT: New iterator */
|
||||
Fts5Iter **ppIter /* OUT: New iterator */
|
||||
){
|
||||
Fts5Structure *pStruct;
|
||||
Fts5Buffer *aBuf;
|
||||
const int nBuf = 32;
|
||||
|
||||
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 ){
|
||||
xMerge = fts5MergeRowidLists;
|
||||
xAppend = fts5AppendRowid;
|
||||
@ -4668,7 +4685,7 @@ static void fts5SetupPrefixIter(
|
||||
const int flags = FTS5INDEX_QUERY_SCAN;
|
||||
int i;
|
||||
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;
|
||||
Fts5Buffer doclist;
|
||||
int bNewTerm = 1;
|
||||
@ -4932,6 +4949,179 @@ int sqlite3Fts5IndexWrite(
|
||||
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
|
||||
** specified token or token prefix.
|
||||
@ -4944,22 +5134,27 @@ int sqlite3Fts5IndexQuery(
|
||||
Fts5IndexIter **ppIter /* OUT: New iterator object */
|
||||
){
|
||||
Fts5Config *pConfig = p->pConfig;
|
||||
Fts5IndexIter *pRet = 0;
|
||||
int iIdx = 0;
|
||||
Fts5Iter *pRet = 0;
|
||||
Fts5Buffer buf = {0, 0, 0};
|
||||
|
||||
/* If the QUERY_SCAN flag is set, all other flags must be clear. */
|
||||
assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN );
|
||||
|
||||
if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){
|
||||
int iIdx = 0; /* Index to search */
|
||||
memcpy(&buf.p[1], pToken, nToken);
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
/* If the QUERY_TEST_NOIDX flag was specified, then this must be a
|
||||
/* Figure out which index to search and set iIdx accordingly. If this
|
||||
** 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),
|
||||
** evaluate the prefix query using the main FTS index. This is used
|
||||
** for internal sanity checking by the integrity-check in debug
|
||||
** mode only. */
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( pConfig->bPrefixIndex==0 || (flags & FTS5INDEX_QUERY_TEST_NOIDX) ){
|
||||
assert( flags & FTS5INDEX_QUERY_PREFIX );
|
||||
iIdx = 1+pConfig->nPrefix;
|
||||
@ -4973,6 +5168,7 @@ int sqlite3Fts5IndexQuery(
|
||||
}
|
||||
|
||||
if( iIdx<=pConfig->nPrefix ){
|
||||
/* Straight index lookup */
|
||||
Fts5Structure *pStruct = fts5StructureRead(p);
|
||||
buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx);
|
||||
if( pStruct ){
|
||||
@ -4980,17 +5176,25 @@ int sqlite3Fts5IndexQuery(
|
||||
fts5StructureRelease(pStruct);
|
||||
}
|
||||
}else{
|
||||
/* Scan multiple terms in the main index */
|
||||
int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0;
|
||||
buf.p[0] = FTS5_MAIN_PREFIX;
|
||||
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 ){
|
||||
sqlite3Fts5IterClose(pRet);
|
||||
sqlite3Fts5IterClose(&pRet->base);
|
||||
pRet = 0;
|
||||
fts5CloseReader(p);
|
||||
}
|
||||
*ppIter = pRet;
|
||||
|
||||
*ppIter = &pRet->base;
|
||||
sqlite3Fts5BufferFree(&buf);
|
||||
}
|
||||
return fts5IndexReturn(p);
|
||||
@ -5000,14 +5204,15 @@ int sqlite3Fts5IndexQuery(
|
||||
** Return true if the iterator passed as the only argument is at EOF.
|
||||
*/
|
||||
int sqlite3Fts5IterEof(Fts5IndexIter *pIter){
|
||||
assert( pIter->pIndex->rc==SQLITE_OK );
|
||||
return pIter->bEof;
|
||||
assert( ((Fts5Iter*)pIter)->pIndex->rc==SQLITE_OK );
|
||||
return ((Fts5Iter*)pIter)->bEof;
|
||||
}
|
||||
|
||||
/*
|
||||
** Move to the next matching rowid.
|
||||
*/
|
||||
int sqlite3Fts5IterNext(Fts5IndexIter *pIter){
|
||||
int sqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){
|
||||
Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
|
||||
assert( pIter->pIndex->rc==SQLITE_OK );
|
||||
fts5MultiIterNext(pIter->pIndex, pIter, 0, 0);
|
||||
return fts5IndexReturn(pIter->pIndex);
|
||||
@ -5016,7 +5221,8 @@ int sqlite3Fts5IterNext(Fts5IndexIter *pIter){
|
||||
/*
|
||||
** 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;
|
||||
|
||||
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
|
||||
** 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);
|
||||
return fts5IndexReturn(pIter->pIndex);
|
||||
}
|
||||
@ -5047,121 +5254,26 @@ int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIter, i64 iMatch){
|
||||
/*
|
||||
** Return the current rowid.
|
||||
*/
|
||||
i64 sqlite3Fts5IterRowid(Fts5IndexIter *pIter){
|
||||
return fts5MultiIterRowid(pIter);
|
||||
i64 sqlite3Fts5IterRowid(Fts5IndexIter *pIndexIter){
|
||||
return fts5MultiIterRowid((Fts5Iter*)pIndexIter);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the current term.
|
||||
*/
|
||||
const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIter, int *pn){
|
||||
const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){
|
||||
int n;
|
||||
const char *z = (const char*)fts5MultiIterTerm(pIter, &n);
|
||||
const char *z = (const char*)fts5MultiIterTerm((Fts5Iter*)pIndexIter, &n);
|
||||
*pn = n-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().
|
||||
*/
|
||||
void sqlite3Fts5IterClose(Fts5IndexIter *pIter){
|
||||
if( pIter ){
|
||||
void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){
|
||||
if( pIndexIter ){
|
||||
Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
|
||||
Fts5Index *pIndex = pIter->pIndex;
|
||||
fts5MultiIterFree(pIter->pIndex, pIter);
|
||||
fts5CloseReader(pIndex);
|
||||
@ -5328,20 +5440,17 @@ static int fts5QueryCksum(
|
||||
){
|
||||
int eDetail = p->pConfig->eDetail;
|
||||
u64 cksum = *pCksum;
|
||||
Fts5IndexIter *pIdxIter = 0;
|
||||
Fts5Buffer buf = {0, 0, 0};
|
||||
int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIdxIter);
|
||||
Fts5IndexIter *pIter = 0;
|
||||
int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIter);
|
||||
|
||||
while( rc==SQLITE_OK && 0==sqlite3Fts5IterEof(pIdxIter) ){
|
||||
i64 rowid = sqlite3Fts5IterRowid(pIdxIter);
|
||||
while( rc==SQLITE_OK && 0==sqlite3Fts5IterEof(pIter) ){
|
||||
i64 rowid = sqlite3Fts5IterRowid(pIter);
|
||||
|
||||
if( eDetail==FTS5_DETAIL_NONE ){
|
||||
cksum ^= sqlite3Fts5IndexEntryCksum(rowid, 0, 0, iIdx, z, n);
|
||||
}else{
|
||||
rc = sqlite3Fts5IterPoslistBuffer(pIdxIter, &buf);
|
||||
if( rc==SQLITE_OK ){
|
||||
Fts5PoslistReader sReader;
|
||||
for(sqlite3Fts5PoslistReaderInit(buf.p, buf.n, &sReader);
|
||||
for(sqlite3Fts5PoslistReaderInit(pIter->pData, pIter->nData, &sReader);
|
||||
sReader.bEof==0;
|
||||
sqlite3Fts5PoslistReaderNext(&sReader)
|
||||
){
|
||||
@ -5350,13 +5459,11 @@ static int fts5QueryCksum(
|
||||
cksum ^= sqlite3Fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3Fts5IterNext(pIdxIter);
|
||||
rc = sqlite3Fts5IterNext(pIter);
|
||||
}
|
||||
}
|
||||
sqlite3Fts5IterClose(pIdxIter);
|
||||
fts5BufferFree(&buf);
|
||||
sqlite3Fts5IterClose(pIter);
|
||||
|
||||
*pCksum = cksum;
|
||||
return rc;
|
||||
@ -5661,7 +5768,7 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){
|
||||
int eDetail = p->pConfig->eDetail;
|
||||
u64 cksum2 = 0; /* Checksum based on contents of indexes */
|
||||
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 */
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
|
@ -538,7 +538,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
|
||||
for(i=0; i<pInfo->nConstraint; i++){
|
||||
struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
|
||||
int j;
|
||||
for(j=0; j<(int)ArraySize(aConstraint); j++){
|
||||
for(j=0; j<ArraySize(aConstraint); j++){
|
||||
struct Constraint *pC = &aConstraint[j];
|
||||
if( p->iColumn==aColMap[pC->iCol] && p->op & pC->op ){
|
||||
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. */
|
||||
iNext = 1;
|
||||
for(i=0; i<(int)ArraySize(aConstraint); i++){
|
||||
for(i=0; i<ArraySize(aConstraint); i++){
|
||||
struct Constraint *pC = &aConstraint[i];
|
||||
if( pC->iConsIndex>=0 ){
|
||||
pInfo->aConstraintUsage[pC->iConsIndex].argvIndex = iNext++;
|
||||
|
@ -338,7 +338,7 @@ int sqlite3Fts5StorageClose(Fts5Storage *p){
|
||||
int i;
|
||||
|
||||
/* Finalize all SQL statements */
|
||||
for(i=0; i<(int)ArraySize(p->aStmt); i++){
|
||||
for(i=0; i<ArraySize(p->aStmt); i++){
|
||||
sqlite3_finalize(p->aStmt[i]);
|
||||
}
|
||||
|
||||
|
@ -1220,7 +1220,7 @@ int sqlite3Fts5TokenizerInit(fts5_api *pApi){
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
int i; /* To iterate through builtin functions */
|
||||
|
||||
for(i=0; rc==SQLITE_OK && i<(int)ArraySize(aBuiltin); i++){
|
||||
for(i=0; rc==SQLITE_OK && i<ArraySize(aBuiltin); i++){
|
||||
rc = pApi->xCreateTokenizer(pApi,
|
||||
aBuiltin[i].zName,
|
||||
(void*)pApi,
|
||||
|
@ -184,7 +184,7 @@ static int fts5VocabInitVtab(
|
||||
|
||||
rc = fts5VocabTableType(zType, pzErr, &eType);
|
||||
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]);
|
||||
}
|
||||
|
||||
@ -407,15 +407,16 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
|
||||
|
||||
assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW );
|
||||
while( rc==SQLITE_OK ){
|
||||
i64 dummy;
|
||||
const u8 *pPos; int nPos; /* Position list */
|
||||
i64 iPos = 0; /* 64-bit position read from poslist */
|
||||
int iOff = 0; /* Current offset within position list */
|
||||
|
||||
pPos = pCsr->pIter->pData;
|
||||
nPos = pCsr->pIter->nData;
|
||||
switch( pCsr->pConfig->eDetail ){
|
||||
case FTS5_DETAIL_FULL:
|
||||
rc = sqlite3Fts5IterPoslist(pCsr->pIter, 0, &pPos, &nPos, &dummy);
|
||||
if( rc==SQLITE_OK ){
|
||||
pPos = pCsr->pIter->pData;
|
||||
nPos = pCsr->pIter->nData;
|
||||
if( pTab->eType==FTS5_VOCAB_ROW ){
|
||||
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
|
||||
pCsr->aCnt[0]++;
|
||||
@ -436,17 +437,13 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case FTS5_DETAIL_COLUMNS:
|
||||
if( pTab->eType==FTS5_VOCAB_ROW ){
|
||||
pCsr->aDoc[0]++;
|
||||
}else{
|
||||
Fts5Buffer buf = {0, 0, 0};
|
||||
rc = sqlite3Fts5IterPoslistBuffer(pCsr->pIter, &buf);
|
||||
if( rc==SQLITE_OK ){
|
||||
while( 0==sqlite3Fts5PoslistNext64(buf.p, buf.n, &iOff,&iPos) ){
|
||||
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff,&iPos) ){
|
||||
assert_nc( iPos>=0 && iPos<nCol );
|
||||
if( iPos>=nCol ){
|
||||
rc = FTS5_CORRUPT;
|
||||
@ -455,8 +452,6 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
|
||||
pCsr->aDoc[iPos]++;
|
||||
}
|
||||
}
|
||||
sqlite3Fts5BufferFree(&buf);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -48,7 +48,8 @@ proc fts5_test_poslist2 {cmd} {
|
||||
}
|
||||
}
|
||||
|
||||
set res
|
||||
#set res
|
||||
sort_poslist $res
|
||||
}
|
||||
|
||||
proc fts5_test_collist {cmd} {
|
||||
|
@ -158,8 +158,8 @@ foreach {tn2 sql} {
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
foreach {tn expr} {
|
||||
1.2 "a OR b"
|
||||
1.1 "a AND b"
|
||||
1.2 "a OR b"
|
||||
1.3 "o"
|
||||
1.4 "b q"
|
||||
1.5 "e a e"
|
||||
@ -250,7 +250,6 @@ foreach {tn2 sql} {
|
||||
FROM xx WHERE xx match $expr
|
||||
} $res
|
||||
|
||||
|
||||
set res [fts5_query_data $expr xx DESC]
|
||||
do_execsql_test 1.$tn2.$tn.[llength $res].desc {
|
||||
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_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] }
|
||||
sqlite3_fts5_create_function db fts5_rowid fts5_rowid
|
||||
|
||||
@ -89,6 +104,8 @@ do_execsql_test 1.$tok.0.2 {
|
||||
}
|
||||
|
||||
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.5 "v" 1.6 "vi" 1.7 "vii" 1.8 "viii"
|
||||
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]
|
||||
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
|
||||
|
||||
do_execsql_test 1.$tok.$tn.[llength $res].asc.2 {
|
||||
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
|
||||
} $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 '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*'"}
|
||||
|
||||
{2 "SELECT count(*) FROM t1 WHERE t1 MATCH 'c:the'"}
|
||||
}
|
||||
|
||||
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 ""
|
||||
puts stderr "Options are"
|
||||
puts stderr " -fts5"
|
||||
puts stderr " -fts4"
|
||||
puts stderr " -colsize <list of column sizes>"
|
||||
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 "Switches are:"
|
||||
foreach o $O {
|
||||
if {[llength $o]==3} {
|
||||
foreach {a b c} $o {}
|
||||
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.
|
||||
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
|
||||
@ -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
|
||||
is exhausted.
|
||||
}
|
||||
exit -1
|
||||
|
||||
if {$A(fts4)} {
|
||||
set A(fts) fts4
|
||||
} else {
|
||||
set A(fts) fts5
|
||||
}
|
||||
|
||||
set O(aColSize) [list 10 10 10]
|
||||
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)
|
||||
sqlite3 db $A(database)
|
||||
|
||||
# Create the FTS table in the db. Return a list of the table columns.
|
||||
#
|
||||
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 nCol [llength $O(aColSize)]
|
||||
set nCol [llength $A(colsize)]
|
||||
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 ");"
|
||||
if {$A(fts)=="fts5"} { append sql ",detail=$A(detail));" }
|
||||
|
||||
db eval $sql
|
||||
return $cols
|
||||
@ -89,27 +171,35 @@ proc readfile {file} {
|
||||
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.
|
||||
#
|
||||
set tokens [list]
|
||||
foreach f $O(files) {
|
||||
set tokens [concat $tokens [readfile $f]]
|
||||
foreach f $A(file) {
|
||||
set tokens [concat $tokens [repeat [readfile $f] $A(repeat)]]
|
||||
}
|
||||
|
||||
set N [llength $tokens]
|
||||
set i 0
|
||||
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] {
|
||||
append sql ", \$A($c)"
|
||||
append sql ", \$R($c)"
|
||||
}
|
||||
append sql ")"
|
||||
|
||||
db eval BEGIN
|
||||
while {$i < $N} {
|
||||
foreach c $cols s $O(aColSize) {
|
||||
set A($c) [lrange $tokens $i [expr $i+$s-1]]
|
||||
foreach c $cols s $A(colsize) {
|
||||
set R($c) [lrange $tokens $i [expr $i+$s-1]]
|
||||
incr i $s
|
||||
}
|
||||
db eval $sql
|
||||
|
@ -365,8 +365,8 @@ static int editdist1(const char *zA, const char *zB, int *pnMatch){
|
||||
int *m; /* The cost matrix */
|
||||
char *cx; /* Corresponding character values */
|
||||
int *toFree = 0; /* Malloced space */
|
||||
int mStack[60+15]; /* Stack space to use if not too much is needed */
|
||||
int nMatch = 0;
|
||||
int mStack[60+15]; /* Stack space to use if not too much is needed */
|
||||
|
||||
/* Early out if either input is NULL */
|
||||
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.
|
||||
**
|
||||
** If an error occurs, return a negative number which is the error code.
|
||||
@ -899,15 +910,24 @@ static int editDist3Core(
|
||||
EditDist3FromString f = *pFrom;
|
||||
EditDist3To *a2;
|
||||
unsigned int *m;
|
||||
unsigned int *pToFree;
|
||||
int szRow;
|
||||
EditDist3Cost *p;
|
||||
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 */
|
||||
n = (f.n+1)*(n2+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( 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];
|
||||
memset(a2, 0, sizeof(a2[0])*n2);
|
||||
|
||||
@ -1029,7 +1049,7 @@ static int editDist3Core(
|
||||
|
||||
editDist3Abort:
|
||||
for(i2=0; i2<n2; i2++) sqlite3_free(a2[i2].apIns);
|
||||
sqlite3_free(m);
|
||||
sqlite3_free(pToFree);
|
||||
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.
|
||||
D 2016-01-21T17:06:33.267
|
||||
F Makefile.in 7be88f5b473891e3a8c07245ed60535fcda4f9ee
|
||||
C Merge\sall\srecent\strunk\senhancements.
|
||||
D 2016-01-26T23:32:55.750
|
||||
F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc c5ead4aa22ff6f528c755b07ed1e31184ac5b3d2
|
||||
F Makefile.msc 6fca5455aaecbd14479f33f091aa19df2d3d2969
|
||||
F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7
|
||||
F VERSION 866588d1edf0ccb5b0d33896974338f97564f719
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
@ -10,9 +10,10 @@ F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
|
||||
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
|
||||
F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
|
||||
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
|
||||
F autoconf/Makefile.am 089e5ecdb5761e64ea1013ded02feb4d8b29927d
|
||||
F autoconf/README 14458f1046c118efa721aadec5f227e876d3cd38
|
||||
F autoconf/Makefile.am 1c1657650775960804945dc392e14d9e43c5ed84
|
||||
F autoconf/Makefile.msc 68ed752a809b611d97b95d8572a34fe6fd1196f1
|
||||
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
|
||||
F autoconf/README.txt e9757a381e5ce2553dbaa6247bb8ad00eb8d87aa w autoconf/README
|
||||
F autoconf/configure.ac 7b1ea0dcaf49fafba262ce4b0ee8cb3281b555d1
|
||||
F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd
|
||||
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/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
|
||||
F ext/fts5/fts5.h ff9c2782e8ed890b0de2f697a8d63971939e70c7
|
||||
F ext/fts5/fts5Int.h 5599703af9c13512900a9f22fec39d48078d619d
|
||||
F ext/fts5/fts5_aux.c 2dafc3aee0c70d643140c77d8d70daffa51a9e9e
|
||||
F ext/fts5/fts5_buffer.c 7d3f6f01f8fdc45204e6a33925ef8478a67d28dd
|
||||
F ext/fts5/fts5Int.h 6e0f90eb4872654a5b98130dec16965716525c9a
|
||||
F ext/fts5/fts5_aux.c b9bcce753ef5b451267b2232f0ca153ddeb3951d
|
||||
F ext/fts5/fts5_buffer.c f6e0c6018ffc8e39fc0b333b5daa8b8d528ae6e4
|
||||
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_index.c 716c301835a122ba36910b4f821c87d26ae9a5d9
|
||||
F ext/fts5/fts5_main.c 833db0a3df10ab26e0221a9baa40cf871c450df3
|
||||
F ext/fts5/fts5_storage.c fb2eaec3aa954b680d43096dc539f8270bd6390e
|
||||
F ext/fts5/fts5_index.c 5558bfbeaf364cc67f937e25753ceed8757cb6d1
|
||||
F ext/fts5/fts5_main.c 3886bbfc5ac1d9df29979823ddf2b68241e1127e
|
||||
F ext/fts5/fts5_storage.c 2a1f44deae090cd711f02cec0c2af8e660360d24
|
||||
F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966
|
||||
F ext/fts5/fts5_test_mi.c 1ec66ffdf7632077fbd773b7a6df5153272ec070
|
||||
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_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/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/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/fts5ae.test 612dcb51f4069226791ff14c17dbfb3138c56f20
|
||||
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/fts5simple.test 2bc6451cbe887a9215f5b14ae307c70d850344c9
|
||||
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/fts5synonym2.test eadb00c73ef0653258873e756b7e9102e0687539
|
||||
F ext/fts5/test/fts5synonym2.test aa4c43bd3b691ff80f658cb064f5ab40690e834e
|
||||
F ext/fts5/test/fts5tok1.test beb894c6f3468f10a574302f69ebe4436b0287c7
|
||||
F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2
|
||||
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/fts5version.test 978f59541d8cef7e8591f8be2115ec5ccb863e2e
|
||||
F ext/fts5/test/fts5vocab.test 480d780aa6b699816c5066225fbd86f3a0239477
|
||||
F ext/fts5/tool/fts5speed.tcl aaee41894b552df8fbf8616aad003b2ea9ba3221
|
||||
F ext/fts5/tool/fts5txt2db.tcl c374c4c4797e8cdfadabdfaeeb5412dcd6686e84
|
||||
F ext/fts5/tool/fts5speed.tcl 47f0031e6ac564964f4f4805e439ea665e848df2
|
||||
F ext/fts5/tool/fts5txt2db.tcl ae308338b2da1646dea456ab66706acdde8c714e
|
||||
F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093
|
||||
F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45
|
||||
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/series.c b8fb7befd85b3a9b4a10e701b30b2b79ca92b6d4
|
||||
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/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
|
||||
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
|
||||
@ -291,16 +293,16 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73
|
||||
F src/btree.c 97cf881292e085ee71faf44f7167b6312965b562
|
||||
F src/btree.h c5dfbbc59226fa5fcc2b03befa85fe10ef23c1b5
|
||||
F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5
|
||||
F src/build.c 31af80bba31ac159967951ef58f3144cc7db9d70
|
||||
F src/build.c b4eba1e84752ec9cae7ff3dacd5a8b6d1ab8deb9
|
||||
F src/callback.c 29ae4faba226c7ebb9aee93016b5ce8a8f071261
|
||||
F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
|
||||
F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198
|
||||
F src/date.c 997651e3ee6c2818fbf7fcdb7156cef9eb3ece20
|
||||
F src/dbstat.c ffd63fc8ba7541476ced189b95e95d7f2bc63f78
|
||||
F src/dbstat.c b2ec6793eef97aebb4d171d490a4ffdfa9f2475c
|
||||
F src/delete.c f02e46234c5fc86f6c03ae34dc0ba48e93cd5029
|
||||
F src/expr.c df0d7c3230d59abd679da22ff5ce4cfd0e3a0e63
|
||||
F src/expr.c d10c1cdef5810cdbf73adc9f9b383684230b360a
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c e18b3dff7d47c7bcac5ac4fc178a89b9fd322b44
|
||||
F src/fkey.c c66d3e5b35d4d95b5c1e2ee6c12f5df13a7f9ad6
|
||||
F src/func.c ba6c03f9e440f5693086c08ee88e6e60212b3504
|
||||
F src/global.c bd5a0af3f30b0c01be6db756c626cd3c33a3d260
|
||||
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
|
||||
@ -316,7 +318,7 @@ F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
|
||||
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
|
||||
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
|
||||
F src/mem5.c 71f81a11fc5e29a57428761ab38a7bf2ef4ee19d
|
||||
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
|
||||
F src/memjournal.c 3eb2c0b51adbd869cb6a44780323f05fa904dc85
|
||||
F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495
|
||||
F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c
|
||||
@ -329,10 +331,10 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8
|
||||
F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf
|
||||
F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e
|
||||
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
||||
F src/os_unix.c b509b49b40a269e7b75ab511b6e92b2dc9444359
|
||||
F src/os_unix.c 5bb20172d0c9a6afcfa829a88c406970593c848d
|
||||
F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811
|
||||
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
||||
F src/pager.c f4e9ac39fbb1e0fde97af85c0f4e00eb90764b67
|
||||
F src/pager.c 2916c66aee50f69d9ec56a7619b62d9c6a3bee61
|
||||
F src/pager.h 1c2a49143dfba9e69cc8159ef019f472ed8d260b
|
||||
F src/parse.y caad1e98edeca6960493d0c60d31b76820dd7776
|
||||
F src/pcache.c 73895411fa6b7bd6f0091212feabbe833b358d23
|
||||
@ -340,21 +342,21 @@ F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545
|
||||
F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051
|
||||
F src/pragma.c ea290193369faa0a26ae2f924e7b86289b4a7987
|
||||
F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c
|
||||
F src/prepare.c 74855ddbdfad6a1c4a4d5c4b0913ebb01174ba19
|
||||
F src/prepare.c 8ca7237428f372a04717d558555ea67ee1c5df93
|
||||
F src/printf.c af589a27b7d40f6f4f704e9eea99f02f18ad6d32
|
||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||
F src/resolve.c 9f7ce3a3c087afb7597b7c916c99126ff3f12f0c
|
||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||
F src/select.c 718954db86277d696c520fe671148db1e9c4ed3c
|
||||
F src/select.c c34292c8ce7fe69c7cf890d933834a22572bd301
|
||||
F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4
|
||||
F src/sqlite.h.in 214476a62012e578f42133a9a3b4f97a9aa421a3
|
||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d
|
||||
F src/sqliteInt.h 46e0bac7a3cdab96e8b5afd1436accc25d2c3d6a
|
||||
F src/sqliteInt.h 0faffdeed20201bedb202cf6ec07f14b29158c66
|
||||
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
|
||||
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
|
||||
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
|
||||
F src/tclsqlite.c 82979239a896992f9b78efec81cfda05d316a7d0
|
||||
F src/tclsqlite.c 94ef6e2794220c5b6064d4c78ec7169a8c5cc45d
|
||||
F src/test1.c 4f1b42699068b7806af3111786f5ad760c2c1ff7
|
||||
F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b
|
||||
F src/test3.c a8887dabbbee3059af338f20d290084a63ed1b0f
|
||||
@ -405,22 +407,22 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c bbfb74450643cb5372a43ad4f6cffd7e9dfcecb0
|
||||
F src/tokenize.c 5606871a377f390af7040ec3c12e0d183512d785
|
||||
F src/treeview.c 78842e90c1f71269e7a73a1d4221b6fe360bab66
|
||||
F src/trigger.c 056e51182a3677434423e3be0c74e61b90b4a663
|
||||
F src/trigger.c 72d876b2d0c66604a112362bdae07dae9b104816
|
||||
F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3
|
||||
F src/utf.c 32d7f82aa921322f3e1c956f4b58f019ebd2c6b3
|
||||
F src/util.c e802e8e311a0d6c48cd1b3e89db164f6f0248d70
|
||||
F src/util.c 72d40df0a52d3f30b462a15f0e094fcbade6dc82
|
||||
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
|
||||
F src/vdbe.c e21a506d17a7397cba16c162d8c9c96e9769c68e
|
||||
F src/vdbe.c 6039096edea4ed25f7b1e28aa5d46b0ee3ba73ef
|
||||
F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337
|
||||
F src/vdbeInt.h 42eefa4f9e7432b9968d321b44e48821ec13b189
|
||||
F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e
|
||||
F src/vdbeaux.c 07f8f485a6cbc0a62da660f14e303061d45d5cb6
|
||||
F src/vdbeaux.c 757f86e6fef8efb3dd4226cb31e2e82b9c44c883
|
||||
F src/vdbeblob.c 37c3d11a753e403698c69e17383d282e1ae73e75
|
||||
F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0
|
||||
F src/vdbesort.c 0971557e5d3c289e46f56a52aed2197c13251de7
|
||||
F src/vdbesort.c 3bb1f1f03162e6d223da623714d8e93fcaeac658
|
||||
F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0
|
||||
F src/vtab.c 320682cca733115b4cbe71320b5c5eeb1074ebde
|
||||
F src/vxworks.h 974e7d9a98f602d6310d563e1dc4e08f9fc48e47
|
||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c d21b99fd1458159d0b1ecdccc8ee6ada4fdc4c54
|
||||
F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c
|
||||
F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354
|
||||
@ -924,7 +926,7 @@ F test/orderby6.test 8b38138ab0972588240b3fca0985d2e400432859
|
||||
F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da
|
||||
F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd
|
||||
F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3
|
||||
F test/oserror.test 361346396ae18462c7393c1ac5c3f17237bd89b2
|
||||
F test/oserror.test b32dc34f2363ef18532e3a0a7358e3e7e321974f
|
||||
F test/ovfl.test 4f7ca651cba5c059a12d8c67dddd49bec5747799
|
||||
F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa
|
||||
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
|
||||
@ -1052,7 +1054,7 @@ F test/spellfix3.test f7bf7b3482971473d32b6b00f6944c5c066cff97
|
||||
F test/sqldiff1.test 8f6bc7c6a5b3585d350d779c6078869ba402f8f5
|
||||
F test/sqllimits1.test a74ee2a3740b9f9c2437c246d8fb77354862a142
|
||||
F test/sqllog.test a8faa2df39610a037dd372ed872d124260d32953
|
||||
F test/stat.test 8de91498c99f5298b303f70f1d1f3b9557af91bf
|
||||
F test/stat.test fafe6e82dfdb97d8c8be31cd83e36e973079ce0f
|
||||
F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1
|
||||
F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
|
||||
F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f
|
||||
@ -1061,9 +1063,9 @@ F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
|
||||
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
|
||||
F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8
|
||||
F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2
|
||||
F test/symlink.test cbf6cb8c6c4b63a39e9f0f6b0d5c99e249dbc102
|
||||
F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849
|
||||
F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85
|
||||
F test/syscall.test 2aa9e111b79fb385681ff8940124def6f8faab87
|
||||
F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c
|
||||
F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04
|
||||
F test/tabfunc01.test cc33684f9480fcf1fd5ce287ac28d22971cad1cc
|
||||
F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f
|
||||
@ -1376,8 +1378,9 @@ F tool/lemon.c 799e73e19a33b8dd7767a7fa34618ed2a9c2397d
|
||||
F tool/lempar.c 3ec1463a034b37d87d782be5f6b8b10a3b1ecbe7
|
||||
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
|
||||
F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6
|
||||
F tool/mkautoconfamal.sh 5a5441280b509d2bb3bdc71bfb63781b0d570373
|
||||
F tool/mkautoconfamal.sh a29b14d54302b33fd892958f6895582ea90e4a45
|
||||
F tool/mkkeywordhash.c 06ec0b78bd4fa68c12d90ef2bdfe76b039133ff8
|
||||
F tool/mkmsvcmin.tcl 93167a9e73383465b5716aa8dfa407409fccef1d
|
||||
F tool/mkopcodec.tcl edde8adc42621b5e598127f8cdc6d52cfe21f52b
|
||||
F tool/mkopcodeh.tcl e04177031532b7aa9379ded50e820231ac4abd6e
|
||||
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
|
||||
@ -1419,10 +1422,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P a3cec529f0238e4ca1196fec420f2de80d28db78
|
||||
R 76198b2176fddd32b1fb9b7a5f18b4c8
|
||||
T *branch * btree-fordelete-flag
|
||||
T *sym-btree-fordelete-flag *
|
||||
T -sym-trunk *
|
||||
P ac2cbadd8000947c097da5b00c00090fe58fdcff a3d7b8ac53f94d29a11362f193fd1967f30583df
|
||||
R 7855243eb7d1aae3e5a98345ca05c333
|
||||
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 ){
|
||||
ExprList *pList;
|
||||
Token ipkToken;
|
||||
ipkToken.z = pTab->aCol[pTab->iPKey].zName;
|
||||
ipkToken.n = sqlite3Strlen30(ipkToken.z);
|
||||
sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zName);
|
||||
pList = sqlite3ExprListAppend(pParse, 0,
|
||||
sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0));
|
||||
if( pList==0 ) return;
|
||||
@ -3057,8 +3056,7 @@ Index *sqlite3CreateIndex(
|
||||
*/
|
||||
if( pList==0 ){
|
||||
Token prevCol;
|
||||
prevCol.z = pTab->aCol[pTab->nCol-1].zName;
|
||||
prevCol.n = sqlite3Strlen30(prevCol.z);
|
||||
sqlite3TokenInit(&prevCol, pTab->aCol[pTab->nCol-1].zName);
|
||||
pList = sqlite3ExprListAppend(pParse, 0,
|
||||
sqlite3ExprAlloc(db, TK_ID, &prevCol, 0));
|
||||
if( pList==0 ) goto exit_create_index;
|
||||
|
@ -149,7 +149,9 @@ static int statConnect(
|
||||
int iDb;
|
||||
|
||||
if( argc>=4 ){
|
||||
iDb = sqlite3FindDbName(db, argv[3]);
|
||||
Token nm;
|
||||
sqlite3TokenInit(&nm, (char*)argv[3]);
|
||||
iDb = sqlite3FindDb(db, &nm);
|
||||
if( iDb<0 ){
|
||||
*pzErr = sqlite3_mprintf("no such database: %s", argv[3]);
|
||||
return SQLITE_ERROR;
|
||||
|
@ -85,8 +85,7 @@ Expr *sqlite3ExprAddCollateToken(
|
||||
Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
|
||||
Token s;
|
||||
assert( zC!=0 );
|
||||
s.z = zC;
|
||||
s.n = sqlite3Strlen30(s.z);
|
||||
sqlite3TokenInit(&s, (char*)zC);
|
||||
return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0);
|
||||
}
|
||||
|
||||
|
@ -1192,11 +1192,9 @@ static Trigger *fkActionTrigger(
|
||||
assert( iFromCol>=0 );
|
||||
assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKey<pTab->nCol) );
|
||||
assert( pIdx==0 || pIdx->aiColumn[i]>=0 );
|
||||
tToCol.z = pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName;
|
||||
tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName;
|
||||
|
||||
tToCol.n = sqlite3Strlen30(tToCol.z);
|
||||
tFromCol.n = sqlite3Strlen30(tFromCol.z);
|
||||
sqlite3TokenInit(&tToCol,
|
||||
pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName);
|
||||
sqlite3TokenInit(&tFromCol, pFKey->pFrom->aCol[iFromCol].zName);
|
||||
|
||||
/* Create the expression "OLD.zToCol = zFromCol". It is important
|
||||
** that the "OLD.zToCol" term is on the LHS of the = operator, so
|
||||
|
@ -322,11 +322,11 @@ static void memsys5FreeUnsafe(void *pOld){
|
||||
int iBuddy;
|
||||
if( (iBlock>>iLogsize) & 1 ){
|
||||
iBuddy = iBlock - size;
|
||||
assert( iBuddy>=0 );
|
||||
}else{
|
||||
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;
|
||||
memsys5Unlink(iBuddy, iLogsize);
|
||||
iLogsize++;
|
||||
|
153
src/os_unix.c
153
src/os_unix.c
@ -149,6 +149,11 @@
|
||||
*/
|
||||
#define MAX_PATHNAME 512
|
||||
|
||||
/*
|
||||
** Maximum supported symbolic links
|
||||
*/
|
||||
#define SQLITE_MAX_SYMLINKS 100
|
||||
|
||||
/* Always cast the getpid() return type for compatibility with
|
||||
** kernel modules in VxWorks. */
|
||||
#define osGetpid(X) (pid_t)getpid()
|
||||
@ -475,6 +480,12 @@ static struct unix_syscall {
|
||||
#endif
|
||||
#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 */
|
||||
|
||||
@ -5927,6 +5938,32 @@ static int unixAccess(
|
||||
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
|
||||
@ -5943,7 +5980,17 @@ static int unixFullPathname(
|
||||
int nOut, /* Size of output buffer in bytes */
|
||||
char *zOut /* Output buffer */
|
||||
){
|
||||
#if !defined(HAVE_READLINK) || !defined(HAVE_LSTAT)
|
||||
return mkFullPathname(zPath, zOut, nOut);
|
||||
#else
|
||||
int rc = SQLITE_OK;
|
||||
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
|
||||
** using the io-error infrastructure to test that SQLite handles this
|
||||
@ -5952,60 +5999,62 @@ static int unixFullPathname(
|
||||
*/
|
||||
SimulateIOError( return SQLITE_ERROR );
|
||||
|
||||
assert( pVfs->mxPathname==MAX_PATHNAME );
|
||||
UNUSED_PARAMETER(pVfs);
|
||||
do {
|
||||
|
||||
#if defined(HAVE_READLINK)
|
||||
/* Attempt to resolve the path as if it were a symbolic link. If it is
|
||||
** a symbolic link, the resolved path is stored in buffer zOut[]. Or, if
|
||||
** the identified file is not a symbolic link or does not exist, then
|
||||
** zPath is copied directly into zOut. Either way, nByte is left set to
|
||||
** the size of the string copied into zOut[] in bytes. */
|
||||
nByte = osReadlink(zPath, zOut, nOut-1);
|
||||
if( nByte<0 ){
|
||||
if( errno!=EINVAL && errno!=ENOENT ){
|
||||
return unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zPath);
|
||||
/* Call stat() on path zIn. Set bLink to true if the path is a symbolic
|
||||
** link, or false otherwise. */
|
||||
int bLink = 0;
|
||||
struct stat buf;
|
||||
if( osLstat(zIn, &buf)!=0 ){
|
||||
if( errno!=ENOENT ){
|
||||
rc = unixLogError(SQLITE_CANTOPEN_BKPT, "lstat", zIn);
|
||||
}
|
||||
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
|
||||
** to do. If it contains a relative path, do the following:
|
||||
**
|
||||
** * move the relative path string so that it is at the end of th
|
||||
** zOut[] buffer.
|
||||
** * Call getcwd() to read the path of the current working directory
|
||||
** 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
|
||||
** follows the '/'.
|
||||
**
|
||||
** This code is written so that if the combination of the CWD and relative
|
||||
** path are larger than the allocated size of zOut[] the CWD is silently
|
||||
** truncated to make it fit. This is Ok, as SQLite refuses to open any
|
||||
** file for which this function returns a full path larger than (nOut-8)
|
||||
** bytes in size. */
|
||||
testcase( nByte==nOut-5 );
|
||||
testcase( nByte==nOut-4 );
|
||||
if( zOut[0]!='/' && nByte<nOut-4 ){
|
||||
int nCwd;
|
||||
int nRem = nOut-nByte-1;
|
||||
memmove(&zOut[nRem], zOut, nByte+1);
|
||||
zOut[nRem-1] = '\0';
|
||||
if( osGetcwd(zOut, nRem-1)==0 ){
|
||||
return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
|
||||
}
|
||||
nCwd = sqlite3Strlen30(zOut);
|
||||
assert( nCwd<=nRem-1 );
|
||||
zOut[nCwd] = '/';
|
||||
memmove(&zOut[nCwd+1], &zOut[nRem], nByte+1);
|
||||
bLink = S_ISLNK(buf.st_mode);
|
||||
}
|
||||
|
||||
return SQLITE_OK;
|
||||
if( bLink ){
|
||||
if( zDel==0 ){
|
||||
zDel = sqlite3_malloc(nOut);
|
||||
if( zDel==0 ) rc = SQLITE_NOMEM;
|
||||
}else if( ++nLink>SQLITE_MAX_SYMLINKS ){
|
||||
rc = SQLITE_CANTOPEN_BKPT;
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
nByte = osReadlink(zIn, zDel, nOut-1);
|
||||
if( nByte<0 ){
|
||||
rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zIn);
|
||||
}else{
|
||||
if( zDel[0]!='/' ){
|
||||
int n;
|
||||
for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--);
|
||||
if( nByte+n+1>nOut ){
|
||||
rc = SQLITE_CANTOPEN_BKPT;
|
||||
}else{
|
||||
memmove(&zDel[n], zDel, nByte+1);
|
||||
memcpy(zDel, zIn, n);
|
||||
nByte += n;
|
||||
}
|
||||
}
|
||||
zDel[nByte] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
zIn = zDel;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#if 0 /* Not used */
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
/*
|
||||
** Find the current time (in Universal Coordinated Time). Write the
|
||||
** 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
|
||||
#endif
|
||||
|
||||
#if 0 /* Not used */
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
/*
|
||||
** We added the xGetLastError() method with the intention of providing
|
||||
** 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
|
||||
** correctly. See ticket [bb3a86e890c8e96ab] */
|
||||
assert( ArraySize(aSyscall)==27 );
|
||||
assert( ArraySize(aSyscall)==28 );
|
||||
|
||||
/* Register all VFSes defined in the aVfs[] array */
|
||||
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
|
||||
|
||||
/*
|
||||
** 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
|
||||
** 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);
|
||||
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;
|
||||
assert( ppStmt && *ppStmt==0 );
|
||||
assert( !db->mallocFailed );
|
||||
/* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */
|
||||
assert( sqlite3_mutex_held(db->mutex) );
|
||||
|
||||
/* 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);
|
||||
sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v);
|
||||
VdbeComment((v, "OFFSET counter"));
|
||||
sqlite3VdbeAddOp3(v, OP_SetIfNotPos, iOffset, iOffset, 0);
|
||||
sqlite3VdbeAddOp3(v, OP_Add, iLimit, iOffset, iOffset+1);
|
||||
sqlite3VdbeAddOp3(v, OP_OffsetLimit, iLimit, iOffset+1, iOffset);
|
||||
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);
|
||||
VdbeComment((v, "Jump ahead if LIMIT reached"));
|
||||
if( p->iOffset ){
|
||||
sqlite3VdbeAddOp3(v, OP_SetIfNotPos, p->iOffset, p->iOffset, 0);
|
||||
sqlite3VdbeAddOp3(v, OP_Add, p->iLimit, p->iOffset, p->iOffset+1);
|
||||
sqlite3VdbeAddOp3(v, OP_SetIfNotPos, p->iLimit, p->iOffset+1, -1);
|
||||
sqlite3VdbeAddOp3(v, OP_OffsetLimit,
|
||||
p->iLimit, p->iOffset+1, p->iOffset);
|
||||
}
|
||||
}
|
||||
explainSetInteger(iSub2, pParse->iNextSelectId);
|
||||
@ -4438,8 +4435,7 @@ static int selectExpander(Walker *pWalker, Select *p){
|
||||
pExpr = pRight;
|
||||
}
|
||||
pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
|
||||
sColname.z = zColname;
|
||||
sColname.n = sqlite3Strlen30(zColname);
|
||||
sqlite3TokenInit(&sColname, zColname);
|
||||
sqlite3ExprListSetName(pParse, pNew, &sColname, 0);
|
||||
if( pNew && (p->selFlags & SF_NestedFrom)!=0 ){
|
||||
struct ExprList_item *pX = &pNew->a[pNew->nExpr-1];
|
||||
|
@ -39,9 +39,11 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
* Icon
|
||||
*/
|
||||
|
||||
#if !defined(RC_VERONLY)
|
||||
#define IDI_SQLITE 101
|
||||
|
||||
IDI_SQLITE ICON "..\\art\\sqlite370.ico"
|
||||
#endif /* !defined(RC_VERONLY) */
|
||||
|
||||
/*
|
||||
* Version
|
||||
|
@ -3325,6 +3325,7 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
|
||||
void sqlite3SetString(char **, sqlite3*, const char*);
|
||||
void sqlite3ErrorMsg(Parse*, const char*, ...);
|
||||
int sqlite3Dequote(char*);
|
||||
void sqlite3TokenInit(Token*,char*);
|
||||
int sqlite3KeywordCode(const unsigned char*, int);
|
||||
int sqlite3RunParser(Parse*, const char*, char **);
|
||||
void sqlite3FinishCoding(Parse*);
|
||||
|
@ -153,6 +153,7 @@ struct SqliteDb {
|
||||
IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */
|
||||
int nStep, nSort, nIndex; /* Statistics for most recent operation */
|
||||
int nTransaction; /* Number of nested [transaction] methods */
|
||||
int openFlags; /* Flags used to open. (SQLITE_OPEN_URI) */
|
||||
#ifdef SQLITE_TEST
|
||||
int bLegacyPrepare; /* True to use sqlite3_prepare() */
|
||||
#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");
|
||||
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 ){
|
||||
Tcl_AppendResult(interp, "cannot open target database: ",
|
||||
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");
|
||||
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 ){
|
||||
Tcl_AppendResult(interp, "cannot open source database: ",
|
||||
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;
|
||||
}
|
||||
p->maxStmt = NUM_PREPARED_STMTS;
|
||||
p->openFlags = flags & SQLITE_OPEN_URI;
|
||||
p->interp = interp;
|
||||
zArg = Tcl_GetStringFromObj(objv[1], 0);
|
||||
if( DbUseNre() ){
|
||||
|
@ -287,8 +287,7 @@ void sqlite3FinishTrigger(
|
||||
pStepList->pTrig = pTrig;
|
||||
pStepList = pStepList->pNext;
|
||||
}
|
||||
nameToken.z = pTrig->zName;
|
||||
nameToken.n = sqlite3Strlen30(nameToken.z);
|
||||
sqlite3TokenInit(&nameToken, pTrig->zName);
|
||||
sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken);
|
||||
if( sqlite3FixTriggerStep(&sFix, pTrig->step_list)
|
||||
|| sqlite3FixExpr(&sFix, pTrig->pWhen)
|
||||
|
@ -234,6 +234,14 @@ int sqlite3Dequote(char *z){
|
||||
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 */
|
||||
#define UpperToLower sqlite3UpperToLower
|
||||
|
||||
|
31
src/vdbe.c
31
src/vdbe.c
@ -5766,20 +5766,31 @@ case OP_IfPos: { /* jump, in1 */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: SetIfNotPos P1 P2 P3 * *
|
||||
** Synopsis: if r[P1]<=0 then r[P2]=P3
|
||||
/* Opcode: OffsetLimit P1 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.
|
||||
** If the value of register P1 is not positive (if it is less than 1) then
|
||||
** set the value of register P2 to be the integer P3.
|
||||
** This opcode performs a commonly used computation associated with
|
||||
** LIMIT and OFFSET process. r[P1] holds the limit counter. r[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];
|
||||
assert( pIn1->flags&MEM_Int );
|
||||
if( pIn1->u.i<=0 ){
|
||||
pIn3 = &aMem[pOp->p3];
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
pOut->u.i = pOp->p3;
|
||||
}
|
||||
assert( pIn1->flags & MEM_Int );
|
||||
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;
|
||||
}
|
||||
|
||||
|
119
src/vdbeaux.c
119
src/vdbeaux.c
@ -1721,41 +1721,43 @@ void sqlite3VdbeIOTraceSql(Vdbe *p){
|
||||
}
|
||||
#endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */
|
||||
|
||||
/*
|
||||
** Allocate space from a fixed size buffer and return a pointer to
|
||||
** that space. If insufficient space is available, return NULL.
|
||||
/* An instance of this object describes bulk memory available for use
|
||||
** by subcomponents of a prepared statement. Space is allocated out
|
||||
** 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
|
||||
** receive the new memory. pBuf is normally NULL. If pBuf is not
|
||||
** NULL, it means that memory space has already been allocated and that
|
||||
** 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.
|
||||
** If pBuf is not initially NULL, that means that the memory has already
|
||||
** been allocated by a prior call to this routine, so just return a copy
|
||||
** of pBuf and leave ReusableSpace unchanged.
|
||||
**
|
||||
** nByte is the number of bytes of space needed.
|
||||
**
|
||||
** pFrom points to *pnFrom bytes of available space. New space is allocated
|
||||
** from the end of the pFrom buffer and *pnFrom is decremented.
|
||||
**
|
||||
** *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.
|
||||
** 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
|
||||
** statement.
|
||||
*/
|
||||
static void *allocSpace(
|
||||
void *pBuf, /* Where return pointer will be stored */
|
||||
int nByte, /* Number of bytes to allocate */
|
||||
u8 *pFrom, /* Memory available for allocation */
|
||||
int *pnFrom, /* IN/OUT: Space available at pFrom */
|
||||
int *pnNeeded /* If allocation cannot be made, increment *pnByte */
|
||||
struct ReusableSpace *p, /* Bulk memory available for allocation */
|
||||
void *pBuf, /* Pointer to a prior allocation */
|
||||
int nByte /* Bytes of memory needed */
|
||||
){
|
||||
assert( EIGHT_BYTE_ALIGNMENT(pFrom) );
|
||||
assert( EIGHT_BYTE_ALIGNMENT(p->pSpace) );
|
||||
if( pBuf==0 ){
|
||||
nByte = ROUND8(nByte);
|
||||
if( nByte <= *pnFrom ){
|
||||
*pnFrom -= nByte;
|
||||
pBuf = &pFrom[*pnFrom];
|
||||
if( nByte <= p->nFree ){
|
||||
p->nFree -= nByte;
|
||||
pBuf = &p->pSpace[p->nFree];
|
||||
}else{
|
||||
*pnNeeded += nByte;
|
||||
p->nNeeded += nByte;
|
||||
}
|
||||
}
|
||||
assert( EIGHT_BYTE_ALIGNMENT(pBuf) );
|
||||
@ -1831,9 +1833,7 @@ void sqlite3VdbeMakeReady(
|
||||
int nArg; /* Number of arguments in subprograms */
|
||||
int nOnce; /* Number of OP_Once instructions */
|
||||
int n; /* Loop counter */
|
||||
int nFree; /* Available free space */
|
||||
u8 *zCsr; /* Memory available for allocation */
|
||||
int nByte; /* How much extra memory is needed */
|
||||
struct ReusableSpace x; /* Reusable bulk memory */
|
||||
|
||||
assert( p!=0 );
|
||||
assert( p->nOp>0 );
|
||||
@ -1851,7 +1851,7 @@ void sqlite3VdbeMakeReady(
|
||||
|
||||
/* For each cursor required, also allocate a memory cell. Memory
|
||||
** 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
|
||||
** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1)
|
||||
** stores the blob of memory associated with cursor 1, etc.
|
||||
@ -1860,20 +1860,18 @@ void sqlite3VdbeMakeReady(
|
||||
*/
|
||||
nMem += nCursor;
|
||||
|
||||
/* zCsr will initially point to nFree bytes of unused space at the
|
||||
** end of the opcode array, p->aOp. The computation of nFree is
|
||||
** conservative - it might be smaller than the true number of free
|
||||
** bytes, but never larger. nFree must be a multiple of 8 - it is
|
||||
** rounded down if is not.
|
||||
/* Figure out how much reusable memory is available at the end of the
|
||||
** opcode array. This extra memory will be reallocated for other elements
|
||||
** of the prepared statement.
|
||||
*/
|
||||
n = ROUND8(sizeof(Op)*p->nOp); /* Bytes of opcode space used */
|
||||
zCsr = &((u8*)p->aOp)[n]; /* Unused opcode space */
|
||||
assert( EIGHT_BYTE_ALIGNMENT(zCsr) );
|
||||
nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused space */
|
||||
assert( nFree>=0 );
|
||||
if( nFree>0 ){
|
||||
memset(zCsr, 0, nFree);
|
||||
assert( EIGHT_BYTE_ALIGNMENT(&zCsr[nFree]) );
|
||||
n = ROUND8(sizeof(Op)*p->nOp); /* Bytes of opcode memory used */
|
||||
x.pSpace = &((u8*)p->aOp)[n]; /* Unused opcode memory */
|
||||
assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) );
|
||||
x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused memory */
|
||||
assert( x.nFree>=0 );
|
||||
if( x.nFree>0 ){
|
||||
memset(x.pSpace, 0, x.nFree);
|
||||
assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) );
|
||||
}
|
||||
|
||||
resolveP2Values(p, &nArg);
|
||||
@ -1883,33 +1881,30 @@ void sqlite3VdbeMakeReady(
|
||||
}
|
||||
p->expired = 0;
|
||||
|
||||
/* Memory for registers, parameters, cursor, etc, is allocated in two
|
||||
** passes. On the first pass, we try to reuse unused space at the
|
||||
/* Memory for registers, parameters, cursor, etc, is allocated in one or two
|
||||
** 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
|
||||
** 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
|
||||
** 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.
|
||||
*/
|
||||
do {
|
||||
nByte = 0;
|
||||
p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), zCsr, &nFree, &nByte);
|
||||
p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), zCsr, &nFree, &nByte);
|
||||
p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), zCsr, &nFree, &nByte);
|
||||
p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*),
|
||||
zCsr, &nFree, &nByte);
|
||||
p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, zCsr, &nFree, &nByte);
|
||||
x.nNeeded = 0;
|
||||
p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem));
|
||||
p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem));
|
||||
p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*));
|
||||
p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
|
||||
p->aOnceFlag = allocSpace(&x, p->aOnceFlag, nOnce);
|
||||
#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
|
||||
if( nByte ){
|
||||
p->pFree = sqlite3DbMallocZero(db, nByte);
|
||||
}
|
||||
zCsr = p->pFree;
|
||||
nFree = nByte;
|
||||
}while( nByte && !db->mallocFailed );
|
||||
if( x.nNeeded==0 ) break;
|
||||
x.pSpace = p->pFree = sqlite3DbMallocZero(db, x.nNeeded);
|
||||
x.nFree = x.nNeeded;
|
||||
}while( !db->mallocFailed );
|
||||
|
||||
p->nCursor = nCursor;
|
||||
p->nOnceFlag = nOnce;
|
||||
|
@ -1837,7 +1837,9 @@ int sqlite3VdbeSorterWrite(
|
||||
|
||||
pNew = (SorterRecord*)&pSorter->list.aMemory[pSorter->iMemory];
|
||||
pSorter->iMemory += ROUND8(nReq);
|
||||
if( pSorter->list.pList ){
|
||||
pNew->u.iNext = (int)((u8*)(pSorter->list.pList) - pSorter->list.aMemory);
|
||||
}
|
||||
}else{
|
||||
pNew = (SorterRecord *)sqlite3Malloc(nReq);
|
||||
if( pNew==0 ){
|
||||
|
@ -28,4 +28,5 @@
|
||||
#define OS_VXWORKS 0
|
||||
#define HAVE_FCHOWN 1
|
||||
#define HAVE_READLINK 1
|
||||
#define HAVE_LSTAT 1
|
||||
#endif /* defined(_WRS_KERNEL) */
|
||||
|
@ -95,7 +95,7 @@ do_test 1.4.1 {
|
||||
|
||||
do_re_test 1.4.2 {
|
||||
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.
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix stat
|
||||
|
||||
ifcapable !vtab||!compound {
|
||||
finish_test
|
||||
@ -184,4 +185,69 @@ do_catchsql_test stat-6.1 {
|
||||
CREATE VIRTUAL TABLE temp.s2 USING dbstat(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
|
||||
|
@ -83,25 +83,30 @@ do_test 1.5 {
|
||||
do_test 2.0 {
|
||||
catch { db close }
|
||||
catch { db2 close }
|
||||
forcedelete test.db test.db2
|
||||
forcedelete test.db test.db2 test.db3
|
||||
sqlite3 db test.db
|
||||
execsql { CREATE TABLE t1(x) }
|
||||
file link test.db2 test.db
|
||||
sqlite3 db2 test.db2
|
||||
file link test.db3 test.db2
|
||||
set {} {}
|
||||
} {}
|
||||
|
||||
foreach {tn f} {1 test.db2 2 test.db3} {
|
||||
do_test 2.$tn.1 {
|
||||
sqlite3 db2 $f
|
||||
file exists test.db-journal
|
||||
} 0
|
||||
|
||||
do_test 2.1 {
|
||||
do_test 2.$tn.2 {
|
||||
execsql {
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES(1);
|
||||
} db2
|
||||
file exists test.db-journal
|
||||
} 1
|
||||
do_test 2.2 {
|
||||
file exists test.db2-journal
|
||||
} 0
|
||||
do_test 2.3 {
|
||||
do_test 2.$tn.3 {
|
||||
list [file exists test2.db-journal] [file exists test3.db-journal]
|
||||
} {0 0}
|
||||
do_test 2.$tn.4 {
|
||||
execsql {
|
||||
COMMIT;
|
||||
PRAGMA journal_mode = wal;
|
||||
@ -109,12 +114,18 @@ do_test 2.3 {
|
||||
} db2
|
||||
file exists test.db-wal
|
||||
} 1
|
||||
do_test 2.4 {
|
||||
file exists test.db2-wal
|
||||
} 0
|
||||
do_execsql_test 2.5 {
|
||||
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
|
||||
# Kostya Serebryany using libFuzzer on 2015-11-30.
|
||||
@ -125,5 +136,56 @@ do_test 3.1 {
|
||||
set res
|
||||
} {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
|
||||
|
@ -61,7 +61,7 @@ foreach s {
|
||||
fcntl read pread write pwrite fchmod fallocate
|
||||
pread64 pwrite64 unlink openDirectory mkdir rmdir
|
||||
statvfs fchown geteuid umask mmap munmap mremap
|
||||
getpagesize readlink
|
||||
getpagesize readlink lstat
|
||||
} {
|
||||
if {[test_syscall exists $s]} {lappend syscall_list $s}
|
||||
}
|
||||
|
@ -35,13 +35,13 @@ ARTIFACT=`printf "3%.2d%.2d%.2d" $xx $yy $zz`
|
||||
|
||||
rm -rf $TMPSPACE
|
||||
cp -R $TOP/autoconf $TMPSPACE
|
||||
|
||||
cp sqlite3.c $TMPSPACE
|
||||
cp sqlite3.h $TMPSPACE
|
||||
cp sqlite3ext.h $TMPSPACE
|
||||
cp $TOP/sqlite3.1 $TMPSPACE
|
||||
cp $TOP/sqlite3.pc.in $TMPSPACE
|
||||
cp $TOP/src/shell.c $TMPSPACE
|
||||
cp $TOP/src/sqlite3.rc $TMPSPACE
|
||||
|
||||
cat $TMPSPACE/configure.ac |
|
||||
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