Compare commits
131 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 63225522f9 | |||
| 8dd1c25388 | |||
| 9584f58cc2 | |||
| 71258abf0d | |||
| 85979cd818 | |||
| 25b0c4094f | |||
| e3b63599a3 | |||
| 7f8a93d72c | |||
| 4380ff8887 | |||
| b3ebc805ed | |||
| 7d3bfa2713 | |||
| 98fea32c83 | |||
| da9da5624a | |||
| 3e6d22ad4d | |||
| 59189433ba | |||
| d08a63ab62 | |||
| e9e1505b3c | |||
| 9525a86ba1 | |||
| a7f6597400 | |||
| f0db464b93 | |||
| 153110a7da | |||
| 245fdc60d6 | |||
| 6a75c8ad94 | |||
| b457764d01 | |||
| 3bfab7c6d6 | |||
| 5596eb3020 | |||
| e44b835e63 | |||
| e8e6657fa7 | |||
| 9fb13abc6e | |||
| 4a6beac28b | |||
| dbf6773e88 | |||
| c56fac7483 | |||
| de4148e304 | |||
| 1167d32716 | |||
| 6fa255fd5c | |||
| 9109b7f8e1 | |||
| 36c33aa633 | |||
| 24b8457911 | |||
| 1bbbd85bd2 | |||
| f7854c7329 | |||
| 2853c688ad | |||
| c5dc3dcd6e | |||
| 0691191d26 | |||
| ad61c46409 | |||
| 3d541a5b8c | |||
| 433d5aaed1 | |||
| 6b513640c0 | |||
| 4dd83a22f2 | |||
| 46e6ea0282 | |||
| 56d90be183 | |||
| fb785b2c2b | |||
| 2b4e95226c | |||
| fd261ec67e | |||
| 7ef855f156 | |||
| 16158eeb49 | |||
| 1dfaa5c4b2 | |||
| 99b25309d0 | |||
| f2c9995dbe | |||
| 5c22e82a17 | |||
| 6d7734c27d | |||
| 219f4d48a2 | |||
| 9cc4ae6f2a | |||
| 3f9bfa740f | |||
| 8789fbb2bd | |||
| 5e5b454cd8 | |||
| 3c060c2aef | |||
| 0206920e27 | |||
| 05903e6a87 | |||
| b0df963465 | |||
| 0030aaad67 | |||
| f170ea44d4 | |||
| 04ce31fafe | |||
| 1cfc44392c | |||
| 49472655d4 | |||
| b9e8f59b63 | |||
| be37c12423 | |||
| faf3727904 | |||
| 95fa606616 | |||
| 848a3326f7 | |||
| c24658b5d7 | |||
| c6ce388301 | |||
| ce78bc6e7e | |||
| fed7ac6f04 | |||
| 9eef8c6934 | |||
| 59a052359d | |||
| 039ca6ab59 | |||
| b02392e6f0 | |||
| 9676c48199 | |||
| 8873996b7b | |||
| 460cd9ccfd | |||
| 5f93ccd7fc | |||
| cdabd7bd50 | |||
| 99f4647ef5 | |||
| fdefc36792 | |||
| 78e3f61f22 | |||
| 501b402c65 | |||
| 021643560b | |||
| 8d32e8042c | |||
| fcbe99ae38 | |||
| cf9fb7eb1c | |||
| 5b66350ac7 | |||
| ba461cac7b | |||
| 946ef60ad0 | |||
| cc7304888f | |||
| dfff1ffec6 | |||
| 80372ae248 | |||
| 48cc9a31e1 | |||
| 60a15a48c5 | |||
| 7651e0a439 | |||
| b15393b8d5 | |||
| ae1a015c87 | |||
| 81966bea22 | |||
| 163c29c5f3 | |||
| 4970d4032e | |||
| c1bd84124b | |||
| bcf40a7f12 | |||
| b413a5467a | |||
| a67a31624d | |||
| 0403cb3012 | |||
| 1eb6eeb829 | |||
| 2f2b02785a | |||
| 0df57012da | |||
| fe66352d17 | |||
| ffc648cfa9 | |||
| f7e369070e | |||
| 07194bff0e | |||
| bec2476afc | |||
| 91d3a61f8a | |||
| 159c1a18db | |||
| 5b88bc4bec | |||
| 28935364ef |
@@ -1,138 +0,0 @@
|
||||
#!/usr/make
|
||||
#
|
||||
# Makefile for SQLITE
|
||||
#
|
||||
# This is a template makefile for SQLite. Most people prefer to
|
||||
# use the autoconf generated "configure" script to generate the
|
||||
# makefile automatically. But that does not work for everybody
|
||||
# and in every situation. If you are having problems with the
|
||||
# "configure" script, you might want to try this makefile as an
|
||||
# alternative. Create a copy of this file, edit the parameters
|
||||
# below and type "make".
|
||||
#
|
||||
|
||||
#### The directory where to find the mingw32ce tools
|
||||
MINGW32CE = /opt/mingw32ce/bin
|
||||
|
||||
#### The target prefix of the mingw32ce tools
|
||||
TARGET = arm-wince-mingw32ce
|
||||
|
||||
#### The toplevel directory of the source tree. This is the directory
|
||||
# that contains this "Makefile.in" and the "configure.in" script.
|
||||
#
|
||||
TOP = ../sqlite
|
||||
|
||||
#### C Compiler and options for use in building executables that
|
||||
# will run on the platform that is doing the build.
|
||||
#
|
||||
BCC = gcc -g -O2
|
||||
#BCC = /opt/ancic/bin/c89 -0
|
||||
|
||||
#### If the target operating system supports the "usleep()" system
|
||||
# call, then define the HAVE_USLEEP macro for all C modules.
|
||||
#
|
||||
USLEEP =
|
||||
#USLEEP = -DHAVE_USLEEP=1
|
||||
|
||||
#### If you want the SQLite library to be safe for use within a
|
||||
# multi-threaded program, then define the following macro
|
||||
# appropriately:
|
||||
#
|
||||
THREADSAFE = -DTHREADSAFE=1
|
||||
#THREADSAFE = -DTHREADSAFE=0
|
||||
|
||||
#### Specify any extra linker options needed to make the library
|
||||
# thread safe
|
||||
#
|
||||
#THREADLIB = -lpthread
|
||||
THREADLIB =
|
||||
|
||||
#### Specify any extra libraries needed to access required functions.
|
||||
#
|
||||
#TLIBS = -lrt # fdatasync on Solaris 8
|
||||
TLIBS =
|
||||
|
||||
#### Leave SQLITE_DEBUG undefined for maximum speed. Use SQLITE_DEBUG=1
|
||||
# to check for memory leaks. Use SQLITE_DEBUG=2 to print a log of all
|
||||
# malloc()s and free()s in order to track down memory leaks.
|
||||
#
|
||||
# SQLite uses some expensive assert() statements in the inner loop.
|
||||
# You can make the library go almost twice as fast if you compile
|
||||
# with -DNDEBUG=1
|
||||
#
|
||||
#OPTS = -DSQLITE_DEBUG=2
|
||||
#OPTS = -DSQLITE_DEBUG=1
|
||||
#OPTS =
|
||||
OPTS = -DNDEBUG=1 -DSQLITE_OS_WIN=1 -D_WIN32_WCE=1
|
||||
#OPTS += -DHAVE_FDATASYNC=1
|
||||
|
||||
#### The suffix to add to executable files. ".exe" for windows.
|
||||
# Nothing for unix.
|
||||
#
|
||||
EXE = .exe
|
||||
#EXE =
|
||||
|
||||
#### C Compile and options for use in building executables that
|
||||
# will run on the target platform. This is usually the same
|
||||
# as BCC, unless you are cross-compiling.
|
||||
#
|
||||
#TCC = gcc -O6
|
||||
#TCC = gcc -g -O0 -Wall
|
||||
#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage
|
||||
#TCC = /opt/mingw/bin/i386-mingw32-gcc -O6
|
||||
TCC = $(MINGW32CE)/$(TARGET)-gcc -O2
|
||||
#TCC = /opt/ansic/bin/c89 -O +z -Wl,-a,archive
|
||||
|
||||
#### Tools used to build a static library.
|
||||
#
|
||||
#AR = ar cr
|
||||
#AR = /opt/mingw/bin/i386-mingw32-ar cr
|
||||
AR = $(MINGW32CE)/$(TARGET)-ar cr
|
||||
#RANLIB = ranlib
|
||||
#RANLIB = /opt/mingw/bin/i386-mingw32-ranlib
|
||||
RANLIB = $(MINGW32CE)/$(TARGET)-ranlib
|
||||
|
||||
#MKSHLIB = gcc -shared
|
||||
#SO = so
|
||||
#SHPREFIX = lib
|
||||
MKSHLIB = $(MINGW32CE)/$(TARGET)-gcc -shared
|
||||
SO = dll
|
||||
SHPREFIX =
|
||||
|
||||
#### Extra compiler options needed for programs that use the TCL library.
|
||||
#
|
||||
#TCL_FLAGS =
|
||||
#TCL_FLAGS = -DSTATIC_BUILD=1
|
||||
TCL_FLAGS = -I/home/drh/tcltk/8.5linux
|
||||
#TCL_FLAGS = -I/home/drh/tcltk/8.5win -DSTATIC_BUILD=1
|
||||
#TCL_FLAGS = -I/home/drh/tcltk/8.3hpux
|
||||
|
||||
#### Linker options needed to link against the TCL library.
|
||||
#
|
||||
#LIBTCL = -ltcl -lm -ldl
|
||||
LIBTCL = /home/drh/tcltk/8.5linux/libtcl8.5g.a -lm -ldl
|
||||
#LIBTCL = /home/drh/tcltk/8.5win/libtcl85s.a -lmsvcrt
|
||||
#LIBTCL = /home/drh/tcltk/8.3hpux/libtcl8.3.a -ldld -lm -lc
|
||||
|
||||
#### Additional objects for SQLite library when TCL support is enabled.
|
||||
TCLOBJ =
|
||||
#TCLOBJ = tclsqlite.o
|
||||
|
||||
#### Compiler options needed for programs that use the readline() library.
|
||||
#
|
||||
READLINE_FLAGS =
|
||||
#READLINE_FLAGS = -DHAVE_READLINE=1 -I/usr/include/readline
|
||||
|
||||
#### Linker options needed by programs using readline() must link against.
|
||||
#
|
||||
LIBREADLINE =
|
||||
#LIBREADLINE = -static -lreadline -ltermcap
|
||||
|
||||
#### Which "awk" program provides nawk compatibilty
|
||||
#
|
||||
# NAWK = nawk
|
||||
NAWK = awk
|
||||
|
||||
# You should not have to change anything below this line
|
||||
###############################################################################
|
||||
include $(TOP)/main.mk
|
||||
+9
-11
@@ -54,6 +54,7 @@ LIBTCL = @TCL_LIB_SPEC@
|
||||
# Compiler options needed for programs that use the readline() library.
|
||||
#
|
||||
READLINE_FLAGS = -DHAVE_READLINE=@TARGET_HAVE_READLINE@ @TARGET_READLINE_INC@
|
||||
READLINE_FLAGS += -DHAVE_EDITLINE=@TARGET_HAVE_EDITLINE@
|
||||
|
||||
# The library that programs using readline() must link against.
|
||||
#
|
||||
@@ -155,9 +156,6 @@ LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(TCC) $(LTCOMPILE_EXTRAS)
|
||||
LTLINK = $(LIBTOOL) --mode=link $(TCC) $(LTCOMPILE_EXTRAS) @LDFLAGS@ $(LTLINK_EXTRAS)
|
||||
LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL)
|
||||
|
||||
# nawk compatible awk.
|
||||
NAWK = @AWK@
|
||||
|
||||
# You should not have to change anything below this line
|
||||
###############################################################################
|
||||
|
||||
@@ -902,22 +900,22 @@ tclsqlite3$(TEXE): tclsqlite-shell.lo libsqlite3.la
|
||||
|
||||
# Rules to build opcodes.c and opcodes.h
|
||||
#
|
||||
opcodes.c: opcodes.h $(TOP)/mkopcodec.awk
|
||||
$(NAWK) -f $(TOP)/mkopcodec.awk opcodes.h >opcodes.c
|
||||
opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl
|
||||
$(TCLSH_CMD) $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c
|
||||
|
||||
opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk
|
||||
cat parse.h $(TOP)/src/vdbe.c | $(NAWK) -f $(TOP)/mkopcodeh.awk >opcodes.h
|
||||
opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/tool/mkopcodeh.tcl
|
||||
cat parse.h $(TOP)/src/vdbe.c | $(TCLSH_CMD) $(TOP)/tool/mkopcodeh.tcl >opcodes.h
|
||||
|
||||
# Rules to build parse.c and parse.h - the outputs of lemon.
|
||||
#
|
||||
parse.h: parse.c
|
||||
|
||||
parse.c: $(TOP)/src/parse.y lemon$(BEXE) $(TOP)/addopcodes.awk
|
||||
parse.c: $(TOP)/src/parse.y lemon$(BEXE) $(TOP)/tool/addopcodes.tcl
|
||||
cp $(TOP)/src/parse.y .
|
||||
rm -f parse.h
|
||||
./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) parse.y
|
||||
mv parse.h parse.h.temp
|
||||
$(NAWK) -f $(TOP)/addopcodes.awk parse.h.temp >parse.h
|
||||
$(TCLSH_CMD) $(TOP)/tool/addopcodes.tcl parse.h.temp >parse.h
|
||||
|
||||
sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest.uuid $(TOP)/VERSION
|
||||
$(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h
|
||||
@@ -1070,7 +1068,7 @@ fastfuzztest: fuzzcheck$(TEXE) $(FUZZDATA)
|
||||
./fuzzcheck$(TEXE) --limit-mem 100M $(FUZZDATA)
|
||||
|
||||
valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA)
|
||||
valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M $(FUZZDATA)
|
||||
valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA)
|
||||
|
||||
# Minimal testing that runs in less than 3 minutes
|
||||
#
|
||||
@@ -1102,7 +1100,7 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
|
||||
cat sqlite3.c $(TOP)/src/tclsqlite.c >> $@
|
||||
echo "static const char *tclsh_main_loop(void){" >> $@
|
||||
echo "static const char *zMainloop = " >> $@
|
||||
$(NAWK) -f $(TOP)/tool/tostr.awk $(TOP)/tool/spaceanal.tcl >> $@
|
||||
$(TCLSH_CMD) $(TOP)/tool/tostr.tcl $(TOP)/tool/spaceanal.tcl >> $@
|
||||
echo "; return zMainloop; }" >> $@
|
||||
|
||||
sqlite3_analyzer$(TEXE): sqlite3_analyzer.c
|
||||
|
||||
@@ -118,11 +118,6 @@ READLINE_FLAGS =
|
||||
LIBREADLINE =
|
||||
#LIBREADLINE = -static -lreadline -ltermcap
|
||||
|
||||
#### Which "awk" program provides nawk compatibilty
|
||||
#
|
||||
# NAWK = nawk
|
||||
NAWK = awk
|
||||
|
||||
# You should not have to change anything below this line
|
||||
###############################################################################
|
||||
include $(TOP)/main.mk
|
||||
|
||||
+53
-43
@@ -292,9 +292,9 @@ NSDKLIBPATH = $(NSDKLIBPATH:\\=\)
|
||||
# will run on the platform that is doing the build.
|
||||
#
|
||||
!IF $(USE_FULLWARN)!=0
|
||||
BCC = $(NCC) -nologo -W4
|
||||
BCC = $(NCC) -nologo -W4 $(CCOPTS) $(BCCOPTS)
|
||||
!ELSE
|
||||
BCC = $(NCC) -nologo -W3
|
||||
BCC = $(NCC) -nologo -W3 $(CCOPTS) $(BCCOPTS)
|
||||
!ENDIF
|
||||
|
||||
# Check if assembly code listings should be generated for the source
|
||||
@@ -322,13 +322,13 @@ NLTLIBPATHS = $(NLTLIBPATHS) "/LIBPATH:$(NUCRTLIBPATH)"
|
||||
# same unless your are cross-compiling.)
|
||||
#
|
||||
!IF $(USE_FULLWARN)!=0
|
||||
TCC = $(CC) -nologo -W4 -DINCLUDE_MSVC_H=1
|
||||
TCC = $(CC) -nologo -W4 -DINCLUDE_MSVC_H=1 $(CCOPTS) $(TCCOPTS)
|
||||
!ELSE
|
||||
TCC = $(CC) -nologo -W3
|
||||
TCC = $(CC) -nologo -W3 $(CCOPTS) $(TCCOPTS)
|
||||
!ENDIF
|
||||
|
||||
TCC = $(TCC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -I$(TOP)\src -fp:precise
|
||||
RCC = $(RC) -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src
|
||||
RCC = $(RC) -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src $(RCOPTS) $(RCCOPTS)
|
||||
|
||||
# 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
|
||||
@@ -569,6 +569,14 @@ TCLLIBDIR = c:\tcl\lib
|
||||
LIBTCL = tcl85.lib
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF LIBTCLSTUB
|
||||
LIBTCLSTUB = tclstub85.lib
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF LIBTCLPATH
|
||||
LIBTCLPATH = c:\tcl\bin
|
||||
!ENDIF
|
||||
|
||||
# The locations of the ICU header and library files. These variables
|
||||
# (ICUINCDIR, ICULIBDIR, and LIBICU) may be overridden via the environment
|
||||
# prior to running nmake in order to match the actual installed location on
|
||||
@@ -792,7 +800,9 @@ LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(PSDKLIBPATH)"
|
||||
# If either debugging or symbols are enabled, enable PDBs.
|
||||
#
|
||||
!IF $(DEBUG)>1 || $(SYMBOLS)!=0
|
||||
LDFLAGS = /DEBUG
|
||||
LDFLAGS = /DEBUG $(LDOPTS)
|
||||
!ELSE
|
||||
LDFLAGS = $(LDOPTS)
|
||||
!ENDIF
|
||||
|
||||
# Start with the Tcl related linker options.
|
||||
@@ -809,12 +819,6 @@ LTLIBPATHS = $(LTLIBPATHS) /LIBPATH:$(ICULIBDIR)
|
||||
LTLIBS = $(LTLIBS) $(LIBICU)
|
||||
!ENDIF
|
||||
|
||||
# nawk compatible awk.
|
||||
#
|
||||
!IFNDEF NAWK
|
||||
NAWK = gawk.exe
|
||||
!ENDIF
|
||||
|
||||
# You should not have to change anything below this line
|
||||
###############################################################################
|
||||
|
||||
@@ -1080,11 +1084,9 @@ TESTEXT = \
|
||||
$(TOP)\ext\misc\eval.c \
|
||||
$(TOP)\ext\misc\fileio.c \
|
||||
$(TOP)\ext\misc\fuzzer.c \
|
||||
fts5.c \
|
||||
$(TOP)\ext\fts5\fts5_tcl.c \
|
||||
$(TOP)\ext\fts5\fts5_test_mi.c \
|
||||
$(TOP)\ext\misc\ieee754.c \
|
||||
$(TOP)\ext\misc\json1.c \
|
||||
$(TOP)\ext\misc\nextchar.c \
|
||||
$(TOP)\ext\misc\percentile.c \
|
||||
$(TOP)\ext\misc\regexp.c \
|
||||
@@ -1230,25 +1232,25 @@ libsqlite3.lib: $(LIBOBJ)
|
||||
$(LTLIB) $(LTLIBOPTS) /OUT:$@ $(LIBOBJ) $(TLIBS)
|
||||
|
||||
libtclsqlite3.lib: tclsqlite.lo libsqlite3.lib
|
||||
$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCL:tcl=tclstub) $(TLIBS)
|
||||
$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCLSTUB) $(TLIBS)
|
||||
|
||||
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 $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
|
||||
/link /pdb:sqlite3sh.pdb $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
|
||||
|
||||
sqldiff.exe: $(TOP)\tool\sqldiff.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) $(NO_WARN) $(TOP)\tool\sqldiff.c sqlite3.c
|
||||
$(LTLINK) $(NO_WARN) $(TOP)\tool\sqldiff.c sqlite3.c /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
fuzzershell.exe: $(TOP)\tool\fuzzershell.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) $(NO_WARN) $(FUZZERSHELL_COMPILE_OPTS) \
|
||||
$(TOP)\tool\fuzzershell.c sqlite3.c
|
||||
$(TOP)\tool\fuzzershell.c sqlite3.c /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
fuzzcheck.exe: $(TOP)\test\fuzzcheck.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(TOP)\test\fuzzcheck.c sqlite3.c
|
||||
$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(TOP)\test\fuzzcheck.c sqlite3.c /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 $(LTLINKOPTS) $(LTLIBPATHS) $(SHELL_LINK_OPTS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
|
||||
/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(SHELL_LINK_OPTS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
|
||||
|
||||
MPTEST1 = mptester mptest.db $(TOP)\mptest\crash01.test --repeat 20
|
||||
MPTEST2 = mptester mptest.db $(TOP)\mptest\multiwrite01.test --repeat 20
|
||||
@@ -1313,7 +1315,7 @@ lempar.c: $(TOP)\src\lempar.c
|
||||
|
||||
lemon.exe: $(TOP)\tool\lemon.c lempar.c
|
||||
$(BCC) $(NO_WARN) -Daccess=_access \
|
||||
-Fe$@ $(TOP)\tool\lemon.c /link $(NLTLINKOPTS) $(NLTLIBPATHS)
|
||||
-Fe$@ $(TOP)\tool\lemon.c /link $(LDFLAGS) $(NLTLINKOPTS) $(NLTLIBPATHS)
|
||||
|
||||
# Rules to build individual *.lo files from generated *.c files. This
|
||||
# applies to:
|
||||
@@ -1334,7 +1336,7 @@ $(LIBRESOBJS): $(TOP)\src\sqlite3.rc $(HDR)
|
||||
echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h
|
||||
for /F %%V in ('type "$(TOP)\VERSION"') do ( \
|
||||
echo #define SQLITE_RESOURCE_VERSION %%V \
|
||||
| $(NAWK) "/.*/ { gsub(/[.]/,\",\");print }" >> sqlite3rc.h \
|
||||
| $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact . ^, >> sqlite3rc.h \
|
||||
)
|
||||
echo #endif >> sqlite3rc.h
|
||||
$(LTRCOMPILE) -fo $(LIBRESOBJS) $(TOP)\src\sqlite3.rc
|
||||
@@ -1571,26 +1573,26 @@ 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)
|
||||
$(LTLINK) $(SQLITE3C) /link $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite-shell.lo $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
||||
$(LTLINK) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite-shell.lo $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
||||
|
||||
# Rules to build opcodes.c and opcodes.h
|
||||
#
|
||||
opcodes.c: opcodes.h $(TOP)\mkopcodec.awk
|
||||
$(NAWK) -f $(TOP)\mkopcodec.awk opcodes.h > opcodes.c
|
||||
opcodes.c: opcodes.h $(TOP)\tool\mkopcodec.tcl
|
||||
$(TCLSH_CMD) $(TOP)\tool\mkopcodec.tcl opcodes.h > opcodes.c
|
||||
|
||||
opcodes.h: parse.h $(TOP)\src\vdbe.c $(TOP)\mkopcodeh.awk
|
||||
type parse.h $(TOP)\src\vdbe.c | $(NAWK) -f $(TOP)\mkopcodeh.awk > opcodes.h
|
||||
opcodes.h: parse.h $(TOP)\src\vdbe.c $(TOP)\tool\mkopcodeh.tcl
|
||||
type parse.h $(TOP)\src\vdbe.c | $(TCLSH_CMD) $(TOP)\tool\mkopcodeh.tcl > opcodes.h
|
||||
|
||||
# Rules to build parse.c and parse.h - the outputs of lemon.
|
||||
#
|
||||
parse.h: parse.c
|
||||
|
||||
parse.c: $(TOP)\src\parse.y lemon.exe $(TOP)\addopcodes.awk
|
||||
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
|
||||
move parse.h parse.h.temp
|
||||
$(NAWK) -f $(TOP)\addopcodes.awk parse.h.temp > parse.h
|
||||
$(TCLSH_CMD) $(TOP)\tool\addopcodes.tcl parse.h.temp > parse.h
|
||||
|
||||
sqlite3.h: $(TOP)\src\sqlite.h.in $(TOP)\manifest.uuid $(TOP)\VERSION
|
||||
$(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > sqlite3.h
|
||||
@@ -1600,7 +1602,7 @@ sqlite3ext.h: .target_source
|
||||
|
||||
mkkeywordhash.exe: $(TOP)\tool\mkkeywordhash.c
|
||||
$(BCC) $(NO_WARN) -Fe$@ $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) \
|
||||
$(TOP)\tool\mkkeywordhash.c /link $(NLTLINKOPTS) $(NLTLIBPATHS)
|
||||
$(TOP)\tool\mkkeywordhash.c /link $(LDFLAGS) $(NLTLINKOPTS) $(NLTLIBPATHS)
|
||||
|
||||
keywordhash.h: $(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe
|
||||
.\mkkeywordhash.exe > keywordhash.h
|
||||
@@ -1734,21 +1736,26 @@ testfixture.exe: $(TESTFIXTURE_SRC) $(LIBRESOBJS) $(HDR)
|
||||
$(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \
|
||||
-DBUILD_sqlite -I$(TCLINCDIR) \
|
||||
$(TESTFIXTURE_SRC) \
|
||||
/link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
||||
/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
||||
|
||||
extensiontest: testfixture.exe testloadext.dll
|
||||
@set PATH=$(LIBTCLPATH);$(PATH)
|
||||
.\testfixture.exe $(TOP)\test\loadext.test $(TESTOPTS)
|
||||
|
||||
fulltest: $(TESTPROGS) fuzztest
|
||||
@set PATH=$(LIBTCLPATH);$(PATH)
|
||||
.\testfixture.exe $(TOP)\test\all.test $(TESTOPTS)
|
||||
|
||||
soaktest: $(TESTPROGS)
|
||||
@set PATH=$(LIBTCLPATH);$(PATH)
|
||||
.\testfixture.exe $(TOP)\test\all.test -soak=1 $(TESTOPTS)
|
||||
|
||||
fulltestonly: $(TESTPROGS) fuzztest
|
||||
@set PATH=$(LIBTCLPATH);$(PATH)
|
||||
.\testfixture.exe $(TOP)\test\full.test
|
||||
|
||||
queryplantest: testfixture.exe sqlite3.exe
|
||||
@set PATH=$(LIBTCLPATH);$(PATH)
|
||||
.\testfixture.exe $(TOP)\test\permutations.test queryplanner $(TESTOPTS)
|
||||
|
||||
fuzztest: fuzzcheck.exe
|
||||
@@ -1760,15 +1767,18 @@ fastfuzztest: fuzzcheck.exe
|
||||
# Minimal testing that runs in less than 3 minutes (on a fast machine)
|
||||
#
|
||||
quicktest: testfixture.exe
|
||||
@set PATH=$(LIBTCLPATH);$(PATH)
|
||||
.\testfixture.exe $(TOP)\test\extraquick.test $(TESTOPTS)
|
||||
|
||||
# This is the common case. Run many tests that do not take too long,
|
||||
# including fuzzcheck, sqlite3_analyzer, and sqldiff tests.
|
||||
#
|
||||
test: $(TESTPROGS) fastfuzztest
|
||||
@set PATH=$(LIBTCLPATH);$(PATH)
|
||||
.\testfixture.exe $(TOP)\test\veryquick.test $(TESTOPTS)
|
||||
|
||||
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
|
||||
@@ -1777,12 +1787,12 @@ sqlite3_analyzer.c: $(SQLITE3C) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl
|
||||
copy $@ + $(SQLITE3C) + $(TOP)\src\tclsqlite.c $@
|
||||
echo static const char *tclsh_main_loop(void){ >> $@
|
||||
echo static const char *zMainloop = >> $@
|
||||
$(NAWK) -f $(TOP)\tool\tostr.awk $(TOP)\tool\spaceanal.tcl >> $@
|
||||
$(TCLSH_CMD) $(TOP)\tool\tostr.tcl $(TOP)\tool\spaceanal.tcl >> $@
|
||||
echo ; return zMainloop; } >> $@
|
||||
|
||||
sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS)
|
||||
$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_analyzer.c \
|
||||
/link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
||||
/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
||||
|
||||
testloadext.lo: $(TOP)\src\test_loadext.c
|
||||
$(LTCOMPILE) $(NO_WARN) -c $(TOP)\src\test_loadext.c
|
||||
@@ -1792,38 +1802,38 @@ testloadext.dll: testloadext.lo
|
||||
|
||||
showdb.exe: $(TOP)\tool\showdb.c $(SQLITE3C)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(TOP)\tool\showdb.c $(SQLITE3C)
|
||||
$(TOP)\tool\showdb.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
showstat4.exe: $(TOP)\tool\showstat4.c $(SQLITE3C)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(TOP)\tool\showstat4.c $(SQLITE3C)
|
||||
$(TOP)\tool\showstat4.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
showjournal.exe: $(TOP)\tool\showjournal.c $(SQLITE3C)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(TOP)\tool\showjournal.c $(SQLITE3C)
|
||||
$(TOP)\tool\showjournal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
showwal.exe: $(TOP)\tool\showwal.c $(SQLITE3C)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(TOP)\tool\showwal.c $(SQLITE3C)
|
||||
$(TOP)\tool\showwal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
fts3view.exe: $(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C)
|
||||
$(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
rollback-test.exe: $(TOP)\tool\rollback-test.c $(SQLITE3C)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(TOP)\tool\rollback-test.c $(SQLITE3C)
|
||||
$(TOP)\tool\rollback-test.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
LogEst.exe: $(TOP)\tool\logest.c sqlite3.h
|
||||
$(LTLINK) $(NO_WARN) -Fe$@ $(TOP)\tool\LogEst.c
|
||||
$(LTLINK) $(NO_WARN) -Fe$@ $(TOP)\tool\LogEst.c /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
wordcount.exe: $(TOP)\test\wordcount.c $(SQLITE3C)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(TOP)\test\wordcount.c $(SQLITE3C)
|
||||
$(TOP)\test\wordcount.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
speedtest1.exe: $(TOP)\test\speedtest1.c $(SQLITE3C)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(TOP)\test\speedtest1.c $(SQLITE3C)
|
||||
$(TOP)\test\speedtest1.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
clean:
|
||||
del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL
|
||||
@@ -1861,7 +1871,7 @@ dll: sqlite3.dll
|
||||
sqlite3.def: libsqlite3.lib
|
||||
echo EXPORTS > sqlite3.def
|
||||
dumpbin /all libsqlite3.lib \
|
||||
| $(NAWK) "/ 1 _?sqlite3_/ { sub(/^.* _?/,\"\");print }" \
|
||||
| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3_.*)$$" \1 \
|
||||
| sort >> sqlite3.def
|
||||
|
||||
sqlite3.dll: $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
|
||||
|
||||
@@ -1,673 +0,0 @@
|
||||
#!/usr/make
|
||||
#
|
||||
# Makefile for SQLITE on VxWorks
|
||||
|
||||
ifeq ($(FORCPU),)
|
||||
FORCPU = SH32gnule
|
||||
endif
|
||||
|
||||
TOOL_FAMILY = gnu
|
||||
|
||||
include $(WIND_USR)/tool/gnu/make.$(FORCPU)
|
||||
|
||||
#### The toplevel directory of the source tree. This is the directory
|
||||
# that contains this "Makefile.in" and the "configure.in" script.
|
||||
#
|
||||
TOP = .
|
||||
|
||||
#### C Compiler and options for use in building executables that
|
||||
# will run on the platform that is doing the build.
|
||||
#
|
||||
BCC = gcc -g -O2
|
||||
#BCC = /opt/ancic/bin/c89 -0
|
||||
|
||||
#### If the target operating system supports the "usleep()" system
|
||||
# call, then define the HAVE_USLEEP macro for all C modules.
|
||||
#
|
||||
USLEEP =
|
||||
#USLEEP = -DHAVE_USLEEP=1
|
||||
|
||||
#### If you want the SQLite library to be safe for use within a
|
||||
# multi-threaded program, then define the following macro
|
||||
# appropriately:
|
||||
#
|
||||
THREADSAFE = -DSQLITE_THREADSAFE=1
|
||||
#THREADSAFE = -DSQLITE_THREADSAFE=0
|
||||
|
||||
#### Specify any extra linker options needed to make the library
|
||||
# thread safe
|
||||
#
|
||||
#THREADLIB = -lpthread
|
||||
THREADLIB =
|
||||
|
||||
#### Specify any extra libraries needed to access required functions.
|
||||
#
|
||||
ifeq ($(CPU),SH32)
|
||||
# for SH4 shared library
|
||||
TLIBS_SHARED += -L$(WIND_USR)/lib/sh/SH32/commonle/PIC
|
||||
else
|
||||
# for all other CPUs shared library
|
||||
TLIBS_SHARED += $(LD_LINK_PATH_ATEND) $(LD_PARTIAL_LAST_FLAGS)
|
||||
endif
|
||||
# for static library
|
||||
TLIBS += $(LD_LINK_PATH_ATEND) $(LD_PARTIAL_LAST_FLAGS)
|
||||
|
||||
#### Leave SQLITE_DEBUG undefined for maximum speed. Use SQLITE_DEBUG=1
|
||||
# to check for memory leaks. Use SQLITE_DEBUG=2 to print a log of all
|
||||
# malloc()s and free()s in order to track down memory leaks.
|
||||
#
|
||||
# SQLite uses some expensive assert() statements in the inner loop.
|
||||
# You can make the library go almost twice as fast if you compile
|
||||
# with -DNDEBUG=1
|
||||
#
|
||||
#OPTS = -DSQLITE_DEBUG=2
|
||||
#OPTS = -DSQLITE_DEBUG=1
|
||||
#OPTS =
|
||||
OPTS = -DNDEBUG=1 -DSQLITE_OS_UNIX=1 $(THREADSAFE)
|
||||
OPTS += -DSQLITE_OMIT_LOAD_EXTENSION=1
|
||||
OPTS += -DSQLITE_ENABLE_LOCKING_STYLE=1
|
||||
OPTS += -DSQLITE_THREAD_OVERRIDE_LOCK=0
|
||||
OPTS += -DSQLITE_ENABLE_COLUMN_METADATA=1
|
||||
OPTS += -DHAVE_FDATASYNC=1
|
||||
|
||||
#### The suffix to add to executable files. ".exe" for windows.
|
||||
# Nothing for unix.
|
||||
#
|
||||
EXE = .vxe
|
||||
#EXE =
|
||||
|
||||
#### C Compile and options for use in building executables that
|
||||
# will run on the target platform. This is usually the same
|
||||
# as BCC, unless you are cross-compiling.
|
||||
#
|
||||
#TCC = gcc -O6
|
||||
#TCC = gcc -g -O0 -Wall
|
||||
#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage
|
||||
#TCC = /opt/mingw/bin/i386-mingw32-gcc -O6
|
||||
TCC = $(CC) $(DEFINE_CC) -O2 -g -mrtp $(CC_ARCH_SPEC) -D_REENTRANT=1 -D_VX_CPU=_VX_$(CPU) -D_VX_TOOL_FAMILY=$(TOOL_FAMILY) -D_VX_TOOL=$(TOOL)
|
||||
TCC += -I$(WIND_USR)/h -I$(WIND_USR)/h/wrn/coreip
|
||||
#TCC = /opt/ansic/bin/c89 -O +z -Wl,-a,archive
|
||||
|
||||
#TCC_SHARED = $(TCC) -fPIC
|
||||
TCC_SHARED = $(TCC)
|
||||
|
||||
#### Tools used to build a static library.
|
||||
#
|
||||
#ARX = ar cr
|
||||
#ARX = /opt/mingw/bin/i386-mingw32-ar cr
|
||||
AR += cr
|
||||
#RANLIB = ranlib
|
||||
#RANLIB = /opt/mingw/bin/i386-mingw32-ranlib
|
||||
|
||||
#MKSHLIB = gcc -shared
|
||||
#SO = so
|
||||
#SHPREFIX = lib
|
||||
MKSHLIB = $(CC) $(DEFINE_CC) -mrtp -shared $(CC_ARCH_SPEC) -D_VX_CPU=_VX_$(CPU) -D_VX_TOOL_FAMILY=$(TOOL_FAMILY) -D_VX_TOOL=$(TOOL)
|
||||
SO = so
|
||||
SHPREFIX = lib
|
||||
|
||||
#### Extra compiler options needed for programs that use the TCL library.
|
||||
#
|
||||
#TCL_FLAGS =
|
||||
#TCL_FLAGS = -DSTATIC_BUILD=1
|
||||
TCL_FLAGS = -I/home/drh/tcltk/8.5linux
|
||||
#TCL_FLAGS = -I/home/drh/tcltk/8.5win -DSTATIC_BUILD=1
|
||||
#TCL_FLAGS = -I/home/drh/tcltk/8.3hpux
|
||||
|
||||
#### Linker options needed to link against the TCL library.
|
||||
#
|
||||
#LIBTCL = -ltcl -lm -ldl
|
||||
LIBTCL = /home/drh/tcltk/8.5linux/libtcl8.5g.a -lm -ldl
|
||||
#LIBTCL = /home/drh/tcltk/8.5win/libtcl85s.a -lmsvcrt
|
||||
#LIBTCL = /home/drh/tcltk/8.3hpux/libtcl8.3.a -ldld -lm -lc
|
||||
|
||||
#### Additional objects for SQLite library when TCL support is enabled.
|
||||
TCLOBJ =
|
||||
#TCLOBJ = tclsqlite.o
|
||||
|
||||
#### Compiler options needed for programs that use the readline() library.
|
||||
#
|
||||
READLINE_FLAGS =
|
||||
#READLINE_FLAGS = -DHAVE_READLINE=1 -I/usr/include/readline
|
||||
|
||||
#### Linker options needed by programs using readline() must link against.
|
||||
#
|
||||
LIBREADLINE =
|
||||
#LIBREADLINE = -static -lreadline -ltermcap
|
||||
|
||||
#### Which "awk" program provides nawk compatibilty
|
||||
#
|
||||
# NAWK = nawk
|
||||
NAWK = awk
|
||||
|
||||
|
||||
#### Pasted and adapted main.mk file
|
||||
###############################################################################
|
||||
# The following macros should be defined before this script is
|
||||
# invoked:
|
||||
#
|
||||
# TOP The toplevel directory of the source tree. This is the
|
||||
# directory that contains this "Makefile.in" and the
|
||||
# "configure.in" script.
|
||||
#
|
||||
# BCC C Compiler and options for use in building executables that
|
||||
# will run on the platform that is doing the build.
|
||||
#
|
||||
# THREADLIB Specify any extra linker options needed to make the library
|
||||
# thread safe
|
||||
#
|
||||
# OPTS Extra compiler command-line options.
|
||||
#
|
||||
# EXE The suffix to add to executable files. ".exe" for windows
|
||||
# and "" for Unix.
|
||||
#
|
||||
# TCC C Compiler and options for use in building executables that
|
||||
# will run on the target platform. This is usually the same
|
||||
# as BCC, unless you are cross-compiling.
|
||||
#
|
||||
# AR Tools used to build a static library.
|
||||
# RANLIB
|
||||
#
|
||||
# TCL_FLAGS Extra compiler options needed for programs that use the
|
||||
# TCL library.
|
||||
#
|
||||
# LIBTCL Linker options needed to link against the TCL library.
|
||||
#
|
||||
# READLINE_FLAGS Compiler options needed for programs that use the
|
||||
# readline() library.
|
||||
#
|
||||
# LIBREADLINE Linker options needed by programs using readline() must
|
||||
# link against.
|
||||
#
|
||||
# NAWK Nawk compatible awk program. Older (obsolete?) solaris
|
||||
# systems need this to avoid using the original AT&T AWK.
|
||||
#
|
||||
# Once the macros above are defined, the rest of this make script will
|
||||
# build the SQLite library and testing tools.
|
||||
################################################################################
|
||||
|
||||
# This is how we compile
|
||||
#
|
||||
TCCX = $(TCC) $(OPTS) -I. -I$(TOP)/src -I$(TOP)
|
||||
TCCX_SHARED = $(TCC_SHARED) $(OPTS) -I. -I$(TOP)/src -I$(TOP) \
|
||||
-I$(TOP)/ext/rtree -I$(TOP)/ext/icu -I$(TOP)/ext/fts3 \
|
||||
-I$(TOP)/ext/async
|
||||
|
||||
# Object files for the SQLite library.
|
||||
#
|
||||
LIBOBJ+= alter.o analyze.o attach.o auth.o \
|
||||
backup.o bitvec.o btmutex.o btree.o build.o \
|
||||
callback.o complete.o date.o delete.o expr.o fault.o \
|
||||
fts3.o fts3_expr.o fts3_hash.o fts3_icu.o fts3_porter.o \
|
||||
fts3_tokenizer.o fts3_tokenizer1.o \
|
||||
func.o global.o hash.o \
|
||||
icu.o insert.o journal.o legacy.o loadext.o \
|
||||
main.o malloc.o mem0.o mem1.o mem2.o mem3.o mem5.o \
|
||||
memjournal.o \
|
||||
mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \
|
||||
notify.o opcodes.o os.o os_unix.o os_win.o \
|
||||
pager.o parse.o pcache.o pcache1.o pragma.o prepare.o printf.o \
|
||||
random.o resolve.o rowset.o rtree.o select.o status.o \
|
||||
table.o tokenize.o trigger.o \
|
||||
update.o util.o vacuum.o \
|
||||
vdbe.o vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o \
|
||||
walker.o where.o utf.o vtab.o
|
||||
|
||||
|
||||
|
||||
# All of the source code files.
|
||||
#
|
||||
SRC = \
|
||||
$(TOP)/src/alter.c \
|
||||
$(TOP)/src/analyze.c \
|
||||
$(TOP)/src/attach.c \
|
||||
$(TOP)/src/auth.c \
|
||||
$(TOP)/src/backup.c \
|
||||
$(TOP)/src/bitvec.c \
|
||||
$(TOP)/src/btmutex.c \
|
||||
$(TOP)/src/btree.c \
|
||||
$(TOP)/src/btree.h \
|
||||
$(TOP)/src/btreeInt.h \
|
||||
$(TOP)/src/build.c \
|
||||
$(TOP)/src/callback.c \
|
||||
$(TOP)/src/complete.c \
|
||||
$(TOP)/src/ctime.c \
|
||||
$(TOP)/src/date.c \
|
||||
$(TOP)/src/delete.c \
|
||||
$(TOP)/src/expr.c \
|
||||
$(TOP)/src/fault.c \
|
||||
$(TOP)/src/func.c \
|
||||
$(TOP)/src/global.c \
|
||||
$(TOP)/src/hash.c \
|
||||
$(TOP)/src/hash.h \
|
||||
$(TOP)/src/hwtime.h \
|
||||
$(TOP)/src/insert.c \
|
||||
$(TOP)/src/journal.c \
|
||||
$(TOP)/src/legacy.c \
|
||||
$(TOP)/src/loadext.c \
|
||||
$(TOP)/src/main.c \
|
||||
$(TOP)/src/malloc.c \
|
||||
$(TOP)/src/mem0.c \
|
||||
$(TOP)/src/mem1.c \
|
||||
$(TOP)/src/mem2.c \
|
||||
$(TOP)/src/mem3.c \
|
||||
$(TOP)/src/mem5.c \
|
||||
$(TOP)/src/memjournal.c \
|
||||
$(TOP)/src/msvc.h \
|
||||
$(TOP)/src/mutex.c \
|
||||
$(TOP)/src/mutex.h \
|
||||
$(TOP)/src/mutex_noop.c \
|
||||
$(TOP)/src/mutex_unix.c \
|
||||
$(TOP)/src/mutex_w32.c \
|
||||
$(TOP)/src/notify.c \
|
||||
$(TOP)/src/os.c \
|
||||
$(TOP)/src/os.h \
|
||||
$(TOP)/src/os_common.h \
|
||||
$(TOP)/src/os_setup.h \
|
||||
$(TOP)/src/os_unix.c \
|
||||
$(TOP)/src/os_win.c \
|
||||
$(TOP)/src/os_win.h \
|
||||
$(TOP)/src/pager.c \
|
||||
$(TOP)/src/pager.h \
|
||||
$(TOP)/src/parse.y \
|
||||
$(TOP)/src/pcache.c \
|
||||
$(TOP)/src/pcache.h \
|
||||
$(TOP)/src/pcache1.c \
|
||||
$(TOP)/src/pragma.c \
|
||||
$(TOP)/src/prepare.c \
|
||||
$(TOP)/src/printf.c \
|
||||
$(TOP)/src/random.c \
|
||||
$(TOP)/src/resolve.c \
|
||||
$(TOP)/src/rowset.c \
|
||||
$(TOP)/src/select.c \
|
||||
$(TOP)/src/status.c \
|
||||
$(TOP)/src/shell.c \
|
||||
$(TOP)/src/sqlite.h.in \
|
||||
$(TOP)/src/sqlite3ext.h \
|
||||
$(TOP)/src/sqliteInt.h \
|
||||
$(TOP)/src/sqliteLimit.h \
|
||||
$(TOP)/src/table.c \
|
||||
$(TOP)/src/tclsqlite.c \
|
||||
$(TOP)/src/tokenize.c \
|
||||
$(TOP)/src/trigger.c \
|
||||
$(TOP)/src/utf.c \
|
||||
$(TOP)/src/update.c \
|
||||
$(TOP)/src/util.c \
|
||||
$(TOP)/src/vacuum.c \
|
||||
$(TOP)/src/vdbe.c \
|
||||
$(TOP)/src/vdbe.h \
|
||||
$(TOP)/src/vdbeapi.c \
|
||||
$(TOP)/src/vdbeaux.c \
|
||||
$(TOP)/src/vdbeblob.c \
|
||||
$(TOP)/src/vdbemem.c \
|
||||
$(TOP)/src/vdbeInt.h \
|
||||
$(TOP)/src/vtab.c \
|
||||
$(TOP)/src/walker.c \
|
||||
$(TOP)/src/where.c
|
||||
|
||||
# Source code for extensions
|
||||
#
|
||||
SRC += \
|
||||
$(TOP)/ext/fts1/fts1.c \
|
||||
$(TOP)/ext/fts1/fts1.h \
|
||||
$(TOP)/ext/fts1/fts1_hash.c \
|
||||
$(TOP)/ext/fts1/fts1_hash.h \
|
||||
$(TOP)/ext/fts1/fts1_porter.c \
|
||||
$(TOP)/ext/fts1/fts1_tokenizer.h \
|
||||
$(TOP)/ext/fts1/fts1_tokenizer1.c
|
||||
SRC += \
|
||||
$(TOP)/ext/fts2/fts2.c \
|
||||
$(TOP)/ext/fts2/fts2.h \
|
||||
$(TOP)/ext/fts2/fts2_hash.c \
|
||||
$(TOP)/ext/fts2/fts2_hash.h \
|
||||
$(TOP)/ext/fts2/fts2_icu.c \
|
||||
$(TOP)/ext/fts2/fts2_porter.c \
|
||||
$(TOP)/ext/fts2/fts2_tokenizer.h \
|
||||
$(TOP)/ext/fts2/fts2_tokenizer.c \
|
||||
$(TOP)/ext/fts2/fts2_tokenizer1.c
|
||||
SRC += \
|
||||
$(TOP)/ext/fts3/fts3.c \
|
||||
$(TOP)/ext/fts3/fts3.h \
|
||||
$(TOP)/ext/fts3/fts3_expr.c \
|
||||
$(TOP)/ext/fts3/fts3_expr.h \
|
||||
$(TOP)/ext/fts3/fts3_hash.c \
|
||||
$(TOP)/ext/fts3/fts3_hash.h \
|
||||
$(TOP)/ext/fts3/fts3_icu.c \
|
||||
$(TOP)/ext/fts3/fts3_porter.c \
|
||||
$(TOP)/ext/fts3/fts3_tokenizer.h \
|
||||
$(TOP)/ext/fts3/fts3_tokenizer.c \
|
||||
$(TOP)/ext/fts3/fts3_tokenizer1.c
|
||||
SRC += \
|
||||
$(TOP)/ext/icu/sqliteicu.h \
|
||||
$(TOP)/ext/icu/icu.c
|
||||
SRC += \
|
||||
$(TOP)/ext/rtree/rtree.h \
|
||||
$(TOP)/ext/rtree/rtree.c
|
||||
|
||||
|
||||
# Generated source code files
|
||||
#
|
||||
SRC += \
|
||||
keywordhash.h \
|
||||
opcodes.c \
|
||||
opcodes.h \
|
||||
parse.c \
|
||||
parse.h \
|
||||
sqlite3.h
|
||||
|
||||
|
||||
# Source code to the test files.
|
||||
#
|
||||
TESTSRC = \
|
||||
$(TOP)/src/test1.c \
|
||||
$(TOP)/src/test2.c \
|
||||
$(TOP)/src/test3.c \
|
||||
$(TOP)/src/test4.c \
|
||||
$(TOP)/src/test5.c \
|
||||
$(TOP)/src/test6.c \
|
||||
$(TOP)/src/test7.c \
|
||||
$(TOP)/src/test8.c \
|
||||
$(TOP)/src/test9.c \
|
||||
$(TOP)/src/test_autoext.c \
|
||||
$(TOP)/src/test_async.c \
|
||||
$(TOP)/src/test_backup.c \
|
||||
$(TOP)/src/test_btree.c \
|
||||
$(TOP)/src/test_config.c \
|
||||
$(TOP)/src/test_devsym.c \
|
||||
$(TOP)/src/test_func.c \
|
||||
$(TOP)/src/test_hexio.c \
|
||||
$(TOP)/src/test_journal.c \
|
||||
$(TOP)/src/test_malloc.c \
|
||||
$(TOP)/src/test_md5.c \
|
||||
$(TOP)/src/test_mutex.c \
|
||||
$(TOP)/src/test_onefile.c \
|
||||
$(TOP)/src/test_osinst.c \
|
||||
$(TOP)/src/test_pcache.c \
|
||||
$(TOP)/src/test_schema.c \
|
||||
$(TOP)/src/test_server.c \
|
||||
$(TOP)/src/test_tclvar.c \
|
||||
$(TOP)/src/test_thread.c \
|
||||
$(TOP)/src/test_vfs.c \
|
||||
$(TOP)/src/test_wsd.c \
|
||||
|
||||
#TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c
|
||||
#TESTSRC += $(TOP)/ext/fts3/fts3_tokenizer.c
|
||||
|
||||
TESTSRC2 = \
|
||||
$(TOP)/src/attach.c $(TOP)/src/backup.c $(TOP)/src/btree.c \
|
||||
$(TOP)/src/build.c $(TOP)/src/ctime.c $(TOP)/src/date.c \
|
||||
$(TOP)/src/expr.c $(TOP)/src/func.c $(TOP)/src/insert.c $(TOP)/src/os.c \
|
||||
$(TOP)/src/os_unix.c $(TOP)/src/os_win.c \
|
||||
$(TOP)/src/pager.c $(TOP)/src/pragma.c $(TOP)/src/prepare.c \
|
||||
$(TOP)/src/printf.c $(TOP)/src/random.c $(TOP)/src/pcache.c \
|
||||
$(TOP)/src/pcache1.c $(TOP)/src/select.c $(TOP)/src/tokenize.c \
|
||||
$(TOP)/src/utf.c $(TOP)/src/util.c $(TOP)/src/vdbeapi.c $(TOP)/src/vdbeaux.c \
|
||||
$(TOP)/src/vdbe.c $(TOP)/src/vdbemem.c $(TOP)/src/where.c parse.c \
|
||||
$(TOP)/ext/fts3/fts3.c $(TOP)/ext/fts3/fts3_expr.c \
|
||||
$(TOP)/ext/fts3/fts3_tokenizer.c \
|
||||
$(TOP)/ext/async/sqlite3async.c
|
||||
|
||||
# Header files used by all library source files.
|
||||
#
|
||||
HDR = \
|
||||
$(TOP)/src/btree.h \
|
||||
$(TOP)/src/btreeInt.h \
|
||||
$(TOP)/src/hash.h \
|
||||
$(TOP)/src/hwtime.h \
|
||||
keywordhash.h \
|
||||
$(TOP)/src/msvc.h \
|
||||
$(TOP)/src/mutex.h \
|
||||
opcodes.h \
|
||||
$(TOP)/src/os.h \
|
||||
$(TOP)/src/os_common.h \
|
||||
$(TOP)/src/os_setup.h \
|
||||
$(TOP)/src/os_win.h \
|
||||
$(TOP)/src/pager.h \
|
||||
$(TOP)/src/pcache.h \
|
||||
parse.h \
|
||||
sqlite3.h \
|
||||
$(TOP)/src/sqlite3ext.h \
|
||||
$(TOP)/src/sqliteInt.h \
|
||||
$(TOP)/src/sqliteLimit.h \
|
||||
$(TOP)/src/vdbe.h \
|
||||
$(TOP)/src/vdbeInt.h
|
||||
|
||||
# Header files used by extensions
|
||||
#
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/fts1/fts1.h \
|
||||
$(TOP)/ext/fts1/fts1_hash.h \
|
||||
$(TOP)/ext/fts1/fts1_tokenizer.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/fts2/fts2.h \
|
||||
$(TOP)/ext/fts2/fts2_hash.h \
|
||||
$(TOP)/ext/fts2/fts2_tokenizer.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/fts3/fts3.h \
|
||||
$(TOP)/ext/fts3/fts3_expr.h \
|
||||
$(TOP)/ext/fts3/fts3_hash.h \
|
||||
$(TOP)/ext/fts3/fts3_tokenizer.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/rtree/rtree.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/icu/sqliteicu.h
|
||||
|
||||
# This is the default Makefile target. The objects listed here
|
||||
# are what get build when you type just "make" with no arguments.
|
||||
#
|
||||
all: sqlite3.h libsqlite3.a sqlite3$(EXE)
|
||||
|
||||
libsqlite3.a: $(LIBOBJ)
|
||||
$(AR) libsqlite3.a $(LIBOBJ)
|
||||
$(RANLIB) libsqlite3.a
|
||||
|
||||
$(SHPREFIX)sqlite3.$(SO): $(LIBOBJ)
|
||||
$(MKSHLIB) -o $(SHPREFIX)sqlite3.$(SO) $(LIBOBJ) $(TLIBS_SHARED)
|
||||
|
||||
sqlite3$(EXE): $(TOP)/src/shell.c libsqlite3.a sqlite3.h
|
||||
$(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE) \
|
||||
$(TOP)/src/shell.c \
|
||||
$(LIBREADLINE) $(TLIBS) $(THREADLIB) -L. -lsqlite3
|
||||
|
||||
# This target creates a directory named "tsrc" and fills it with
|
||||
# copies of all of the C source code and header files needed to
|
||||
# build on the target system. Some of the C source code and header
|
||||
# files are automatically generated. This target takes care of
|
||||
# all that automatic generation.
|
||||
#
|
||||
target_source: $(SRC)
|
||||
rm -rf tsrc
|
||||
mkdir tsrc
|
||||
cp -f $(SRC) tsrc
|
||||
rm tsrc/sqlite.h.in tsrc/parse.y
|
||||
touch target_source
|
||||
|
||||
sqlite3.c: target_source $(TOP)/tool/mksqlite3c.tcl
|
||||
tclsh $(TOP)/tool/mksqlite3c.tcl
|
||||
cp sqlite3.c tclsqlite3.c
|
||||
cat $(TOP)/src/tclsqlite.c >>tclsqlite3.c
|
||||
|
||||
fts2amal.c: target_source $(TOP)/ext/fts2/mkfts2amal.tcl
|
||||
tclsh $(TOP)/ext/fts2/mkfts2amal.tcl
|
||||
|
||||
fts3amal.c: target_source $(TOP)/ext/fts3/mkfts3amal.tcl
|
||||
tclsh $(TOP)/ext/fts3/mkfts3amal.tcl
|
||||
|
||||
# Rules to build the LEMON compiler generator
|
||||
#
|
||||
lemon: $(TOP)/tool/lemon.c $(TOP)/src/lempar.c
|
||||
$(BCC) -o lemon $(TOP)/tool/lemon.c
|
||||
cp $(TOP)/src/lempar.c .
|
||||
|
||||
# Rules to build individual *.o files from generated *.c files. This
|
||||
# applies to:
|
||||
#
|
||||
# parse.o
|
||||
# opcodes.o
|
||||
#
|
||||
%.o: %.c $(HDR)
|
||||
$(TCCX_SHARED) -c $<
|
||||
|
||||
# Rules to build individual *.o files from files in the src directory.
|
||||
#
|
||||
%.o: $(TOP)/src/%.c $(HDR)
|
||||
$(TCCX_SHARED) -c $<
|
||||
|
||||
tclsqlite.o: $(TOP)/src/tclsqlite.c $(HDR)
|
||||
$(TCCX_SHARED) $(TCL_FLAGS) -c $(TOP)/src/tclsqlite.c
|
||||
|
||||
|
||||
|
||||
# Rules to build opcodes.c and opcodes.h
|
||||
#
|
||||
opcodes.c: opcodes.h $(TOP)/mkopcodec.awk
|
||||
$(NAWK) -f $(TOP)/mkopcodec.awk opcodes.h >opcodes.c
|
||||
|
||||
opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk
|
||||
cat parse.h $(TOP)/src/vdbe.c | \
|
||||
$(NAWK) -f $(TOP)/mkopcodeh.awk >opcodes.h
|
||||
|
||||
# Rules to build parse.c and parse.h - the outputs of lemon.
|
||||
#
|
||||
parse.h: parse.c
|
||||
|
||||
parse.c: $(TOP)/src/parse.y lemon $(TOP)/addopcodes.awk
|
||||
cp $(TOP)/src/parse.y .
|
||||
rm -f parse.h
|
||||
./lemon $(OPTS) parse.y
|
||||
mv parse.h parse.h.temp
|
||||
awk -f $(TOP)/addopcodes.awk parse.h.temp >parse.h
|
||||
|
||||
sqlite3.h: $(TOP)/src/sqlite.h.in
|
||||
sed -e s/--VERS--/`cat ${TOP}/VERSION`/ \
|
||||
-e s/--VERSION-NUMBER--/`cat ${TOP}/VERSION | sed 's/[^0-9]/ /g' | $(NAWK) '{printf "%d%03d%03d",$$1,$$2,$$3}'`/ \
|
||||
$(TOP)/src/sqlite.h.in >sqlite3.h
|
||||
|
||||
keywordhash.h: $(TOP)/tool/mkkeywordhash.c
|
||||
$(BCC) -o mkkeywordhash $(OPTS) $(TOP)/tool/mkkeywordhash.c
|
||||
./mkkeywordhash >keywordhash.h
|
||||
|
||||
|
||||
|
||||
# Rules to build the extension objects.
|
||||
#
|
||||
icu.o: $(TOP)/ext/icu/icu.c $(HDR) $(EXTHDR)
|
||||
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/icu/icu.c
|
||||
|
||||
fts2.o: $(TOP)/ext/fts2/fts2.c $(HDR) $(EXTHDR)
|
||||
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2.c
|
||||
|
||||
fts2_hash.o: $(TOP)/ext/fts2/fts2_hash.c $(HDR) $(EXTHDR)
|
||||
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_hash.c
|
||||
|
||||
fts2_icu.o: $(TOP)/ext/fts2/fts2_icu.c $(HDR) $(EXTHDR)
|
||||
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_icu.c
|
||||
|
||||
fts2_porter.o: $(TOP)/ext/fts2/fts2_porter.c $(HDR) $(EXTHDR)
|
||||
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_porter.c
|
||||
|
||||
fts2_tokenizer.o: $(TOP)/ext/fts2/fts2_tokenizer.c $(HDR) $(EXTHDR)
|
||||
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_tokenizer.c
|
||||
|
||||
fts2_tokenizer1.o: $(TOP)/ext/fts2/fts2_tokenizer1.c $(HDR) $(EXTHDR)
|
||||
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_tokenizer1.c
|
||||
|
||||
fts3.o: $(TOP)/ext/fts3/fts3.c $(HDR) $(EXTHDR)
|
||||
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3.c
|
||||
|
||||
fts3_expr.o: $(TOP)/ext/fts3/fts3_expr.c $(HDR) $(EXTHDR)
|
||||
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_expr.c
|
||||
|
||||
fts3_hash.o: $(TOP)/ext/fts3/fts3_hash.c $(HDR) $(EXTHDR)
|
||||
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_hash.c
|
||||
|
||||
fts3_icu.o: $(TOP)/ext/fts3/fts3_icu.c $(HDR) $(EXTHDR)
|
||||
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_icu.c
|
||||
|
||||
fts3_porter.o: $(TOP)/ext/fts3/fts3_porter.c $(HDR) $(EXTHDR)
|
||||
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_porter.c
|
||||
|
||||
fts3_tokenizer.o: $(TOP)/ext/fts3/fts3_tokenizer.c $(HDR) $(EXTHDR)
|
||||
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer.c
|
||||
|
||||
fts3_tokenizer1.o: $(TOP)/ext/fts3/fts3_tokenizer1.c $(HDR) $(EXTHDR)
|
||||
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer1.c
|
||||
|
||||
rtree.o: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR)
|
||||
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c
|
||||
|
||||
|
||||
# Rules for building test programs and for running tests
|
||||
#
|
||||
tclsqlite3: $(TOP)/src/tclsqlite.c libsqlite3.a
|
||||
$(TCCX_SHARED) $(TCL_FLAGS) -DTCLSH=1 -o tclsqlite3 \
|
||||
$(TOP)/src/tclsqlite.c libsqlite3.a $(LIBTCL) $(THREADLIB)
|
||||
|
||||
|
||||
# Rules to build the 'testfixture' application.
|
||||
#
|
||||
TESTFIXTURE_FLAGS = -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
|
||||
TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE
|
||||
|
||||
testfixture$(EXE): $(TESTSRC2) libsqlite3.a $(TESTSRC) $(TOP)/src/tclsqlite.c
|
||||
$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS) \
|
||||
$(TESTSRC) $(TESTSRC2) $(TOP)/src/tclsqlite.c \
|
||||
-o testfixture$(EXE) $(LIBTCL) $(THREADLIB) libsqlite3.a
|
||||
|
||||
amalgamation-testfixture$(EXE): sqlite3.c $(TESTSRC) $(TOP)/src/tclsqlite.c
|
||||
$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS) \
|
||||
$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c \
|
||||
-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
|
||||
|
||||
fts3-testfixture$(EXE): sqlite3.c fts3amal.c $(TESTSRC) $(TOP)/src/tclsqlite.c
|
||||
$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS) \
|
||||
-DSQLITE_ENABLE_FTS3=1 \
|
||||
$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c fts3amal.c \
|
||||
-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
|
||||
|
||||
fulltest: testfixture$(EXE) sqlite3$(EXE)
|
||||
./testfixture$(EXE) $(TOP)/test/all.test
|
||||
|
||||
soaktest: testfixture$(EXE) sqlite3$(EXE)
|
||||
./testfixture$(EXE) $(TOP)/test/all.test -soak=1
|
||||
|
||||
fulltestonly: testfixture$(EXE) sqlite3$(EXE)
|
||||
./testfixture$(EXE) $(TOP)/test/full.test
|
||||
|
||||
test: testfixture$(EXE) sqlite3$(EXE)
|
||||
./testfixture$(EXE) $(TOP)/test/veryquick.test
|
||||
|
||||
sqlite3_analyzer$(EXE): $(TOP)/src/tclsqlite.c sqlite3.c $(TESTSRC) \
|
||||
$(TOP)/tool/spaceanal.tcl
|
||||
sed \
|
||||
-e '/^#/d' \
|
||||
-e 's,\\,\\\\,g' \
|
||||
-e 's,",\\",g' \
|
||||
-e 's,^,",' \
|
||||
-e 's,$$,\\n",' \
|
||||
$(TOP)/tool/spaceanal.tcl >spaceanal_tcl.h
|
||||
$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS) \
|
||||
-DTCLSH=2 -DSQLITE_TEST=1 -DSQLITE_DEBUG=1 -DSQLITE_PRIVATE="" \
|
||||
$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c \
|
||||
-o sqlite3_analyzer$(EXE) \
|
||||
$(LIBTCL) $(THREADLIB)
|
||||
|
||||
TEST_EXTENSION = $(SHPREFIX)testloadext.$(SO)
|
||||
$(TEST_EXTENSION): $(TOP)/src/test_loadext.c
|
||||
$(MKSHLIB) $(TOP)/src/test_loadext.c -o $(TEST_EXTENSION)
|
||||
|
||||
extensiontest: testfixture$(EXE) $(TEST_EXTENSION)
|
||||
./testfixture$(EXE) $(TOP)/test/loadext.test
|
||||
|
||||
clean:
|
||||
rm -f *.o sqlite3$(EXE) libsqlite3.a sqlite3.h opcodes.*
|
||||
rm -f lemon lempar.c parse.* sqlite*.tar.gz mkkeywordhash keywordhash.h
|
||||
rm -f $(PUBLISH)
|
||||
rm -f *.da *.bb *.bbg gmon.out
|
||||
rm -rf quota2a quota2b quota2c
|
||||
rm -rf tsrc target_source
|
||||
rm -f testloadext.dll libtestloadext.so
|
||||
rm -f sqlite3.c fts?amal.c tclsqlite3.c
|
||||
rm -f sqlite3rc.h
|
||||
rm -f shell.c sqlite3ext.h
|
||||
rm -f $(SHPREFIX)sqlite3.$(SO)
|
||||
@@ -1,34 +0,0 @@
|
||||
#!/usr/bin/awk
|
||||
#
|
||||
# This script appends additional token codes to the end of the
|
||||
# parse.h file that lemon generates. These extra token codes are
|
||||
# not used by the parser. But they are used by the tokenizer and/or
|
||||
# the code generator.
|
||||
#
|
||||
#
|
||||
BEGIN {
|
||||
max = 0
|
||||
}
|
||||
/^#define TK_/ {
|
||||
print $0
|
||||
if( max<$3 ) max = $3
|
||||
}
|
||||
END {
|
||||
printf "#define TK_%-29s %4d\n", "TO_TEXT", ++max
|
||||
printf "#define TK_%-29s %4d\n", "TO_BLOB", ++max
|
||||
printf "#define TK_%-29s %4d\n", "TO_NUMERIC", ++max
|
||||
printf "#define TK_%-29s %4d\n", "TO_INT", ++max
|
||||
printf "#define TK_%-29s %4d\n", "TO_REAL", ++max
|
||||
printf "#define TK_%-29s %4d\n", "ISNOT", ++max
|
||||
printf "#define TK_%-29s %4d\n", "END_OF_FILE", ++max
|
||||
printf "#define TK_%-29s %4d\n", "ILLEGAL", ++max
|
||||
printf "#define TK_%-29s %4d\n", "SPACE", ++max
|
||||
printf "#define TK_%-29s %4d\n", "UNCLOSED_STRING", ++max
|
||||
printf "#define TK_%-29s %4d\n", "FUNCTION", ++max
|
||||
printf "#define TK_%-29s %4d\n", "COLUMN", ++max
|
||||
printf "#define TK_%-29s %4d\n", "AGG_FUNCTION", ++max
|
||||
printf "#define TK_%-29s %4d\n", "AGG_COLUMN", ++max
|
||||
printf "#define TK_%-29s %4d\n", "UMINUS", ++max
|
||||
printf "#define TK_%-29s %4d\n", "UPLUS", ++max
|
||||
printf "#define TK_%-29s %4d\n", "REGISTER", ++max
|
||||
}
|
||||
+17
-3
@@ -18,7 +18,6 @@ AC_SYS_LARGEFILE
|
||||
|
||||
# Check for required programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_RANLIB
|
||||
AC_PROG_LIBTOOL
|
||||
AC_PROG_MKDIR_P
|
||||
|
||||
@@ -30,12 +29,27 @@ AC_CONFIG_FILES([Makefile sqlite3.pc])
|
||||
AC_SUBST(BUILD_CFLAGS)
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
# --enable-editline
|
||||
# --enable-readline
|
||||
#
|
||||
AC_ARG_ENABLE(editline, [AS_HELP_STRING(
|
||||
[--enable-editline],
|
||||
[use BSD libedit])],
|
||||
[], [enable_editline=yes])
|
||||
AC_ARG_ENABLE(readline, [AS_HELP_STRING(
|
||||
[--enable-readline],
|
||||
[use readline in shell tool (yes, no) [default=yes]])],
|
||||
[], [enable_readline=yes])
|
||||
[use readline])],
|
||||
[], [enable_readline=no])
|
||||
if test x"$enable_editline" != xno ; then
|
||||
sLIBS=$LIBS
|
||||
LIBS=""
|
||||
AC_SEARCH_LIBS([readline],[edit],[enable_readline=no],[enable_editline=no])
|
||||
READLINE_LIBS=$LIBS
|
||||
if test x"$LIBS" != "x"; then
|
||||
AC_DEFINE([HAVE_EDITLINE],1,Define to use BSD editline)
|
||||
fi
|
||||
LIBS=$sLIBS
|
||||
fi
|
||||
if test x"$enable_readline" != xno ; then
|
||||
sLIBS=$LIBS
|
||||
LIBS=""
|
||||
|
||||
@@ -603,8 +603,8 @@ SubstituteFile(
|
||||
sp = fopen(substitutions, "rt");
|
||||
if (sp != NULL) {
|
||||
while (fgets(szBuffer, cbBuffer, sp) != NULL) {
|
||||
char *ks, *ke, *vs, *ve;
|
||||
ks = szBuffer;
|
||||
unsigned char *ks, *ke, *vs, *ve;
|
||||
ks = (unsigned char*)szBuffer;
|
||||
while (ks && *ks && isspace(*ks)) ++ks;
|
||||
ke = ks;
|
||||
while (ke && *ke && !isspace(*ke)) ++ke;
|
||||
@@ -613,7 +613,7 @@ SubstituteFile(
|
||||
ve = vs;
|
||||
while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
|
||||
*ke = 0, *ve = 0;
|
||||
list_insert(&substPtr, ks, vs);
|
||||
list_insert(&substPtr, (char*)ks, (char*)vs);
|
||||
}
|
||||
fclose(sp);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for sqlite 3.9.1.
|
||||
# Generated by GNU Autoconf 2.69 for sqlite 3.10.0.
|
||||
#
|
||||
#
|
||||
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
||||
@@ -726,8 +726,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='sqlite'
|
||||
PACKAGE_TARNAME='sqlite'
|
||||
PACKAGE_VERSION='3.9.1'
|
||||
PACKAGE_STRING='sqlite 3.9.1'
|
||||
PACKAGE_VERSION='3.10.0'
|
||||
PACKAGE_STRING='sqlite 3.10.0'
|
||||
PACKAGE_BUGREPORT=''
|
||||
PACKAGE_URL=''
|
||||
|
||||
@@ -774,6 +774,7 @@ USE_GCOV
|
||||
OPT_FEATURE_FLAGS
|
||||
USE_AMALGAMATION
|
||||
TARGET_DEBUG
|
||||
TARGET_HAVE_EDITLINE
|
||||
TARGET_HAVE_READLINE
|
||||
TARGET_READLINE_INC
|
||||
TARGET_READLINE_LIBS
|
||||
@@ -803,7 +804,6 @@ VERSION
|
||||
program_prefix
|
||||
TCLLIBDIR
|
||||
TCLSH_CMD
|
||||
AWK
|
||||
INSTALL_DATA
|
||||
INSTALL_SCRIPT
|
||||
INSTALL_PROGRAM
|
||||
@@ -896,6 +896,7 @@ enable_releasemode
|
||||
enable_tempstore
|
||||
enable_tcl
|
||||
with_tcl
|
||||
enable_editline
|
||||
enable_readline
|
||||
with_readline_lib
|
||||
with_readline_inc
|
||||
@@ -1459,7 +1460,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures sqlite 3.9.1 to adapt to many kinds of systems.
|
||||
\`configure' configures sqlite 3.10.0 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1524,7 +1525,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of sqlite 3.9.1:";;
|
||||
short | recursive ) echo "Configuration of sqlite 3.10.0:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1543,7 +1544,8 @@ Optional Features:
|
||||
--enable-tempstore Use an in-ram database for temporary tables
|
||||
(never,no,yes,always)
|
||||
--disable-tcl do not build TCL extension
|
||||
--disable-readline disable readline support [default=detect]
|
||||
--enable-editline enable BSD editline support
|
||||
--disable-readline disable readline support
|
||||
--enable-debug enable debugging & verbose explain
|
||||
--disable-amalgamation Disable the amalgamation and instead build all files
|
||||
separately
|
||||
@@ -1644,7 +1646,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
sqlite configure 3.9.1
|
||||
sqlite configure 3.10.0
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@@ -2063,7 +2065,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by sqlite $as_me 3.9.1, which was
|
||||
It was created by sqlite $as_me 3.10.0, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -3921,13 +3923,13 @@ if ${lt_cv_nm_interface+:} false; then :
|
||||
else
|
||||
lt_cv_nm_interface="BSD nm"
|
||||
echo "int some_variable = 0;" > conftest.$ac_ext
|
||||
(eval echo "\"\$as_me:3924: $ac_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:3926: $ac_compile\"" >&5)
|
||||
(eval "$ac_compile" 2>conftest.err)
|
||||
cat conftest.err >&5
|
||||
(eval echo "\"\$as_me:3927: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
|
||||
(eval echo "\"\$as_me:3929: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
|
||||
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
|
||||
cat conftest.err >&5
|
||||
(eval echo "\"\$as_me:3930: output\"" >&5)
|
||||
(eval echo "\"\$as_me:3932: output\"" >&5)
|
||||
cat conftest.out >&5
|
||||
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
|
||||
lt_cv_nm_interface="MS dumpbin"
|
||||
@@ -5133,7 +5135,7 @@ ia64-*-hpux*)
|
||||
;;
|
||||
*-*-irix6*)
|
||||
# Find out which ABI we are using.
|
||||
echo '#line 5136 "configure"' > conftest.$ac_ext
|
||||
echo '#line 5138 "configure"' > conftest.$ac_ext
|
||||
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
|
||||
(eval $ac_compile) 2>&5
|
||||
ac_status=$?
|
||||
@@ -6658,11 +6660,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:6661: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:6663: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:6665: \$? = $ac_status" >&5
|
||||
echo "$as_me:6667: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
@@ -6997,11 +6999,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:7000: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:7002: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:7004: \$? = $ac_status" >&5
|
||||
echo "$as_me:7006: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
@@ -7102,11 +7104,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:7105: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:7107: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:7109: \$? = $ac_status" >&5
|
||||
echo "$as_me:7111: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@@ -7157,11 +7159,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:7160: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:7162: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:7164: \$? = $ac_status" >&5
|
||||
echo "$as_me:7166: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@@ -9537,7 +9539,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 9540 "configure"
|
||||
#line 9542 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@@ -9633,7 +9635,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 9636 "configure"
|
||||
#line 9638 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@@ -9953,48 +9955,6 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
|
||||
|
||||
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
|
||||
|
||||
for ac_prog in gawk mawk nawk awk
|
||||
do
|
||||
# Extract the first word of "$ac_prog", so it can be a program name with args.
|
||||
set dummy $ac_prog; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_prog_AWK+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
if test -n "$AWK"; then
|
||||
ac_cv_prog_AWK="$AWK" # Let the user override the test.
|
||||
else
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_prog_AWK="$ac_prog"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
fi
|
||||
fi
|
||||
AWK=$ac_cv_prog_AWK
|
||||
if test -n "$AWK"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
|
||||
$as_echo "$AWK" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
test -n "$AWK" && break
|
||||
done
|
||||
|
||||
|
||||
#########
|
||||
# Enable large file support (if special flags are necessary)
|
||||
@@ -10875,6 +10835,14 @@ fi
|
||||
TARGET_READLINE_LIBS=""
|
||||
TARGET_READLINE_INC=""
|
||||
TARGET_HAVE_READLINE=0
|
||||
TARGET_HAVE_EDITLINE=0
|
||||
# Check whether --enable-editline was given.
|
||||
if test "${enable_editline+set}" = set; then :
|
||||
enableval=$enable_editline; with_editline=$enableval
|
||||
else
|
||||
with_editline=auto
|
||||
fi
|
||||
|
||||
# Check whether --enable-readline was given.
|
||||
if test "${enable_readline+set}" = set; then :
|
||||
enableval=$enable_readline; with_readline=$enableval
|
||||
@@ -10883,6 +10851,71 @@ else
|
||||
fi
|
||||
|
||||
|
||||
if test x"$with_editline" != xno; then
|
||||
sLIBS=$LIBS
|
||||
LIBS=""
|
||||
TARGET_HAVE_EDITLINE=1
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing readline" >&5
|
||||
$as_echo_n "checking for library containing readline... " >&6; }
|
||||
if ${ac_cv_search_readline+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_func_search_save_LIBS=$LIBS
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char readline ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return readline ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
for ac_lib in '' edit; do
|
||||
if test -z "$ac_lib"; then
|
||||
ac_res="none required"
|
||||
else
|
||||
ac_res=-l$ac_lib
|
||||
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
|
||||
fi
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_search_readline=$ac_res
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext
|
||||
if ${ac_cv_search_readline+:} false; then :
|
||||
break
|
||||
fi
|
||||
done
|
||||
if ${ac_cv_search_readline+:} false; then :
|
||||
|
||||
else
|
||||
ac_cv_search_readline=no
|
||||
fi
|
||||
rm conftest.$ac_ext
|
||||
LIBS=$ac_func_search_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_readline" >&5
|
||||
$as_echo "$ac_cv_search_readline" >&6; }
|
||||
ac_res=$ac_cv_search_readline
|
||||
if test "$ac_res" != no; then :
|
||||
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
|
||||
with_readline=no
|
||||
else
|
||||
TARGET_HAVE_EDITLINE=0
|
||||
fi
|
||||
|
||||
TARGET_READLINE_LIBS=$LIBS
|
||||
LIBS=$sLIBS
|
||||
fi
|
||||
if test x"$with_readline" != xno; then
|
||||
found="yes"
|
||||
|
||||
@@ -11071,6 +11104,7 @@ fi
|
||||
|
||||
|
||||
|
||||
|
||||
##########
|
||||
# Figure out what C libraries are required to compile programs
|
||||
# that use "fdatasync()" function.
|
||||
@@ -11989,7 +12023,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by sqlite $as_me 3.9.1, which was
|
||||
This file was extended by sqlite $as_me 3.10.0, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -12055,7 +12089,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
sqlite config.status 3.9.1
|
||||
sqlite config.status 3.10.0
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
@@ -12066,7 +12100,6 @@ gives unlimited permission to copy, distribute and modify it."
|
||||
ac_pwd='$ac_pwd'
|
||||
srcdir='$srcdir'
|
||||
INSTALL='$INSTALL'
|
||||
AWK='$AWK'
|
||||
test -n "\$AWK" || AWK=awk
|
||||
_ACEOF
|
||||
|
||||
|
||||
+15
-2
@@ -90,7 +90,6 @@ fi
|
||||
#
|
||||
AC_PROG_LIBTOOL
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_AWK
|
||||
|
||||
#########
|
||||
# Enable large file support (if special flags are necessary)
|
||||
@@ -461,11 +460,24 @@ AC_SUBST(HAVE_TCL)
|
||||
TARGET_READLINE_LIBS=""
|
||||
TARGET_READLINE_INC=""
|
||||
TARGET_HAVE_READLINE=0
|
||||
TARGET_HAVE_EDITLINE=0
|
||||
AC_ARG_ENABLE([editline],
|
||||
[AC_HELP_STRING([--enable-editline],[enable BSD editline support])],
|
||||
[with_editline=$enableval],
|
||||
[with_editline=auto])
|
||||
AC_ARG_ENABLE([readline],
|
||||
[AC_HELP_STRING([--disable-readline],[disable readline support [default=detect]])],
|
||||
[AC_HELP_STRING([--disable-readline],[disable readline support])],
|
||||
[with_readline=$enableval],
|
||||
[with_readline=auto])
|
||||
|
||||
if test x"$with_editline" != xno; then
|
||||
sLIBS=$LIBS
|
||||
LIBS=""
|
||||
TARGET_HAVE_EDITLINE=1
|
||||
AC_SEARCH_LIBS(readline,edit,[with_readline=no],[TARGET_HAVE_EDITLINE=0])
|
||||
TARGET_READLINE_LIBS=$LIBS
|
||||
LIBS=$sLIBS
|
||||
fi
|
||||
if test x"$with_readline" != xno; then
|
||||
found="yes"
|
||||
|
||||
@@ -520,6 +532,7 @@ fi
|
||||
AC_SUBST(TARGET_READLINE_LIBS)
|
||||
AC_SUBST(TARGET_READLINE_INC)
|
||||
AC_SUBST(TARGET_HAVE_READLINE)
|
||||
AC_SUBST(TARGET_HAVE_EDITLINE)
|
||||
|
||||
##########
|
||||
# Figure out what C libraries are required to compile programs
|
||||
|
||||
+3
-3
@@ -205,13 +205,13 @@ static int getVarint32(const char *p, int *pi){
|
||||
*/
|
||||
/* TODO(shess) Is __isascii() a portable version of (c&0x80)==0? */
|
||||
static int safe_isspace(char c){
|
||||
return (c&0x80)==0 ? isspace(c) : 0;
|
||||
return (c&0x80)==0 ? isspace((unsigned char)c) : 0;
|
||||
}
|
||||
static int safe_tolower(char c){
|
||||
return (c&0x80)==0 ? tolower(c) : c;
|
||||
return (c&0x80)==0 ? tolower((unsigned char)c) : c;
|
||||
}
|
||||
static int safe_isalnum(char c){
|
||||
return (c&0x80)==0 ? isalnum(c) : 0;
|
||||
return (c&0x80)==0 ? isalnum((unsigned char)c) : 0;
|
||||
}
|
||||
|
||||
typedef enum DocListType {
|
||||
|
||||
@@ -138,7 +138,7 @@ static int simpleNext(
|
||||
** case-insensitivity.
|
||||
*/
|
||||
char ch = c->pCurrent[ii];
|
||||
c->zToken[ii] = (unsigned char)ch<0x80 ? tolower(ch) : ch;
|
||||
c->zToken[ii] = (unsigned char)ch<0x80 ? tolower((unsigned char)ch):ch;
|
||||
}
|
||||
c->zToken[n] = '\0';
|
||||
*ppToken = c->zToken;
|
||||
|
||||
+7
-5
@@ -224,7 +224,7 @@ struct Fts5Buffer {
|
||||
int nSpace;
|
||||
};
|
||||
|
||||
int sqlite3Fts5BufferGrow(int*, Fts5Buffer*, int);
|
||||
int sqlite3Fts5BufferSize(int*, Fts5Buffer*, int);
|
||||
void sqlite3Fts5BufferAppendVarint(int*, Fts5Buffer*, i64);
|
||||
void sqlite3Fts5BufferAppendBlob(int*, Fts5Buffer*, int, const u8*);
|
||||
void sqlite3Fts5BufferAppendString(int *, Fts5Buffer*, const char*);
|
||||
@@ -232,17 +232,19 @@ void sqlite3Fts5BufferFree(Fts5Buffer*);
|
||||
void sqlite3Fts5BufferZero(Fts5Buffer*);
|
||||
void sqlite3Fts5BufferSet(int*, Fts5Buffer*, int, const u8*);
|
||||
void sqlite3Fts5BufferAppendPrintf(int *, Fts5Buffer*, char *zFmt, ...);
|
||||
void sqlite3Fts5BufferAppend32(int*, Fts5Buffer*, int);
|
||||
|
||||
char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...);
|
||||
|
||||
#define fts5BufferZero(x) sqlite3Fts5BufferZero(x)
|
||||
#define fts5BufferGrow(a,b,c) sqlite3Fts5BufferGrow(a,b,c)
|
||||
#define fts5BufferAppendVarint(a,b,c) sqlite3Fts5BufferAppendVarint(a,b,c)
|
||||
#define fts5BufferFree(a) sqlite3Fts5BufferFree(a)
|
||||
#define fts5BufferAppendBlob(a,b,c,d) sqlite3Fts5BufferAppendBlob(a,b,c,d)
|
||||
#define fts5BufferSet(a,b,c,d) sqlite3Fts5BufferSet(a,b,c,d)
|
||||
#define fts5BufferAppend32(a,b,c) sqlite3Fts5BufferAppend32(a,b,c)
|
||||
|
||||
#define fts5BufferGrow(pRc,pBuf,nn) ( \
|
||||
(pBuf)->n + (nn) <= (pBuf)->nSpace ? 0 : \
|
||||
sqlite3Fts5BufferSize((pRc),(pBuf),(nn)+(pBuf)->n) \
|
||||
)
|
||||
|
||||
/* Write and decode big-endian 32-bit integer values */
|
||||
void sqlite3Fts5Put32(u8*, int);
|
||||
@@ -475,7 +477,7 @@ int sqlite3Fts5GetTokenizer(
|
||||
char **pzErr
|
||||
);
|
||||
|
||||
Fts5Index *sqlite3Fts5IndexFromCsrid(Fts5Global*, i64, int*);
|
||||
Fts5Index *sqlite3Fts5IndexFromCsrid(Fts5Global*, i64, Fts5Config **);
|
||||
|
||||
/*
|
||||
** End of interface to code in fts5.c.
|
||||
|
||||
+1
-1
@@ -137,7 +137,7 @@ static void fts5HighlightAppend(
|
||||
const char *z, int n
|
||||
){
|
||||
if( *pRc==SQLITE_OK ){
|
||||
if( n<0 ) n = strlen(z);
|
||||
if( n<0 ) n = (int)strlen(z);
|
||||
p->zOut = sqlite3_mprintf("%z%.*s", p->zOut, n, z);
|
||||
if( p->zOut==0 ) *pRc = SQLITE_NOMEM;
|
||||
}
|
||||
|
||||
+19
-31
@@ -15,36 +15,30 @@
|
||||
|
||||
#include "fts5Int.h"
|
||||
|
||||
int sqlite3Fts5BufferGrow(int *pRc, Fts5Buffer *pBuf, int nByte){
|
||||
|
||||
if( (pBuf->n + nByte) > pBuf->nSpace ){
|
||||
u8 *pNew;
|
||||
int nNew = pBuf->nSpace ? pBuf->nSpace*2 : 64;
|
||||
|
||||
/* A no-op if an error has already occurred */
|
||||
if( *pRc ) return 1;
|
||||
|
||||
while( nNew<(pBuf->n + nByte) ){
|
||||
nNew = nNew * 2;
|
||||
}
|
||||
pNew = sqlite3_realloc(pBuf->p, nNew);
|
||||
if( pNew==0 ){
|
||||
*pRc = SQLITE_NOMEM;
|
||||
return 1;
|
||||
}else{
|
||||
pBuf->nSpace = nNew;
|
||||
pBuf->p = pNew;
|
||||
}
|
||||
int sqlite3Fts5BufferSize(int *pRc, Fts5Buffer *pBuf, int nByte){
|
||||
int nNew = pBuf->nSpace ? pBuf->nSpace*2 : 64;
|
||||
u8 *pNew;
|
||||
while( nNew<nByte ){
|
||||
nNew = nNew * 2;
|
||||
}
|
||||
pNew = sqlite3_realloc(pBuf->p, nNew);
|
||||
if( pNew==0 ){
|
||||
*pRc = SQLITE_NOMEM;
|
||||
return 1;
|
||||
}else{
|
||||
pBuf->nSpace = nNew;
|
||||
pBuf->p = pNew;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Encode value iVal as an SQLite varint and append it to the buffer object
|
||||
** pBuf. If an OOM error occurs, set the error code in p.
|
||||
*/
|
||||
void sqlite3Fts5BufferAppendVarint(int *pRc, Fts5Buffer *pBuf, i64 iVal){
|
||||
if( sqlite3Fts5BufferGrow(pRc, pBuf, 9) ) return;
|
||||
if( fts5BufferGrow(pRc, pBuf, 9) ) return;
|
||||
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iVal);
|
||||
}
|
||||
|
||||
@@ -59,12 +53,6 @@ int sqlite3Fts5Get32(const u8 *aBuf){
|
||||
return (aBuf[0] << 24) + (aBuf[1] << 16) + (aBuf[2] << 8) + aBuf[3];
|
||||
}
|
||||
|
||||
void sqlite3Fts5BufferAppend32(int *pRc, Fts5Buffer *pBuf, int iVal){
|
||||
if( sqlite3Fts5BufferGrow(pRc, pBuf, 4) ) return;
|
||||
sqlite3Fts5Put32(&pBuf->p[pBuf->n], iVal);
|
||||
pBuf->n += 4;
|
||||
}
|
||||
|
||||
/*
|
||||
** Append buffer nData/pData to buffer pBuf. If an OOM error occurs, set
|
||||
** the error code in p. If an error has already occurred when this function
|
||||
@@ -77,7 +65,7 @@ void sqlite3Fts5BufferAppendBlob(
|
||||
const u8 *pData
|
||||
){
|
||||
assert( *pRc || nData>=0 );
|
||||
if( sqlite3Fts5BufferGrow(pRc, pBuf, nData) ) return;
|
||||
if( fts5BufferGrow(pRc, pBuf, nData) ) return;
|
||||
memcpy(&pBuf->p[pBuf->n], pData, nData);
|
||||
pBuf->n += nData;
|
||||
}
|
||||
@@ -92,7 +80,7 @@ void sqlite3Fts5BufferAppendString(
|
||||
Fts5Buffer *pBuf,
|
||||
const char *zStr
|
||||
){
|
||||
int nStr = strlen(zStr);
|
||||
int nStr = (int)strlen(zStr);
|
||||
sqlite3Fts5BufferAppendBlob(pRc, pBuf, nStr+1, (const u8*)zStr);
|
||||
pBuf->n--;
|
||||
}
|
||||
@@ -227,7 +215,7 @@ int sqlite3Fts5PoslistWriterAppend(
|
||||
){
|
||||
static const i64 colmask = ((i64)(0x7FFFFFFF)) << 32;
|
||||
int rc = SQLITE_OK;
|
||||
if( 0==sqlite3Fts5BufferGrow(&rc, pBuf, 5+5+5) ){
|
||||
if( 0==fts5BufferGrow(&rc, pBuf, 5+5+5) ){
|
||||
if( (iPos & colmask) != (pWriter->iPrev & colmask) ){
|
||||
pBuf->p[pBuf->n++] = 1;
|
||||
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos>>32));
|
||||
@@ -264,7 +252,7 @@ char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn){
|
||||
char *zRet = 0;
|
||||
if( *pRc==SQLITE_OK ){
|
||||
if( nIn<0 ){
|
||||
nIn = strlen(pIn);
|
||||
nIn = (int)strlen(pIn);
|
||||
}
|
||||
zRet = (char*)sqlite3_malloc(nIn+1);
|
||||
if( zRet ){
|
||||
|
||||
@@ -211,7 +211,7 @@ static int fts5ConfigParseSpecial(
|
||||
char **pzErr /* OUT: Error message */
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
int nCmd = strlen(zCmd);
|
||||
int nCmd = (int)strlen(zCmd);
|
||||
if( sqlite3_strnicmp("prefix", zCmd, nCmd)==0 ){
|
||||
const int nByte = sizeof(int) * FTS5_MAX_PREFIX_INDEXES;
|
||||
const char *p;
|
||||
@@ -248,7 +248,7 @@ static int fts5ConfigParseSpecial(
|
||||
|
||||
if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){
|
||||
const char *p = (const char*)zArg;
|
||||
int nArg = strlen(zArg) + 1;
|
||||
int nArg = (int)strlen(zArg) + 1;
|
||||
char **azArg = sqlite3Fts5MallocZero(&rc, sizeof(char*) * nArg);
|
||||
char *pDel = sqlite3Fts5MallocZero(&rc, nArg * 2);
|
||||
char *pSpace = pDel;
|
||||
@@ -364,7 +364,7 @@ static const char *fts5ConfigGobbleWord(
|
||||
){
|
||||
const char *zRet = 0;
|
||||
|
||||
int nIn = strlen(zIn);
|
||||
int nIn = (int)strlen(zIn);
|
||||
char *zOut = sqlite3_malloc(nIn+1);
|
||||
|
||||
assert( *pRc==SQLITE_OK );
|
||||
|
||||
@@ -907,7 +907,7 @@ static int fts5ExprNearInitAll(
|
||||
p->pIter = 0;
|
||||
}
|
||||
rc = sqlite3Fts5IndexQuery(
|
||||
pExpr->pIndex, p->zTerm, strlen(p->zTerm),
|
||||
pExpr->pIndex, p->zTerm, (int)strlen(p->zTerm),
|
||||
(pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) |
|
||||
(pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0),
|
||||
pNear->pColset,
|
||||
@@ -1518,7 +1518,7 @@ Fts5ExprPhrase *sqlite3Fts5ParseTerm(
|
||||
int flags = FTS5_TOKENIZE_QUERY | (bPrefix ? FTS5_TOKENIZE_QUERY : 0);
|
||||
int n;
|
||||
sqlite3Fts5Dequote(z);
|
||||
n = strlen(z);
|
||||
n = (int)strlen(z);
|
||||
rc = sqlite3Fts5Tokenize(pConfig, flags, z, n, &sCtx, fts5ParseTokenize);
|
||||
}
|
||||
sqlite3_free(z);
|
||||
@@ -1591,7 +1591,8 @@ int sqlite3Fts5ExprClonePhrase(
|
||||
Fts5ExprTerm *p;
|
||||
for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){
|
||||
const char *zTerm = p->zTerm;
|
||||
rc = fts5ParseTokenize((void*)&sCtx, tflags, zTerm, strlen(zTerm), 0, 0);
|
||||
rc = fts5ParseTokenize((void*)&sCtx, tflags, zTerm, (int)strlen(zTerm),
|
||||
0, 0);
|
||||
tflags = FTS5_TOKEN_COLOCATED;
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
@@ -1833,7 +1834,7 @@ static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){
|
||||
|
||||
/* Determine the maximum amount of space required. */
|
||||
for(p=pTerm; p; p=p->pSynonym){
|
||||
nByte += strlen(pTerm->zTerm) * 2 + 3 + 2;
|
||||
nByte += (int)strlen(pTerm->zTerm) * 2 + 3 + 2;
|
||||
}
|
||||
zQuoted = sqlite3_malloc(nByte);
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@ static int fts5HashResize(Fts5Hash *pHash){
|
||||
int iHash;
|
||||
Fts5HashEntry *p = apOld[i];
|
||||
apOld[i] = p->pHashNext;
|
||||
iHash = fts5HashKey(nNew, (u8*)p->zKey, strlen(p->zKey));
|
||||
iHash = fts5HashKey(nNew, (u8*)p->zKey, (int)strlen(p->zKey));
|
||||
p->pHashNext = apNew[iHash];
|
||||
apNew[iHash] = p;
|
||||
}
|
||||
@@ -458,7 +458,7 @@ void sqlite3Fts5HashScanEntry(
|
||||
){
|
||||
Fts5HashEntry *p;
|
||||
if( (p = pHash->pScan) ){
|
||||
int nTerm = strlen(p->zKey);
|
||||
int nTerm = (int)strlen(p->zKey);
|
||||
fts5HashAddPoslistSize(p);
|
||||
*pzTerm = p->zKey;
|
||||
*ppDoclist = (const u8*)&p->zKey[nTerm+1];
|
||||
|
||||
+146
-85
@@ -374,26 +374,6 @@ struct Fts5SegWriter {
|
||||
int iBtPage; /* Page number corresponding to btterm */
|
||||
};
|
||||
|
||||
/*
|
||||
** Object for iterating through the merged results of one or more segments,
|
||||
** visiting each term/rowid pair in the merged data.
|
||||
**
|
||||
** nSeg is always a power of two greater than or equal to the number of
|
||||
** segments that this object is merging data from. Both the aSeg[] and
|
||||
** aFirst[] arrays are sized at nSeg entries. The aSeg[] array is padded
|
||||
** with zeroed objects - these are handled as if they were iterators opened
|
||||
** on empty segments.
|
||||
**
|
||||
** The results of comparing segments aSeg[N] and aSeg[N+1], where N is an
|
||||
** even number, is stored in aFirst[(nSeg+N)/2]. The "result" of the
|
||||
** comparison in this context is the index of the iterator that currently
|
||||
** points to the smaller term/rowid combination. Iterators at EOF are
|
||||
** considered to be greater than all other iterators.
|
||||
**
|
||||
** aFirst[1] contains the index in aSeg[] of the iterator that points to
|
||||
** the smallest key overall. aFirst[0] is unused.
|
||||
*/
|
||||
|
||||
typedef struct Fts5CResult Fts5CResult;
|
||||
struct Fts5CResult {
|
||||
u16 iFirst; /* aSeg[] index of firstest iterator */
|
||||
@@ -500,6 +480,24 @@ struct Fts5SegIter {
|
||||
#define fts5LeafFirstRowidOff(x) (fts5GetU16((x)->p))
|
||||
|
||||
/*
|
||||
** Object for iterating through the merged results of one or more segments,
|
||||
** visiting each term/rowid pair in the merged data.
|
||||
**
|
||||
** nSeg is always a power of two greater than or equal to the number of
|
||||
** segments that this object is merging data from. Both the aSeg[] and
|
||||
** aFirst[] arrays are sized at nSeg entries. The aSeg[] array is padded
|
||||
** with zeroed objects - these are handled as if they were iterators opened
|
||||
** on empty segments.
|
||||
**
|
||||
** The results of comparing segments aSeg[N] and aSeg[N+1], where N is an
|
||||
** even number, is stored in aFirst[(nSeg+N)/2]. The "result" of the
|
||||
** comparison in this context is the index of the iterator that currently
|
||||
** points to the smaller term/rowid combination. Iterators at EOF are
|
||||
** considered to be greater than all other iterators.
|
||||
**
|
||||
** aFirst[1] contains the index in aSeg[] of the iterator that points to
|
||||
** the smallest key overall. aFirst[0] is unused.
|
||||
**
|
||||
** poslist:
|
||||
** Used by sqlite3Fts5IterPoslist() when the poslist needs to be buffered.
|
||||
** There is no way to tell if this is populated or not.
|
||||
@@ -1008,6 +1006,18 @@ static int fts5StructureCountSegments(Fts5Structure *pStruct){
|
||||
}
|
||||
#endif
|
||||
|
||||
#define fts5BufferSafeAppendBlob(pBuf, pBlob, nBlob) { \
|
||||
assert( (pBuf)->nSpace>=((pBuf)->n+nBlob) ); \
|
||||
memcpy(&(pBuf)->p[(pBuf)->n], pBlob, nBlob); \
|
||||
(pBuf)->n += nBlob; \
|
||||
}
|
||||
|
||||
#define fts5BufferSafeAppendVarint(pBuf, iVal) { \
|
||||
(pBuf)->n += sqlite3Fts5PutVarint(&(pBuf)->p[(pBuf)->n], (iVal)); \
|
||||
assert( (pBuf)->nSpace>=(pBuf)->n ); \
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Serialize and store the "structure" record.
|
||||
**
|
||||
@@ -1026,11 +1036,14 @@ static void fts5StructureWrite(Fts5Index *p, Fts5Structure *pStruct){
|
||||
/* Append the current configuration cookie */
|
||||
iCookie = p->pConfig->iCookie;
|
||||
if( iCookie<0 ) iCookie = 0;
|
||||
fts5BufferAppend32(&p->rc, &buf, iCookie);
|
||||
|
||||
fts5BufferAppendVarint(&p->rc, &buf, pStruct->nLevel);
|
||||
fts5BufferAppendVarint(&p->rc, &buf, pStruct->nSegment);
|
||||
fts5BufferAppendVarint(&p->rc, &buf, (i64)pStruct->nWriteCounter);
|
||||
if( 0==sqlite3Fts5BufferSize(&p->rc, &buf, 4+9+9+9) ){
|
||||
sqlite3Fts5Put32(buf.p, iCookie);
|
||||
buf.n = 4;
|
||||
fts5BufferSafeAppendVarint(&buf, pStruct->nLevel);
|
||||
fts5BufferSafeAppendVarint(&buf, pStruct->nSegment);
|
||||
fts5BufferSafeAppendVarint(&buf, (i64)pStruct->nWriteCounter);
|
||||
}
|
||||
|
||||
for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
|
||||
int iSeg; /* Used to iterate through segments */
|
||||
@@ -1486,6 +1499,7 @@ static void fts5SegIterLoadNPos(Fts5Index *p, Fts5SegIter *pIter){
|
||||
pIter->bDel = (nSz & 0x0001);
|
||||
pIter->nPos = nSz>>1;
|
||||
pIter->iLeafOffset = iOff;
|
||||
assert_nc( pIter->nPos>=0 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1659,12 +1673,13 @@ static void fts5SegIterReverseNewPage(Fts5Index *p, Fts5SegIter *pIter){
|
||||
if( pNew ){
|
||||
/* iTermLeafOffset may be equal to szLeaf if the term is the last
|
||||
** thing on the page - i.e. the first rowid is on the following page.
|
||||
** In this case leaf pIter->pLeaf==0, this iterator is at EOF. */
|
||||
if( pIter->iLeafPgno==pIter->iTermLeafPgno
|
||||
&& pIter->iTermLeafOffset<pNew->szLeaf
|
||||
){
|
||||
pIter->pLeaf = pNew;
|
||||
pIter->iLeafOffset = pIter->iTermLeafOffset;
|
||||
** In this case leave pIter->pLeaf==0, this iterator is at EOF. */
|
||||
if( pIter->iLeafPgno==pIter->iTermLeafPgno ){
|
||||
assert( pIter->pLeaf==0 );
|
||||
if( pIter->iTermLeafOffset<pNew->szLeaf ){
|
||||
pIter->pLeaf = pNew;
|
||||
pIter->iLeafOffset = pIter->iTermLeafOffset;
|
||||
}
|
||||
}else{
|
||||
int iRowidOff;
|
||||
iRowidOff = fts5LeafFirstRowidOff(pNew);
|
||||
@@ -1766,6 +1781,7 @@ static void fts5SegIterNext(
|
||||
const u8 *pList = 0;
|
||||
const char *zTerm = 0;
|
||||
int nList = 0;
|
||||
assert( (pIter->flags & FTS5_SEGITER_ONETERM) || pbNewTerm );
|
||||
if( 0==(pIter->flags & FTS5_SEGITER_ONETERM) ){
|
||||
sqlite3Fts5HashScanNext(p->pHash);
|
||||
sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList);
|
||||
@@ -1778,9 +1794,10 @@ static void fts5SegIterNext(
|
||||
pIter->pLeaf->nn = nList;
|
||||
pIter->pLeaf->szLeaf = nList;
|
||||
pIter->iEndofDoclist = nList+1;
|
||||
sqlite3Fts5BufferSet(&p->rc, &pIter->term, strlen(zTerm), (u8*)zTerm);
|
||||
sqlite3Fts5BufferSet(&p->rc, &pIter->term, (int)strlen(zTerm),
|
||||
(u8*)zTerm);
|
||||
pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid);
|
||||
if( pbNewTerm ) *pbNewTerm = 1;
|
||||
*pbNewTerm = 1;
|
||||
}
|
||||
}else{
|
||||
iOff = 0;
|
||||
@@ -1828,7 +1845,15 @@ static void fts5SegIterNext(
|
||||
if( pbNewTerm ) *pbNewTerm = 1;
|
||||
}
|
||||
}else{
|
||||
fts5SegIterLoadNPos(p, pIter);
|
||||
/* The following could be done by calling fts5SegIterLoadNPos(). But
|
||||
** this block is particularly performance critical, so equivalent
|
||||
** code is inlined. */
|
||||
int nSz;
|
||||
assert( p->rc==SQLITE_OK );
|
||||
fts5FastGetVarint32(pIter->pLeaf->p, pIter->iLeafOffset, nSz);
|
||||
pIter->bDel = (nSz & 0x0001);
|
||||
pIter->nPos = nSz>>1;
|
||||
assert_nc( pIter->nPos>=0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2037,11 +2062,14 @@ static void fts5LeafSeek(
|
||||
if( pIter->pLeaf==0 ) return;
|
||||
a = pIter->pLeaf->p;
|
||||
if( fts5LeafIsTermless(pIter->pLeaf)==0 ){
|
||||
fts5GetVarint32(&pIter->pLeaf->p[pIter->pLeaf->szLeaf], iOff);
|
||||
iPgidx = pIter->pLeaf->szLeaf;
|
||||
iPgidx += fts5GetVarint32(&pIter->pLeaf->p[iPgidx], iOff);
|
||||
if( iOff<4 || iOff>=pIter->pLeaf->szLeaf ){
|
||||
p->rc = FTS5_CORRUPT;
|
||||
}else{
|
||||
nKeep = 0;
|
||||
iTermOff = iOff;
|
||||
n = pIter->pLeaf->nn;
|
||||
iOff += fts5GetVarint32(&a[iOff], nNew);
|
||||
break;
|
||||
}
|
||||
@@ -2185,7 +2213,7 @@ static void fts5SegIterHashInit(
|
||||
if( pTerm==0 || (flags & FTS5INDEX_QUERY_SCAN) ){
|
||||
p->rc = sqlite3Fts5HashScanInit(p->pHash, (const char*)pTerm, nTerm);
|
||||
sqlite3Fts5HashScanEntry(p->pHash, (const char**)&z, &pList, &nList);
|
||||
n = (z ? strlen((const char*)z) : 0);
|
||||
n = (z ? (int)strlen((const char*)z) : 0);
|
||||
}else{
|
||||
pIter->flags |= FTS5_SEGITER_ONETERM;
|
||||
sqlite3Fts5HashQuery(p->pHash, (const char*)pTerm, nTerm, &pList, &nList);
|
||||
@@ -2591,6 +2619,35 @@ static void fts5MultiIterNext(
|
||||
}
|
||||
}
|
||||
|
||||
static void fts5MultiIterNext2(
|
||||
Fts5Index *p,
|
||||
Fts5IndexIter *pIter,
|
||||
int *pbNewTerm /* OUT: True if *might* be new term */
|
||||
){
|
||||
assert( pIter->bSkipEmpty );
|
||||
if( p->rc==SQLITE_OK ){
|
||||
do {
|
||||
int iFirst = pIter->aFirst[1].iFirst;
|
||||
Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
|
||||
int bNewTerm = 0;
|
||||
|
||||
fts5SegIterNext(p, pSeg, &bNewTerm);
|
||||
if( pSeg->pLeaf==0 || bNewTerm
|
||||
|| fts5MultiIterAdvanceRowid(p, pIter, iFirst)
|
||||
){
|
||||
fts5MultiIterAdvanced(p, pIter, iFirst, 1);
|
||||
fts5MultiIterSetEof(pIter);
|
||||
*pbNewTerm = 1;
|
||||
}else{
|
||||
*pbNewTerm = 0;
|
||||
}
|
||||
fts5AssertMultiIterSetup(p, pIter);
|
||||
|
||||
}while( fts5MultiIterIsEmpty(p, pIter) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static Fts5IndexIter *fts5MultiIterAlloc(
|
||||
Fts5Index *p, /* FTS5 backend to iterate within */
|
||||
int nSeg
|
||||
@@ -3344,9 +3401,12 @@ static void fts5WriteInit(
|
||||
pWriter->bFirstTermInPage = 1;
|
||||
pWriter->iBtPage = 1;
|
||||
|
||||
assert( pWriter->writer.buf.n==0 );
|
||||
assert( pWriter->writer.pgidx.n==0 );
|
||||
|
||||
/* Grow the two buffers to pgsz + padding bytes in size. */
|
||||
fts5BufferGrow(&p->rc, &pWriter->writer.pgidx, nBuffer);
|
||||
fts5BufferGrow(&p->rc, &pWriter->writer.buf, nBuffer);
|
||||
sqlite3Fts5BufferSize(&p->rc, &pWriter->writer.pgidx, nBuffer);
|
||||
sqlite3Fts5BufferSize(&p->rc, &pWriter->writer.buf, nBuffer);
|
||||
|
||||
if( p->pIdxWriter==0 ){
|
||||
Fts5Config *pConfig = p->pConfig;
|
||||
@@ -3699,17 +3759,6 @@ static int fts5PoslistPrefix(const u8 *aBuf, int nMax){
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define fts5BufferSafeAppendBlob(pBuf, pBlob, nBlob) { \
|
||||
assert( (pBuf)->nSpace>=((pBuf)->n+nBlob) ); \
|
||||
memcpy(&(pBuf)->p[(pBuf)->n], pBlob, nBlob); \
|
||||
(pBuf)->n += nBlob; \
|
||||
}
|
||||
|
||||
#define fts5BufferSafeAppendVarint(pBuf, iVal) { \
|
||||
(pBuf)->n += sqlite3Fts5PutVarint(&(pBuf)->p[(pBuf)->n], (iVal)); \
|
||||
assert( (pBuf)->nSpace>=(pBuf)->n ); \
|
||||
}
|
||||
|
||||
/*
|
||||
** Flush the contents of in-memory hash table iHash to a new level-0
|
||||
** segment on disk. Also update the corresponding structure record.
|
||||
@@ -3758,7 +3807,7 @@ static void fts5FlushOneHash(Fts5Index *p){
|
||||
|
||||
/* Write the term for this entry to disk. */
|
||||
sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist);
|
||||
fts5WriteAppendTerm(p, &writer, strlen(zTerm), (const u8*)zTerm);
|
||||
fts5WriteAppendTerm(p, &writer, (int)strlen(zTerm), (const u8*)zTerm);
|
||||
|
||||
assert( writer.bFirstRowidInPage==0 );
|
||||
if( pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){
|
||||
@@ -4034,7 +4083,7 @@ static void fts5SegiterPoslist(
|
||||
PoslistCallbackCtx sCtx;
|
||||
sCtx.pBuf = pBuf;
|
||||
sCtx.pColset = pColset;
|
||||
sCtx.eState = pColset ? fts5IndexColsetTest(pColset, 0) : 1;
|
||||
sCtx.eState = fts5IndexColsetTest(pColset, 0);
|
||||
assert( sCtx.eState==0 || sCtx.eState==1 );
|
||||
fts5ChunkIterate(p, pSeg, (void*)&sCtx, fts5PoslistFilterCallback);
|
||||
}
|
||||
@@ -4058,7 +4107,7 @@ static int fts5IndexExtractCol(
|
||||
const u8 *pEnd = &p[n]; /* One byte past end of position list */
|
||||
u8 prev = 0;
|
||||
|
||||
while( iCol!=iCurrent ){
|
||||
while( iCol>iCurrent ){
|
||||
/* Advance pointer p until it points to pEnd or an 0x01 byte that is
|
||||
** not part of a varint */
|
||||
while( (prev & 0x80) || *p!=0x01 ){
|
||||
@@ -4068,6 +4117,7 @@ static int fts5IndexExtractCol(
|
||||
*pa = p++;
|
||||
p += fts5GetVarint32(p, iCurrent);
|
||||
}
|
||||
if( iCol!=iCurrent ) return 0;
|
||||
|
||||
/* Advance pointer p until it points to pEnd or an 0x01 byte that is
|
||||
** not part of a varint */
|
||||
@@ -4105,18 +4155,6 @@ static int fts5AppendPoslist(
|
||||
assert( fts5MultiIterEof(p, pMulti)==0 );
|
||||
assert( pSeg->nPos>0 );
|
||||
if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos+9+9) ){
|
||||
int iSv1;
|
||||
int iSv2;
|
||||
int iData;
|
||||
|
||||
/* Append iDelta */
|
||||
iSv1 = pBuf->n;
|
||||
fts5BufferSafeAppendVarint(pBuf, iDelta);
|
||||
|
||||
/* WRITEPOSLISTSIZE */
|
||||
iSv2 = pBuf->n;
|
||||
fts5BufferSafeAppendVarint(pBuf, pSeg->nPos*2);
|
||||
iData = pBuf->n;
|
||||
|
||||
if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf
|
||||
&& (pColset==0 || pColset->nCol==1)
|
||||
@@ -4125,27 +4163,45 @@ static int fts5AppendPoslist(
|
||||
int nPos;
|
||||
if( pColset ){
|
||||
nPos = fts5IndexExtractCol(&pPos, pSeg->nPos, pColset->aiCol[0]);
|
||||
if( nPos==0 ) return 1;
|
||||
}else{
|
||||
nPos = pSeg->nPos;
|
||||
}
|
||||
assert( nPos>0 );
|
||||
fts5BufferSafeAppendVarint(pBuf, iDelta);
|
||||
fts5BufferSafeAppendVarint(pBuf, nPos*2);
|
||||
fts5BufferSafeAppendBlob(pBuf, pPos, nPos);
|
||||
}else{
|
||||
fts5SegiterPoslist(p, pSeg, pColset, pBuf);
|
||||
}
|
||||
int iSv1;
|
||||
int iSv2;
|
||||
int iData;
|
||||
|
||||
if( pColset ){
|
||||
int nActual = pBuf->n - iData;
|
||||
if( nActual!=pSeg->nPos ){
|
||||
if( nActual==0 ){
|
||||
pBuf->n = iSv1;
|
||||
return 1;
|
||||
}else{
|
||||
int nReq = sqlite3Fts5GetVarintLen((u32)(nActual*2));
|
||||
while( iSv2<(iData-nReq) ){ pBuf->p[iSv2++] = 0x80; }
|
||||
sqlite3Fts5PutVarint(&pBuf->p[iSv2], nActual*2);
|
||||
/* Append iDelta */
|
||||
iSv1 = pBuf->n;
|
||||
fts5BufferSafeAppendVarint(pBuf, iDelta);
|
||||
|
||||
/* WRITEPOSLISTSIZE */
|
||||
iSv2 = pBuf->n;
|
||||
fts5BufferSafeAppendVarint(pBuf, pSeg->nPos*2);
|
||||
iData = pBuf->n;
|
||||
|
||||
fts5SegiterPoslist(p, pSeg, pColset, pBuf);
|
||||
|
||||
if( pColset ){
|
||||
int nActual = pBuf->n - iData;
|
||||
if( nActual!=pSeg->nPos ){
|
||||
if( nActual==0 ){
|
||||
pBuf->n = iSv1;
|
||||
return 1;
|
||||
}else{
|
||||
int nReq = sqlite3Fts5GetVarintLen((u32)(nActual*2));
|
||||
while( iSv2<(iData-nReq) ){ pBuf->p[iSv2++] = 0x80; }
|
||||
sqlite3Fts5PutVarint(&pBuf->p[iSv2], nActual*2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4234,7 +4290,7 @@ static void fts5MergePrefixLists(
|
||||
memset(&out, 0, sizeof(out));
|
||||
memset(&tmp, 0, sizeof(tmp));
|
||||
|
||||
sqlite3Fts5BufferGrow(&p->rc, &out, p1->n + p2->n);
|
||||
sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n);
|
||||
fts5DoclistIterInit(p1, &i1);
|
||||
fts5DoclistIterInit(p2, &i2);
|
||||
while( p->rc==SQLITE_OK && (i1.aPoslist!=0 || i2.aPoslist!=0) ){
|
||||
@@ -4325,17 +4381,20 @@ static void fts5SetupPrefixIter(
|
||||
Fts5IndexIter *p1 = 0; /* Iterator used to gather data from index */
|
||||
Fts5Data *pData;
|
||||
Fts5Buffer doclist;
|
||||
int bNewTerm = 1;
|
||||
|
||||
memset(&doclist, 0, sizeof(doclist));
|
||||
for(fts5MultiIterNew(p, pStruct, 1, flags, pToken, nToken, -1, 0, &p1);
|
||||
fts5MultiIterEof(p, p1)==0;
|
||||
fts5MultiIterNext(p, p1, 0, 0)
|
||||
fts5MultiIterNext2(p, p1, &bNewTerm)
|
||||
){
|
||||
i64 iRowid = fts5MultiIterRowid(p1);
|
||||
int nTerm;
|
||||
const u8 *pTerm = fts5MultiIterTerm(p1, &nTerm);
|
||||
assert_nc( memcmp(pToken, pTerm, MIN(nToken, nTerm))<=0 );
|
||||
if( nTerm<nToken || memcmp(pToken, pTerm, nToken) ) break;
|
||||
if( bNewTerm ){
|
||||
if( nTerm<nToken || memcmp(pToken, pTerm, nToken) ) break;
|
||||
}
|
||||
|
||||
if( doclist.n>0 && iRowid<=iLastRowid ){
|
||||
for(i=0; p->rc==SQLITE_OK && doclist.n; i++){
|
||||
@@ -4595,11 +4654,9 @@ int sqlite3Fts5IndexQuery(
|
||||
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)==FTS5INDEX_QUERY_SCAN
|
||||
);
|
||||
assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN );
|
||||
|
||||
if( sqlite3Fts5BufferGrow(&p->rc, &buf, nToken+1)==0 ){
|
||||
if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){
|
||||
memcpy(&buf.p[1], pToken, nToken);
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
@@ -5196,7 +5253,6 @@ static void fts5IndexIntegrityCheckSegment(
|
||||
fts5DataRelease(pLeaf);
|
||||
if( p->rc ) break;
|
||||
|
||||
|
||||
/* Now check that the iter.nEmpty leaves following the current leaf
|
||||
** (a) exist and (b) contain no terms. */
|
||||
fts5IndexIntegrityCheckEmpty(
|
||||
@@ -5285,9 +5341,11 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){
|
||||
Fts5IndexIter *pIter; /* Used to iterate through entire index */
|
||||
Fts5Structure *pStruct; /* Index structure */
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
/* Used by extra internal tests only run if NDEBUG is not defined */
|
||||
u64 cksum3 = 0; /* Checksum based on contents of indexes */
|
||||
Fts5Buffer term = {0,0,0}; /* Buffer used to hold most recent term */
|
||||
#endif
|
||||
|
||||
/* Load the FTS index structure */
|
||||
pStruct = fts5StructureRead(p);
|
||||
@@ -5343,7 +5401,9 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){
|
||||
if( p->rc==SQLITE_OK && cksum!=cksum2 ) p->rc = FTS5_CORRUPT;
|
||||
|
||||
fts5StructureRelease(pStruct);
|
||||
#ifdef SQLITE_DEBUG
|
||||
fts5BufferFree(&term);
|
||||
#endif
|
||||
fts5BufferFree(&poslist);
|
||||
return fts5IndexReturn(p);
|
||||
}
|
||||
@@ -5528,8 +5588,9 @@ static int fts5DecodeDoclist(int *pRc, Fts5Buffer *pBuf, const u8 *a, int n){
|
||||
}
|
||||
while( iOff<n ){
|
||||
int nPos;
|
||||
int bDummy;
|
||||
iOff += fts5GetPoslistSize(&a[iOff], &nPos, &bDummy);
|
||||
int bDel;
|
||||
iOff += fts5GetPoslistSize(&a[iOff], &nPos, &bDel);
|
||||
sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " nPos=%d%s", nPos, bDel?"*":"");
|
||||
iOff += fts5DecodePoslist(pRc, pBuf, &a[iOff], MIN(n-iOff, nPos));
|
||||
if( iOff<n ){
|
||||
i64 iDelta;
|
||||
|
||||
+14
-8
@@ -447,7 +447,10 @@ static int fts5CreateMethod(
|
||||
*/
|
||||
static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){
|
||||
#if SQLITE_VERSION_NUMBER>=3008012
|
||||
if( sqlite3_libversion_number()>=3008012 ){
|
||||
#ifndef SQLITE_CORE
|
||||
if( sqlite3_libversion_number()>=3008012 )
|
||||
#endif
|
||||
{
|
||||
pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE;
|
||||
}
|
||||
#endif
|
||||
@@ -1448,7 +1451,10 @@ static int fts5UpdateMethod(
|
||||
**
|
||||
** Cases 3 and 4 may violate the rowid constraint.
|
||||
*/
|
||||
int eConflict = sqlite3_vtab_on_conflict(pConfig->db);
|
||||
int eConflict = SQLITE_ABORT;
|
||||
if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
|
||||
eConflict = sqlite3_vtab_on_conflict(pConfig->db);
|
||||
}
|
||||
|
||||
assert( eType0==SQLITE_INTEGER || eType0==SQLITE_NULL );
|
||||
assert( nArg!=1 || eType0==SQLITE_INTEGER );
|
||||
@@ -2018,20 +2024,20 @@ static void fts5ApiCallback(
|
||||
** Given cursor id iId, return a pointer to the corresponding Fts5Index
|
||||
** object. Or NULL If the cursor id does not exist.
|
||||
**
|
||||
** If successful, set *pnCol to the number of indexed columns in the
|
||||
** table before returning.
|
||||
** If successful, set *ppConfig to point to the associated config object
|
||||
** before returning.
|
||||
*/
|
||||
Fts5Index *sqlite3Fts5IndexFromCsrid(
|
||||
Fts5Global *pGlobal,
|
||||
i64 iCsrId,
|
||||
int *pnCol
|
||||
Fts5Global *pGlobal, /* FTS5 global context for db handle */
|
||||
i64 iCsrId, /* Id of cursor to find */
|
||||
Fts5Config **ppConfig /* OUT: Configuration object */
|
||||
){
|
||||
Fts5Cursor *pCsr;
|
||||
Fts5Table *pTab;
|
||||
|
||||
pCsr = fts5CursorFromCsrid(pGlobal, iCsrId);
|
||||
pTab = (Fts5Table*)pCsr->base.pVtab;
|
||||
*pnCol = pTab->pConfig->nCol;
|
||||
*ppConfig = pTab->pConfig;
|
||||
|
||||
return pTab->pIndex;
|
||||
}
|
||||
|
||||
+14
-22
@@ -297,10 +297,10 @@ int sqlite3Fts5StorageOpen(
|
||||
int i;
|
||||
int iOff;
|
||||
sqlite3_snprintf(nDefn, zDefn, "id INTEGER PRIMARY KEY");
|
||||
iOff = strlen(zDefn);
|
||||
iOff = (int)strlen(zDefn);
|
||||
for(i=0; i<pConfig->nCol; i++){
|
||||
sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i);
|
||||
iOff += strlen(&zDefn[iOff]);
|
||||
iOff += (int)strlen(&zDefn[iOff]);
|
||||
}
|
||||
rc = sqlite3Fts5CreateTable(pConfig, "content", zDefn, 0, pzErr);
|
||||
}
|
||||
@@ -513,13 +513,15 @@ int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel){
|
||||
}
|
||||
|
||||
/* Delete the %_content record */
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_CONTENT, &pDel, 0);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_bind_int64(pDel, 1, iDel);
|
||||
sqlite3_step(pDel);
|
||||
rc = sqlite3_reset(pDel);
|
||||
if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_CONTENT, &pDel, 0);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_bind_int64(pDel, 1, iDel);
|
||||
sqlite3_step(pDel);
|
||||
rc = sqlite3_reset(pDel);
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the averages record */
|
||||
@@ -725,17 +727,7 @@ int sqlite3Fts5StorageContentInsert(
|
||||
}else{
|
||||
sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */
|
||||
int i; /* Counter variable */
|
||||
#if 0
|
||||
if( eConflict==SQLITE_REPLACE ){
|
||||
eStmt = FTS5_STMT_REPLACE_CONTENT;
|
||||
rc = fts5StorageDeleteFromIndex(p, sqlite3_value_int64(apVal[1]));
|
||||
}else{
|
||||
eStmt = FTS5_STMT_INSERT_CONTENT;
|
||||
}
|
||||
#endif
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0);
|
||||
}
|
||||
rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0);
|
||||
for(i=1; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){
|
||||
rc = sqlite3_bind_value(pInsert, i, apVal[i]);
|
||||
}
|
||||
@@ -924,12 +916,12 @@ int sqlite3Fts5StorageIntegrity(Fts5Storage *p){
|
||||
/* Check that the %_docsize and %_content tables contain the expected
|
||||
** number of rows. */
|
||||
if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
|
||||
i64 nRow;
|
||||
i64 nRow = 0;
|
||||
rc = fts5StorageCount(p, "content", &nRow);
|
||||
if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
|
||||
}
|
||||
if( rc==SQLITE_OK && pConfig->bColumnsize ){
|
||||
i64 nRow;
|
||||
i64 nRow = 0;
|
||||
rc = fts5StorageCount(p, "docsize", &nRow);
|
||||
if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
|
||||
}
|
||||
|
||||
@@ -242,7 +242,7 @@ static int fts5UnicodeAddExceptions(
|
||||
int bTokenChars /* 1 for 'tokenchars', 0 for 'separators' */
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
int n = strlen(z);
|
||||
int n = (int)strlen(z);
|
||||
int *aNew;
|
||||
|
||||
if( n>0 ){
|
||||
|
||||
+149
-37
@@ -55,16 +55,18 @@ struct Fts5VocabCursor {
|
||||
int bEof; /* True if this cursor is at EOF */
|
||||
Fts5IndexIter *pIter; /* Term/rowid iterator object */
|
||||
|
||||
int nLeTerm; /* Size of zLeTerm in bytes */
|
||||
char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */
|
||||
|
||||
/* These are used by 'col' tables only */
|
||||
int nCol;
|
||||
Fts5Config *pConfig; /* Fts5 table configuration */
|
||||
int iCol;
|
||||
i64 *aCnt;
|
||||
i64 *aDoc;
|
||||
|
||||
/* Output values */
|
||||
/* Output values used by 'row' and 'col' tables */
|
||||
i64 rowid; /* This table's current rowid value */
|
||||
Fts5Buffer term; /* Current value of 'term' column */
|
||||
i64 aVal[3]; /* Up to three columns left of 'term' */
|
||||
};
|
||||
|
||||
#define FTS5_VOCAB_COL 0
|
||||
@@ -73,6 +75,14 @@ struct Fts5VocabCursor {
|
||||
#define FTS5_VOCAB_COL_SCHEMA "term, col, doc, cnt"
|
||||
#define FTS5_VOCAB_ROW_SCHEMA "term, doc, cnt"
|
||||
|
||||
/*
|
||||
** Bits for the mask used as the idxNum value by xBestIndex/xFilter.
|
||||
*/
|
||||
#define FTS5_VOCAB_TERM_EQ 0x01
|
||||
#define FTS5_VOCAB_TERM_GE 0x02
|
||||
#define FTS5_VOCAB_TERM_LE 0x04
|
||||
|
||||
|
||||
/*
|
||||
** Translate a string containing an fts5vocab table type to an
|
||||
** FTS5_VOCAB_XXX constant. If successful, set *peType to the output
|
||||
@@ -168,9 +178,9 @@ static int fts5VocabInitVtab(
|
||||
const char *zDb = bDb ? argv[3] : argv[1];
|
||||
const char *zTab = bDb ? argv[4] : argv[3];
|
||||
const char *zType = bDb ? argv[5] : argv[4];
|
||||
int nDb = strlen(zDb)+1;
|
||||
int nTab = strlen(zTab)+1;
|
||||
int eType;
|
||||
int nDb = (int)strlen(zDb)+1;
|
||||
int nTab = (int)strlen(zTab)+1;
|
||||
int eType = 0;
|
||||
|
||||
rc = fts5VocabTableType(zType, pzErr, &eType);
|
||||
if( rc==SQLITE_OK ){
|
||||
@@ -230,6 +240,45 @@ static int fts5VocabBestIndexMethod(
|
||||
sqlite3_vtab *pVTab,
|
||||
sqlite3_index_info *pInfo
|
||||
){
|
||||
int i;
|
||||
int iTermEq = -1;
|
||||
int iTermGe = -1;
|
||||
int iTermLe = -1;
|
||||
int idxNum = 0;
|
||||
int nArg = 0;
|
||||
|
||||
for(i=0; i<pInfo->nConstraint; i++){
|
||||
struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
|
||||
if( p->usable==0 ) continue;
|
||||
if( p->iColumn==0 ){ /* term column */
|
||||
if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ) iTermEq = i;
|
||||
if( p->op==SQLITE_INDEX_CONSTRAINT_LE ) iTermLe = i;
|
||||
if( p->op==SQLITE_INDEX_CONSTRAINT_LT ) iTermLe = i;
|
||||
if( p->op==SQLITE_INDEX_CONSTRAINT_GE ) iTermGe = i;
|
||||
if( p->op==SQLITE_INDEX_CONSTRAINT_GT ) iTermGe = i;
|
||||
}
|
||||
}
|
||||
|
||||
if( iTermEq>=0 ){
|
||||
idxNum |= FTS5_VOCAB_TERM_EQ;
|
||||
pInfo->aConstraintUsage[iTermEq].argvIndex = ++nArg;
|
||||
pInfo->estimatedCost = 100;
|
||||
}else{
|
||||
pInfo->estimatedCost = 1000000;
|
||||
if( iTermGe>=0 ){
|
||||
idxNum |= FTS5_VOCAB_TERM_GE;
|
||||
pInfo->aConstraintUsage[iTermGe].argvIndex = ++nArg;
|
||||
pInfo->estimatedCost = pInfo->estimatedCost / 2;
|
||||
}
|
||||
if( iTermLe>=0 ){
|
||||
idxNum |= FTS5_VOCAB_TERM_LE;
|
||||
pInfo->aConstraintUsage[iTermLe].argvIndex = ++nArg;
|
||||
pInfo->estimatedCost = pInfo->estimatedCost / 2;
|
||||
}
|
||||
}
|
||||
|
||||
pInfo->idxNum = idxNum;
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -242,12 +291,11 @@ static int fts5VocabOpenMethod(
|
||||
){
|
||||
Fts5VocabTable *pTab = (Fts5VocabTable*)pVTab;
|
||||
Fts5Index *pIndex = 0;
|
||||
int nCol = 0;
|
||||
Fts5Config *pConfig = 0;
|
||||
Fts5VocabCursor *pCsr = 0;
|
||||
int rc = SQLITE_OK;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
char *zSql = 0;
|
||||
int nByte;
|
||||
|
||||
zSql = sqlite3Fts5Mprintf(&rc,
|
||||
"SELECT t.%Q FROM %Q.%Q AS t WHERE t.%Q MATCH '*id'",
|
||||
@@ -262,7 +310,7 @@ static int fts5VocabOpenMethod(
|
||||
|
||||
if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
|
||||
i64 iId = sqlite3_column_int64(pStmt, 0);
|
||||
pIndex = sqlite3Fts5IndexFromCsrid(pTab->pGlobal, iId, &nCol);
|
||||
pIndex = sqlite3Fts5IndexFromCsrid(pTab->pGlobal, iId, &pConfig);
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK && pIndex==0 ){
|
||||
@@ -276,14 +324,17 @@ static int fts5VocabOpenMethod(
|
||||
}
|
||||
}
|
||||
|
||||
nByte = nCol * sizeof(i64) * 2 + sizeof(Fts5VocabCursor);
|
||||
pCsr = (Fts5VocabCursor*)sqlite3Fts5MallocZero(&rc, nByte);
|
||||
if( rc==SQLITE_OK ){
|
||||
int nByte = pConfig->nCol * sizeof(i64) * 2 + sizeof(Fts5VocabCursor);
|
||||
pCsr = (Fts5VocabCursor*)sqlite3Fts5MallocZero(&rc, nByte);
|
||||
}
|
||||
|
||||
if( pCsr ){
|
||||
pCsr->pIndex = pIndex;
|
||||
pCsr->pStmt = pStmt;
|
||||
pCsr->nCol = nCol;
|
||||
pCsr->pConfig = pConfig;
|
||||
pCsr->aCnt = (i64*)&pCsr[1];
|
||||
pCsr->aDoc = &pCsr->aCnt[nCol];
|
||||
pCsr->aDoc = &pCsr->aCnt[pConfig->nCol];
|
||||
}else{
|
||||
sqlite3_finalize(pStmt);
|
||||
}
|
||||
@@ -296,6 +347,9 @@ static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){
|
||||
pCsr->rowid = 0;
|
||||
sqlite3Fts5IterClose(pCsr->pIter);
|
||||
pCsr->pIter = 0;
|
||||
sqlite3_free(pCsr->zLeTerm);
|
||||
pCsr->nLeTerm = -1;
|
||||
pCsr->zLeTerm = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -319,16 +373,17 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
|
||||
Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
|
||||
Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab;
|
||||
int rc = SQLITE_OK;
|
||||
int nCol = pCsr->pConfig->nCol;
|
||||
|
||||
pCsr->rowid++;
|
||||
|
||||
if( pTab->eType==FTS5_VOCAB_COL ){
|
||||
for(pCsr->iCol++; pCsr->iCol<pCsr->nCol; pCsr->iCol++){
|
||||
for(pCsr->iCol++; pCsr->iCol<nCol; pCsr->iCol++){
|
||||
if( pCsr->aCnt[pCsr->iCol] ) break;
|
||||
}
|
||||
}
|
||||
|
||||
if( pTab->eType==FTS5_VOCAB_ROW || pCsr->iCol>=pCsr->nCol ){
|
||||
if( pTab->eType==FTS5_VOCAB_ROW || pCsr->iCol>=nCol ){
|
||||
if( sqlite3Fts5IterEof(pCsr->pIter) ){
|
||||
pCsr->bEof = 1;
|
||||
}else{
|
||||
@@ -336,10 +391,18 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
|
||||
int nTerm;
|
||||
|
||||
zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
|
||||
if( pCsr->nLeTerm>=0 ){
|
||||
int nCmp = MIN(nTerm, pCsr->nLeTerm);
|
||||
int bCmp = memcmp(pCsr->zLeTerm, zTerm, nCmp);
|
||||
if( bCmp<0 || (bCmp==0 && pCsr->nLeTerm<nTerm) ){
|
||||
pCsr->bEof = 1;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
sqlite3Fts5BufferSet(&rc, &pCsr->term, nTerm, (const u8*)zTerm);
|
||||
memset(pCsr->aVal, 0, sizeof(pCsr->aVal));
|
||||
memset(pCsr->aCnt, 0, pCsr->nCol * sizeof(i64));
|
||||
memset(pCsr->aDoc, 0, pCsr->nCol * sizeof(i64));
|
||||
memset(pCsr->aCnt, 0, nCol * sizeof(i64));
|
||||
memset(pCsr->aDoc, 0, nCol * sizeof(i64));
|
||||
pCsr->iCol = 0;
|
||||
|
||||
assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW );
|
||||
@@ -353,9 +416,9 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
|
||||
if( rc==SQLITE_OK ){
|
||||
if( pTab->eType==FTS5_VOCAB_ROW ){
|
||||
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
|
||||
pCsr->aVal[1]++;
|
||||
pCsr->aCnt[0]++;
|
||||
}
|
||||
pCsr->aVal[0]++;
|
||||
pCsr->aDoc[0]++;
|
||||
}else{
|
||||
int iCol = -1;
|
||||
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
|
||||
@@ -369,9 +432,12 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
|
||||
}
|
||||
rc = sqlite3Fts5IterNextScan(pCsr->pIter);
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
|
||||
if( nTerm!=pCsr->term.n || memcmp(zTerm, pCsr->term.p, nTerm) ) break;
|
||||
if( nTerm!=pCsr->term.n || memcmp(zTerm, pCsr->term.p, nTerm) ){
|
||||
break;
|
||||
}
|
||||
if( sqlite3Fts5IterEof(pCsr->pIter) ) break;
|
||||
}
|
||||
}
|
||||
@@ -380,9 +446,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
|
||||
|
||||
if( pCsr->bEof==0 && pTab->eType==FTS5_VOCAB_COL ){
|
||||
while( pCsr->aCnt[pCsr->iCol]==0 ) pCsr->iCol++;
|
||||
pCsr->aVal[0] = pCsr->iCol;
|
||||
pCsr->aVal[1] = pCsr->aDoc[pCsr->iCol];
|
||||
pCsr->aVal[2] = pCsr->aCnt[pCsr->iCol];
|
||||
assert( pCsr->iCol<pCsr->pConfig->nCol );
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -398,11 +462,47 @@ static int fts5VocabFilterMethod(
|
||||
sqlite3_value **apVal /* Arguments for the indexing scheme */
|
||||
){
|
||||
Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
|
||||
int rc;
|
||||
const int flags = FTS5INDEX_QUERY_SCAN;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
int iVal = 0;
|
||||
int f = FTS5INDEX_QUERY_SCAN;
|
||||
const char *zTerm = 0;
|
||||
int nTerm = 0;
|
||||
|
||||
sqlite3_value *pEq = 0;
|
||||
sqlite3_value *pGe = 0;
|
||||
sqlite3_value *pLe = 0;
|
||||
|
||||
fts5VocabResetCursor(pCsr);
|
||||
rc = sqlite3Fts5IndexQuery(pCsr->pIndex, 0, 0, flags, 0, &pCsr->pIter);
|
||||
if( idxNum & FTS5_VOCAB_TERM_EQ ) pEq = apVal[iVal++];
|
||||
if( idxNum & FTS5_VOCAB_TERM_GE ) pGe = apVal[iVal++];
|
||||
if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++];
|
||||
|
||||
if( pEq ){
|
||||
zTerm = (const char *)sqlite3_value_text(pEq);
|
||||
nTerm = sqlite3_value_bytes(pEq);
|
||||
f = 0;
|
||||
}else{
|
||||
if( pGe ){
|
||||
zTerm = (const char *)sqlite3_value_text(pGe);
|
||||
nTerm = sqlite3_value_bytes(pGe);
|
||||
}
|
||||
if( pLe ){
|
||||
const char *zCopy = (const char *)sqlite3_value_text(pLe);
|
||||
pCsr->nLeTerm = sqlite3_value_bytes(pLe);
|
||||
pCsr->zLeTerm = sqlite3_malloc(pCsr->nLeTerm+1);
|
||||
if( pCsr->zLeTerm==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
memcpy(pCsr->zLeTerm, zCopy, pCsr->nLeTerm+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3Fts5IndexQuery(pCsr->pIndex, zTerm, nTerm, f, 0, &pCsr->pIter);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = fts5VocabNextMethod(pCursor);
|
||||
}
|
||||
@@ -425,17 +525,29 @@ static int fts5VocabColumnMethod(
|
||||
int iCol /* Index of column to read value from */
|
||||
){
|
||||
Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
|
||||
switch( iCol ){
|
||||
case 0: /* term */
|
||||
sqlite3_result_text(
|
||||
pCtx, (const char*)pCsr->term.p, pCsr->term.n, SQLITE_TRANSIENT
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert( iCol<4 && iCol>0 );
|
||||
sqlite3_result_int64(pCtx, pCsr->aVal[iCol-1]);
|
||||
break;
|
||||
if( iCol==0 ){
|
||||
sqlite3_result_text(
|
||||
pCtx, (const char*)pCsr->term.p, pCsr->term.n, SQLITE_TRANSIENT
|
||||
);
|
||||
}
|
||||
else if( ((Fts5VocabTable*)(pCursor->pVtab))->eType==FTS5_VOCAB_COL ){
|
||||
assert( iCol==1 || iCol==2 || iCol==3 );
|
||||
if( iCol==1 ){
|
||||
const char *z = pCsr->pConfig->azCol[pCsr->iCol];
|
||||
sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC);
|
||||
}else if( iCol==2 ){
|
||||
sqlite3_result_int64(pCtx, pCsr->aDoc[pCsr->iCol]);
|
||||
}else{
|
||||
sqlite3_result_int64(pCtx, pCsr->aCnt[pCsr->iCol]);
|
||||
}
|
||||
}else{
|
||||
assert( iCol==1 || iCol==2 );
|
||||
if( iCol==1 ){
|
||||
sqlite3_result_int64(pCtx, pCsr->aDoc[0]);
|
||||
}else{
|
||||
sqlite3_result_int64(pCtx, pCsr->aCnt[0]);
|
||||
}
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
set testprefix fts5aa
|
||||
|
||||
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
|
||||
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
@@ -159,9 +159,20 @@ do_execsql_test 6.3 {
|
||||
}
|
||||
|
||||
do_execsql_test 6.4 {
|
||||
REPLACE INTO t1(x, y) VALUES('x y z', 'x y z');
|
||||
}
|
||||
|
||||
do_execsql_test 6.5 {
|
||||
INSERT INTO t1(t1) VALUES('integrity-check')
|
||||
}
|
||||
|
||||
do_execsql_test 6.6 {
|
||||
SELECT rowid, * FROM t1;
|
||||
} {
|
||||
22 {l l l} {l l l}
|
||||
23 {x y z} {x y z}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
# 2015 October 27
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#*************************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is testing the FTS5 module.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
set testprefix fts5conflict
|
||||
|
||||
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(x INTEGER PRIMARY KEY, a, b);
|
||||
CREATE VIRTUAL TABLE ft USING fts5(a, b, content=t1, content_rowid=x);
|
||||
}
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
REPLACE INTO ft(rowid, a, b) VALUES(1, 'a b c', 'a b c');
|
||||
REPLACE INTO t1 VALUES(1, 'a b c', 'a b c');
|
||||
}
|
||||
|
||||
do_execsql_test 1.2 {
|
||||
INSERT INTO ft(ft) VALUES('integrity-check');
|
||||
}
|
||||
|
||||
do_execsql_test 2.0 {
|
||||
CREATE TABLE tbl(a INTEGER PRIMARY KEY, b, c);
|
||||
CREATE VIRTUAL TABLE fts_idx USING fts5(b, c, content=tbl, content_rowid=a);
|
||||
CREATE TRIGGER tbl_ai AFTER INSERT ON tbl BEGIN
|
||||
INSERT INTO fts_idx(rowid, b, c) VALUES (new.a, new.b, new.c);
|
||||
END;
|
||||
CREATE TRIGGER tbl_ad AFTER DELETE ON tbl BEGIN
|
||||
INSERT INTO fts_idx(fts_idx, rowid, b, c)
|
||||
VALUES('delete', old.a, old.b, old.c);
|
||||
END;
|
||||
CREATE TRIGGER tbl_au AFTER UPDATE ON tbl BEGIN
|
||||
INSERT INTO fts_idx(fts_idx, rowid, b, c)
|
||||
VALUES('delete', old.a, old.b, old.c);
|
||||
INSERT INTO fts_idx(rowid, b, c) VALUES (new.a, new.b, new.c);
|
||||
END;
|
||||
}
|
||||
|
||||
do_execsql_test 2.1 {
|
||||
PRAGMA recursive_triggers = 1;
|
||||
INSERT INTO tbl VALUES(1, 'x y z', '1 2 3');
|
||||
INSERT INTO tbl VALUES(10, 'x y z', '1 2 3');
|
||||
INSERT INTO tbl VALUES(100, 'x 1 z', '1 y 3');
|
||||
|
||||
UPDATE tbl SET b = '1 2 x' WHERE rowid=10;
|
||||
REPLACE INTO tbl VALUES(1, '4 5 6', '3 2 1');
|
||||
DELETE FROM tbl WHERE a=100;
|
||||
|
||||
INSERT INTO fts_idx(fts_idx) VALUES('integrity-check');
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -250,8 +250,6 @@ foreach rowid [db eval {SELECT rowid FROM x1_data WHERE rowid>100}] {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
@@ -335,6 +333,44 @@ do_catchsql_test 6.3.5 {
|
||||
INSERT INTO t1(t1) VALUES('integrity-check');
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
reset_db
|
||||
proc rnddoc {n} {
|
||||
set map [list a b c d]
|
||||
set doc [list]
|
||||
for {set i 0} {$i < $n} {incr i} {
|
||||
lappend doc "x[lindex $map [expr int(rand()*4)]]"
|
||||
}
|
||||
set doc
|
||||
}
|
||||
|
||||
db func rnddoc rnddoc
|
||||
do_test 7.0 {
|
||||
execsql {
|
||||
CREATE VIRTUAL TABLE t5 USING fts5(x);
|
||||
INSERT INTO t5 VALUES( rnddoc(10000) );
|
||||
INSERT INTO t5 VALUES( rnddoc(10000) );
|
||||
INSERT INTO t5 VALUES( rnddoc(10000) );
|
||||
INSERT INTO t5 VALUES( rnddoc(10000) );
|
||||
INSERT INTO t5(t5) VALUES('optimize');
|
||||
}
|
||||
} {}
|
||||
|
||||
do_test 7.1 {
|
||||
foreach i [db eval { SELECT rowid FROM t5_data WHERE rowid>100 }] {
|
||||
db eval BEGIN
|
||||
db eval {DELETE FROM t5_data WHERE rowid = $i}
|
||||
set r [catchsql { INSERT INTO t5(t5) VALUES('integrity-check')} ]
|
||||
if {$r != "1 {database disk image is malformed}"} { error $r }
|
||||
db eval ROLLBACK
|
||||
}
|
||||
} {}
|
||||
|
||||
sqlite3_fts5_may_be_corrupt 0
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -90,6 +90,14 @@ do_faultsim_test 3.1 -faults oom-t* -body {
|
||||
faultsim_test_result {0 {0 1 10 11 12 13 14 15 16 17 18 19 2 3 4 5 6 7 8 9}}
|
||||
}
|
||||
|
||||
do_faultsim_test 3.2 -faults oom-t* -body {
|
||||
db eval {
|
||||
SELECT term FROM tv WHERE term BETWEEN '1' AND '2';
|
||||
}
|
||||
} -test {
|
||||
faultsim_test_result {0 {1 10 11 12 13 14 15 16 17 18 19 2}}
|
||||
}
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -87,5 +87,26 @@ do_faultsim_test 1 -faults oom-t* -prep {
|
||||
faultsim_test_result {0 {}}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test fault-injection when a segment is promoted.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 2.0 {
|
||||
CREATE VIRTUAL TABLE xy USING fts5(x);
|
||||
INSERT INTO xy(rowid, x) VALUES(1, '1 2 3');
|
||||
INSERT INTO xy(rowid, x) VALUES(2, '2 3 4');
|
||||
INSERT INTO xy(rowid, x) VALUES(3, '3 4 5');
|
||||
}
|
||||
faultsim_save_and_close
|
||||
|
||||
do_faultsim_test 2 -faults oom-* -prep {
|
||||
faultsim_restore_and_reopen
|
||||
} -body {
|
||||
db eval { UPDATE OR REPLACE xy SET rowid=3 WHERE rowid = 2 }
|
||||
} -test {
|
||||
faultsim_test_result {0 {}}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -84,11 +84,13 @@ lappend vocab xyz
|
||||
do_execsql_test 1.1 {
|
||||
CREATE VIRTUAL TABLE vocab USING fts5vocab(eee, 'row');
|
||||
BEGIN;
|
||||
WITH ii(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<100)
|
||||
INSERT INTO eee SELECT r($vocab, 5), r($vocab, 7) FROM ii;
|
||||
INSERT INTO eee(eee) VALUES('integrity-check');
|
||||
}
|
||||
|
||||
do_test 1.2 {
|
||||
for {set i 1} {$i <= 100} {incr i} {
|
||||
execsql { INSERT INTO eee VALUES( r($vocab, 5), r($vocab, 7) ) }
|
||||
}
|
||||
} {}
|
||||
|
||||
do_test 1.2 {
|
||||
db eval { SELECT term, doc FROM vocab } {
|
||||
set nRow [db one {SELECT count(*) FROM eee WHERE eee MATCH $term}]
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# This file containst tests focused on the integrity-check procedure.
|
||||
# This file contains tests focused on the integrity-check procedure.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
@@ -102,6 +102,53 @@ do_catchsql_test 4.5 {
|
||||
#db eval {SELECT rowid, fts5_decode(rowid, block) aS r FROM zz_data} {puts $r}
|
||||
#exit
|
||||
|
||||
execsql { ROLLBACK }
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that integrity-check works on a reasonably large db with many
|
||||
# different terms.
|
||||
|
||||
# Document generator command.
|
||||
proc rnddoc {n} {
|
||||
set doc [list]
|
||||
for {set i 0} {$i<$n} {incr i} {
|
||||
lappend doc [format %.5d [expr int(rand()*10000)]]
|
||||
}
|
||||
return $doc
|
||||
}
|
||||
db func rnddoc rnddoc
|
||||
|
||||
expr srand(0)
|
||||
do_execsql_test 5.0 {
|
||||
CREATE VIRTUAL TABLE gg USING fts5(a, prefix="1,2,3");
|
||||
INSERT INTO gg(gg, rank) VALUES('pgsz', 256);
|
||||
INSERT INTO gg VALUES(rnddoc(20));
|
||||
INSERT INTO gg SELECT rnddoc(20) FROM gg;
|
||||
INSERT INTO gg SELECT rnddoc(20) FROM gg;
|
||||
INSERT INTO gg SELECT rnddoc(20) FROM gg;
|
||||
INSERT INTO gg SELECT rnddoc(20) FROM gg;
|
||||
INSERT INTO gg SELECT rnddoc(20) FROM gg;
|
||||
INSERT INTO gg SELECT rnddoc(20) FROM gg;
|
||||
INSERT INTO gg SELECT rnddoc(20) FROM gg;
|
||||
INSERT INTO gg SELECT rnddoc(20) FROM gg;
|
||||
INSERT INTO gg SELECT rnddoc(20) FROM gg;
|
||||
INSERT INTO gg SELECT rnddoc(20) FROM gg;
|
||||
INSERT INTO gg SELECT rnddoc(20) FROM gg;
|
||||
}
|
||||
|
||||
do_execsql_test 5.1 {
|
||||
INSERT INTO gg(gg) VALUES('integrity-check');
|
||||
}
|
||||
|
||||
do_execsql_test 5.2 {
|
||||
INSERT INTO gg(gg) VALUES('optimize');
|
||||
}
|
||||
|
||||
breakpoint
|
||||
do_execsql_test 5.3 {
|
||||
INSERT INTO gg(gg) VALUES('integrity-check');
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -195,6 +195,108 @@ for {set x 0} {$x<2} {incr x} {
|
||||
execsql { INSERT INTO t3(t3) VALUES('integrity-check') }
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 4.0 {
|
||||
CREATE VIRTUAL TABLE t2 USING fts5(c1, c2);
|
||||
INSERT INTO t2 VALUES('xa xb', 'xb xa');
|
||||
|
||||
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 2
|
||||
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 4
|
||||
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 8
|
||||
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 16
|
||||
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 32
|
||||
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 64
|
||||
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 128
|
||||
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 256
|
||||
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 512
|
||||
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 1024
|
||||
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 2048
|
||||
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 4096
|
||||
|
||||
SELECT count(*) FROM t2('x*');
|
||||
} {4096}
|
||||
|
||||
do_execsql_test 4.1 {
|
||||
UPDATE t2 SET c2 = 'ya yb';
|
||||
SELECT count(*) FROM t2('c1:x*');
|
||||
SELECT count(*) FROM t2('c2:x*');
|
||||
} {4096 0}
|
||||
|
||||
do_execsql_test 4.2 {
|
||||
UPDATE t2 SET c2 = 'xa';
|
||||
SELECT count(*) FROM t2('c1:x*');
|
||||
SELECT count(*) FROM t2('c2:x*');
|
||||
} {4096 4096}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
proc rnddoc {n} {
|
||||
set map [list a b c d]
|
||||
set doc [list]
|
||||
for {set i 0} {$i < $n} {incr i} {
|
||||
lappend doc "x[lindex $map [expr int(rand()*4)]]"
|
||||
}
|
||||
set doc
|
||||
}
|
||||
set cols [list]
|
||||
for {set i 1} {$i<250} {incr i} {
|
||||
lappend cols "c$i"
|
||||
lappend vals "'[rnddoc 10]'"
|
||||
}
|
||||
|
||||
do_test 5.0 {
|
||||
execsql "CREATE VIRTUAL TABLE t4 USING fts5([join $cols ,])"
|
||||
execsql {INSERT INTO t4(t4, rank) VALUES('pgsz', 32)}
|
||||
execsql "INSERT INTO t4 VALUES([join $vals ,])"
|
||||
execsql "INSERT INTO t4 VALUES([join $vals ,])"
|
||||
execsql "INSERT INTO t4 VALUES([join $vals ,])"
|
||||
execsql "INSERT INTO t4 VALUES([join $vals ,])"
|
||||
} {}
|
||||
|
||||
proc gmatch {col pattern} {
|
||||
expr {[lsearch -glob $col $pattern]>=0}
|
||||
}
|
||||
db func gmatch gmatch
|
||||
foreach {tn col pattern} {
|
||||
1 c100 {xa*}
|
||||
2 c200 {xb*}
|
||||
} {
|
||||
set res [db eval "SELECT rowid FROM t4 WHERE gmatch($col, \$pattern)"]
|
||||
set query "$col : $pattern"
|
||||
do_execsql_test 5.$tn { SELECT rowid FROM t4($query) } $res
|
||||
}
|
||||
|
||||
reset_db
|
||||
db func fts5_rnddoc fts5_rnddoc
|
||||
do_test 6.0 {
|
||||
execsql {
|
||||
CREATE VIRTUAL TABLE t5 USING fts5(x, y);
|
||||
INSERT INTO t5 VALUES( fts5_rnddoc(10000), fts5_rnddoc(10000) );
|
||||
INSERT INTO t5 VALUES( fts5_rnddoc(10000), fts5_rnddoc(10000) );
|
||||
INSERT INTO t5 VALUES( fts5_rnddoc(10000), fts5_rnddoc(10000) );
|
||||
INSERT INTO t5 VALUES( fts5_rnddoc(10000), fts5_rnddoc(10000) );
|
||||
}
|
||||
} {}
|
||||
|
||||
proc gmatch {col pattern} {
|
||||
expr {[lsearch -glob $col $pattern]>=0}
|
||||
}
|
||||
db func gmatch gmatch
|
||||
foreach {tn col pattern} {
|
||||
1 y {xa*}
|
||||
2 y {xb*}
|
||||
3 y {xc*}
|
||||
4 x {xa*}
|
||||
5 x {xb*}
|
||||
6 x {xc*}
|
||||
} {
|
||||
set res [db eval "SELECT rowid FROM t5 WHERE gmatch($col, \$pattern)"]
|
||||
set query "$col : $pattern"
|
||||
do_execsql_test 6.$tn { SELECT rowid FROM t5($query) } $res
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
# 2015 October 27
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#*************************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is testing the FTS5 module.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
set testprefix fts5query
|
||||
|
||||
# If SQLITE_ENABLE_FTS5 is defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
for {set tn 1 ; set pgsz 64} {$tn<32} {incr tn; incr pgsz 16} {
|
||||
reset_db
|
||||
do_test 1.$tn.1 {
|
||||
execsql {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(x);
|
||||
INSERT INTO t1(t1, rank) VALUES('pgsz', $pgsz);
|
||||
BEGIN;
|
||||
}
|
||||
foreach x [list aaa bbb ccc ddd eee fff ggg hhh iii jjj] {
|
||||
set doc [string repeat "$x " 30]
|
||||
execsql { INSERT INTO t1 VALUES($doc) }
|
||||
}
|
||||
execsql COMMIT
|
||||
} {}
|
||||
|
||||
do_execsql_test 1.$tn.2 {
|
||||
INSERT INTO t1(t1) VALUES('integrity-check');
|
||||
}
|
||||
|
||||
set ret 1
|
||||
foreach x [list a b c d e f g h i j] {
|
||||
do_execsql_test 1.$tn.3.$ret {
|
||||
SELECT rowid FROM t1 WHERE t1 MATCH $x || '*';
|
||||
} $ret
|
||||
incr ret
|
||||
}
|
||||
}
|
||||
|
||||
for {set tn 1 ; set pgsz 64} {$tn<32} {incr tn; incr pgsz 16} {
|
||||
reset_db
|
||||
do_test 2.$tn.1 {
|
||||
execsql {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(x);
|
||||
INSERT INTO t1(t1, rank) VALUES('pgsz', $pgsz);
|
||||
BEGIN;
|
||||
}
|
||||
foreach x [list bbb ddd fff hhh jjj lll nnn ppp rrr ttt] {
|
||||
set doc [string repeat "$x " 30]
|
||||
execsql { INSERT INTO t1 VALUES($doc) }
|
||||
}
|
||||
execsql COMMIT
|
||||
} {}
|
||||
|
||||
do_execsql_test 1.$tn.2 {
|
||||
INSERT INTO t1(t1) VALUES('integrity-check');
|
||||
}
|
||||
|
||||
set ret 1
|
||||
foreach x [list a c e g i k m o q s u] {
|
||||
do_execsql_test 2.$tn.3.$ret {
|
||||
SELECT rowid FROM t1 WHERE t1 MATCH $x || '*';
|
||||
} {}
|
||||
incr ret
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -300,5 +300,27 @@ do_execsql_test 12.2 {
|
||||
COMMIT;
|
||||
} {}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Try an UPDATE OR REPLACE query.
|
||||
#
|
||||
do_execsql_test 13.1 {
|
||||
CREATE VIRTUAL TABLE xy USING fts5(x);
|
||||
INSERT INTO xy(rowid, x) VALUES(1, '1 2 3');
|
||||
INSERT INTO xy(rowid, x) VALUES(2, '2 3 4');
|
||||
INSERT INTO xy(rowid, x) VALUES(3, '3 4 5');
|
||||
}
|
||||
|
||||
do_execsql_test 13.2 {
|
||||
UPDATE OR REPLACE xy SET rowid=3 WHERE rowid = 2;
|
||||
SELECT rowid, x FROM xy;
|
||||
} {
|
||||
1 {1 2 3}
|
||||
3 {2 3 4}
|
||||
}
|
||||
|
||||
do_execsql_test 13.3 {
|
||||
INSERT INTO xy(xy) VALUES('integrity-check');
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
+142
-10
@@ -56,7 +56,7 @@ do_execsql_test 1.4.1 {
|
||||
|
||||
do_execsql_test 1.4.2 {
|
||||
SELECT * FROM v2;
|
||||
} {x 0 2 4 y 0 1 1 z 0 1 1}
|
||||
} {x one 2 4 y one 1 1 z one 1 1}
|
||||
|
||||
do_execsql_test 1.5.1 {
|
||||
BEGIN;
|
||||
@@ -67,7 +67,7 @@ do_execsql_test 1.5.1 {
|
||||
do_execsql_test 1.5.2 {
|
||||
SELECT * FROM v2 WHERE term<'d';
|
||||
COMMIT;
|
||||
} {a 0 1 1 b 0 1 1 c 0 1 1}
|
||||
} {a one 1 1 b one 1 1 c one 1 1}
|
||||
|
||||
do_execsql_test 1.6 {
|
||||
DELETE FROM t1 WHERE one = 'a b c';
|
||||
@@ -91,14 +91,14 @@ do_execsql_test 2.0 {
|
||||
}
|
||||
|
||||
set res_col {
|
||||
a 0 6 11 a 1 7 9
|
||||
b 0 6 7 b 1 7 7
|
||||
c 0 6 12 c 1 5 8
|
||||
d 0 4 6 d 1 9 13
|
||||
e 0 6 7 e 1 6 6
|
||||
f 0 9 10 f 1 7 10
|
||||
g 0 5 7 g 1 5 7
|
||||
x 0 1 1 y 1 1 1
|
||||
a a 6 11 a b 7 9
|
||||
b a 6 7 b b 7 7
|
||||
c a 6 12 c b 5 8
|
||||
d a 4 6 d b 9 13
|
||||
e a 6 7 e b 6 6
|
||||
f a 9 10 f b 7 10
|
||||
g a 5 7 g b 5 7
|
||||
x a 1 1 y b 1 1
|
||||
}
|
||||
set res_row {
|
||||
a 10 20 b 9 14 c 9 20 d 9 19
|
||||
@@ -213,5 +213,137 @@ do_catchsql_test 6.2 {
|
||||
SELECT * FROM vocab3;
|
||||
} {1 {no such fts5 table: main.lll}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test single term queries on fts5vocab tables (i.e. those with term=?
|
||||
# constraints in the WHERE clause).
|
||||
#
|
||||
do_execsql_test 7.0 {
|
||||
CREATE VIRTUAL TABLE tx USING fts5(one, two);
|
||||
INSERT INTO tx VALUES('g a ggg g a b eee', 'cc d aa ff g ee');
|
||||
INSERT INTO tx VALUES('dd fff i a i jjj', 'f fff hh jj e f');
|
||||
INSERT INTO tx VALUES('ggg a f f fff dd aa', 'd ggg f f j gg ddd');
|
||||
INSERT INTO tx VALUES('e bb h jjj ii gg', 'e aa e f c fff');
|
||||
INSERT INTO tx VALUES('j ff aa a h', 'h a j bbb bb');
|
||||
INSERT INTO tx VALUES('cc i ff c d f', 'dd ii fff f c cc d');
|
||||
INSERT INTO tx VALUES('jjj g i bb cc eee', 'hhh iii aaa b bbb aaa');
|
||||
INSERT INTO tx VALUES('hhh hhh hhh bb fff f', 'fff gg aa ii h a');
|
||||
INSERT INTO tx VALUES('b c cc aaa iii ggg f', 'iii ff ee a ff c cc');
|
||||
INSERT INTO tx VALUES('hhh b hhh aaa j i i', 'dd ee ee aa bbb iii');
|
||||
INSERT INTO tx VALUES('hh dd h b g ff i', 'ccc bb cc ccc f a d');
|
||||
INSERT INTO tx VALUES('g d b ggg jj', 'fff jj ff jj g gg ee');
|
||||
INSERT INTO tx VALUES('g ee ggg ggg cc bb eee', 'aa j jjj bbb dd eee ff');
|
||||
INSERT INTO tx VALUES('c jjj hh ddd dd h', 'e aaa h jjj gg');
|
||||
|
||||
CREATE VIRTUAL TABLE txr USING fts5vocab(tx, row);
|
||||
CREATE VIRTUAL TABLE txc USING fts5vocab(tx, col);
|
||||
}
|
||||
|
||||
proc cont {L elem} {
|
||||
set n 0
|
||||
foreach e $L { if {$elem==$e} {incr n} }
|
||||
set n
|
||||
}
|
||||
db func cont cont
|
||||
|
||||
foreach {term} {
|
||||
a aa aaa
|
||||
b bb bbb
|
||||
c cc ccc
|
||||
d dd ddd
|
||||
e ee eee
|
||||
f ff fff
|
||||
g gg ggg
|
||||
h hh hhh
|
||||
i ii iii
|
||||
j jj jjj
|
||||
} {
|
||||
set resr [db eval {
|
||||
SELECT $term,
|
||||
sum(cont(one || ' ' || two, $term) > 0),
|
||||
sum(cont(one || ' ' || two, $term))
|
||||
FROM tx
|
||||
}]
|
||||
if {[lindex $resr 1]==0} {set resr [list]}
|
||||
|
||||
set r1 [db eval {
|
||||
SELECT $term, 'one', sum(cont(one, $term)>0), sum(cont(one, $term)) FROM tx
|
||||
}]
|
||||
if {[lindex $r1 2]==0} {set r1 [list]}
|
||||
|
||||
set r2 [db eval {
|
||||
SELECT $term, 'two', sum(cont(two, $term)>0), sum(cont(two, $term)) FROM tx
|
||||
}]
|
||||
if {[lindex $r2 2]==0} {set r2 [list]}
|
||||
|
||||
set resc [concat $r1 $r2]
|
||||
do_execsql_test 7.$term.1 {SELECT * FROM txc WHERE term=$term} $resc
|
||||
do_execsql_test 7.$term.2 {SELECT * FROM txr WHERE term=$term} $resr
|
||||
}
|
||||
|
||||
do_execsql_test 7.1 {
|
||||
CREATE TABLE txr_c AS SELECT * FROM txr;
|
||||
CREATE TABLE txc_c AS SELECT * FROM txc;
|
||||
}
|
||||
|
||||
# Test range queries on the fts5vocab tables created above.
|
||||
#
|
||||
foreach {tn a b} {
|
||||
1 a jjj
|
||||
2 bb j
|
||||
3 ccc ddd
|
||||
4 dd xyz
|
||||
5 xzy dd
|
||||
6 h hh
|
||||
} {
|
||||
do_execsql_test 7.2.$tn.1 {
|
||||
SELECT * FROM txr WHERE term>=$a
|
||||
} [db eval {SELECT * FROM txr_c WHERE term>=$a}]
|
||||
do_execsql_test 7.2.$tn.2 {
|
||||
SELECT * FROM txr WHERE term<=$b
|
||||
} [db eval {SELECT * FROM txr_c WHERE term <=$b}]
|
||||
do_execsql_test 7.2.$tn.3 {
|
||||
SELECT * FROM txr WHERE term>=$a AND term<=$b
|
||||
} [db eval {SELECT * FROM txr_c WHERE term>=$a AND term <=$b}]
|
||||
|
||||
do_execsql_test 7.2.$tn.4 {
|
||||
SELECT * FROM txc WHERE term>=$a
|
||||
} [db eval {SELECT * FROM txc_c WHERE term>=$a}]
|
||||
do_execsql_test 7.2.$tn.5 {
|
||||
SELECT * FROM txc WHERE term<=$b
|
||||
} [db eval {SELECT * FROM txc_c WHERE term <=$b}]
|
||||
do_execsql_test 7.2.$tn.6 {
|
||||
SELECT * FROM txc WHERE term>=$a AND term<=$b
|
||||
} [db eval {SELECT * FROM txc_c WHERE term>=$a AND term <=$b}]
|
||||
|
||||
do_execsql_test 7.2.$tn.7 {
|
||||
SELECT * FROM txr WHERE term>$a
|
||||
} [db eval {SELECT * FROM txr_c WHERE term>$a}]
|
||||
do_execsql_test 7.2.$tn.8 {
|
||||
SELECT * FROM txr WHERE term<$b
|
||||
} [db eval {SELECT * FROM txr_c WHERE term<$b}]
|
||||
do_execsql_test 7.2.$tn.9 {
|
||||
SELECT * FROM txr WHERE term>$a AND term<$b
|
||||
} [db eval {SELECT * FROM txr_c WHERE term>$a AND term <$b}]
|
||||
|
||||
do_execsql_test 7.2.$tn.10 {
|
||||
SELECT * FROM txc WHERE term>$a
|
||||
} [db eval {SELECT * FROM txc_c WHERE term>$a}]
|
||||
do_execsql_test 7.2.$tn.11 {
|
||||
SELECT * FROM txc WHERE term<$b
|
||||
} [db eval {SELECT * FROM txc_c WHERE term<$b}]
|
||||
do_execsql_test 7.2.$tn.12 {
|
||||
SELECT * FROM txc WHERE term>$a AND term<$b
|
||||
} [db eval {SELECT * FROM txc_c WHERE term>$a AND term <$b}]
|
||||
}
|
||||
|
||||
do_execsql_test 7.3.1 {
|
||||
SELECT count(*) FROM txr, txr_c WHERE txr.term = txr_c.term;
|
||||
} {30}
|
||||
|
||||
do_execsql_test 7.3.2 {
|
||||
SELECT count(*) FROM txc, txc_c
|
||||
WHERE txc.term = txc_c.term AND txc.col=txc_c.col;
|
||||
} {57}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ is exhausted.
|
||||
exit -1
|
||||
}
|
||||
|
||||
set O(aColsize) [list 10 10 10]
|
||||
set O(aColSize) [list 10 10 10]
|
||||
set O(tblname) t1
|
||||
set O(fts) fts5
|
||||
|
||||
@@ -61,22 +61,7 @@ if {$i > [llength $argv]-2} usage
|
||||
set O(db) [lindex $argv $i]
|
||||
set O(files) [lrange $argv [expr $i+1] end]
|
||||
|
||||
foreach {k v} [lrange $argv 0 end-2] {
|
||||
switch -- $k {
|
||||
-colsize {
|
||||
set O(aColSize) $v
|
||||
}
|
||||
|
||||
-colsize {
|
||||
set O(aColSize) $v
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sqlite3 db $O(db)
|
||||
load_static_extension db fts5
|
||||
|
||||
|
||||
# Create the FTS table in the db. Return a list of the table columns.
|
||||
#
|
||||
@@ -84,7 +69,7 @@ proc create_table {} {
|
||||
global O
|
||||
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 $O(aColSize)]
|
||||
set cols [lrange $cols 0 [expr $nCol-1]]
|
||||
|
||||
set sql "CREATE VIRTUAL TABLE IF NOT EXISTS $O(tblname) USING $O(fts) ("
|
||||
@@ -117,14 +102,14 @@ set i 0
|
||||
set cols [create_table]
|
||||
set sql "INSERT INTO $O(tblname) VALUES(\$[lindex $cols 0]"
|
||||
foreach c [lrange $cols 1 end] {
|
||||
append sql ", \$$c"
|
||||
append sql ", \$A($c)"
|
||||
}
|
||||
append sql ")"
|
||||
|
||||
db eval BEGIN
|
||||
while {$i < $N} {
|
||||
foreach c $cols s $O(aColsize) {
|
||||
set $c [lrange $tokens $i [expr $i+$s-1]]
|
||||
foreach c $cols s $O(aColSize) {
|
||||
set A($c) [lrange $tokens $i [expr $i+$s-1]]
|
||||
incr i $s
|
||||
}
|
||||
db eval $sql
|
||||
|
||||
@@ -78,7 +78,7 @@ proc fts5c_printfile {zIn} {
|
||||
global G
|
||||
set data [readfile $zIn]
|
||||
set zTail [file tail $zIn]
|
||||
puts $G(fd) "#line 2 \"$zTail\""
|
||||
puts $G(fd) "#line 1 \"$zTail\""
|
||||
|
||||
set sub_map [list --FTS5-SOURCE-ID-- [fts5_source_id $::srcdir]]
|
||||
if {$zTail=="fts5parse.c"} {
|
||||
@@ -86,8 +86,10 @@ proc fts5c_printfile {zIn} {
|
||||
}
|
||||
|
||||
foreach line [split $data "\n"] {
|
||||
if {[regexp {^#include.*fts5} $line]} continue
|
||||
if { ![regexp { sqlite3Fts5Init\(} $line]
|
||||
if {[regexp {^#include.*fts5} $line]} {
|
||||
set line "/* $line */"
|
||||
} elseif {
|
||||
![regexp { sqlite3Fts5Init\(} $line]
|
||||
&& [regexp {^(const )?[a-zA-Z][a-zA-Z0-9]* [*]?sqlite3Fts5} $line]
|
||||
} {
|
||||
set line "static $line"
|
||||
|
||||
@@ -8,11 +8,13 @@ proc usage {} {
|
||||
puts stderr "usage: $::argv0 ?OPTIONS? database table"
|
||||
puts stderr ""
|
||||
puts stderr " -nterm (count number of terms in each segment)"
|
||||
puts stderr " -segments (output segment contents)"
|
||||
puts stderr ""
|
||||
exit 1
|
||||
}
|
||||
|
||||
set O(nterm) 0
|
||||
set O(segments) 0
|
||||
|
||||
if {[llength $argv]<2} usage
|
||||
foreach a [lrange $argv 0 end-2] {
|
||||
@@ -21,6 +23,10 @@ foreach a [lrange $argv 0 end-2] {
|
||||
set O(nterm) 1
|
||||
}
|
||||
|
||||
-segments {
|
||||
set O(segments) 1
|
||||
}
|
||||
|
||||
default {
|
||||
usage
|
||||
}
|
||||
@@ -78,6 +84,13 @@ db eval "SELECT fts5_decode(rowid, block) AS d FROM ${tbl}_data WHERE id=10" {
|
||||
}
|
||||
}
|
||||
|
||||
if {$O(segments)} {
|
||||
puts ""
|
||||
db eval "SELECT fts5_decode(rowid, block) AS d FROM ${tbl}_data WHERE id>10" {
|
||||
puts $d
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -816,10 +816,10 @@ static const char *amatchValueOfKey(const char *zKey, const char *zStr){
|
||||
int i;
|
||||
if( nStr<nKey+1 ) return 0;
|
||||
if( memcmp(zStr, zKey, nKey)!=0 ) return 0;
|
||||
for(i=nKey; isspace(zStr[i]); i++){}
|
||||
for(i=nKey; isspace((unsigned char)zStr[i]); i++){}
|
||||
if( zStr[i]!='=' ) return 0;
|
||||
i++;
|
||||
while( isspace(zStr[i]) ){ i++; }
|
||||
while( isspace((unsigned char)zStr[i]) ){ i++; }
|
||||
return zStr+i;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -486,10 +486,10 @@ static const char *closureValueOfKey(const char *zKey, const char *zStr){
|
||||
int i;
|
||||
if( nStr<nKey+1 ) return 0;
|
||||
if( memcmp(zStr, zKey, nKey)!=0 ) return 0;
|
||||
for(i=nKey; isspace(zStr[i]); i++){}
|
||||
for(i=nKey; isspace((unsigned char)zStr[i]); i++){}
|
||||
if( zStr[i]!='=' ) return 0;
|
||||
i++;
|
||||
while( isspace(zStr[i]) ){ i++; }
|
||||
while( isspace((unsigned char)zStr[i]) ){ i++; }
|
||||
return zStr+i;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1851,7 +1851,7 @@ static char *spellfix1Dequote(const char *zIn){
|
||||
char *zOut;
|
||||
int i, j;
|
||||
char c;
|
||||
while( isspace(zIn[0]) ) zIn++;
|
||||
while( isspace((unsigned char)zIn[0]) ) zIn++;
|
||||
zOut = sqlite3_mprintf("%s", zIn);
|
||||
if( zOut==0 ) return 0;
|
||||
i = (int)strlen(zOut);
|
||||
|
||||
@@ -341,6 +341,9 @@ sqlite3rbu *sqlite3rbu_open(
|
||||
** If an error has occurred, either while opening or stepping the RBU object,
|
||||
** this function may return NULL. The error code and message may be collected
|
||||
** when sqlite3rbu_close() is called.
|
||||
**
|
||||
** Database handles returned by this function remain valid until the next
|
||||
** call to any sqlite3rbu_xxx() function other than sqlite3rbu_db().
|
||||
*/
|
||||
sqlite3 *sqlite3rbu_db(sqlite3rbu*, int bRbu);
|
||||
|
||||
|
||||
+30
-6
@@ -56,20 +56,34 @@ static int test_sqlite3rbu_cmd(
|
||||
){
|
||||
int ret = TCL_OK;
|
||||
sqlite3rbu *pRbu = (sqlite3rbu*)clientData;
|
||||
const char *azMethod[] = {
|
||||
"step", "close", "create_rbu_delta", "savestate", 0
|
||||
struct RbuCmd {
|
||||
const char *zName;
|
||||
int nArg;
|
||||
const char *zUsage;
|
||||
} aCmd[] = {
|
||||
{"step", 2, ""}, /* 0 */
|
||||
{"close", 2, ""}, /* 1 */
|
||||
{"create_rbu_delta", 2, ""}, /* 2 */
|
||||
{"savestate", 2, ""}, /* 3 */
|
||||
{"dbMain_eval", 3, "SQL"}, /* 4 */
|
||||
{0,0,0}
|
||||
};
|
||||
int iMethod;
|
||||
int iCmd;
|
||||
|
||||
if( objc!=2 ){
|
||||
if( objc<2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "METHOD");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( Tcl_GetIndexFromObj(interp, objv[1], azMethod, "method", 0, &iMethod) ){
|
||||
ret = Tcl_GetIndexFromObjStruct(
|
||||
interp, objv[1], aCmd, sizeof(aCmd[0]), "method", 0, &iCmd
|
||||
);
|
||||
if( ret ) return TCL_ERROR;
|
||||
if( objc!=aCmd[iCmd].nArg ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, aCmd[iCmd].zUsage);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
switch( iMethod ){
|
||||
switch( iCmd ){
|
||||
case 0: /* step */ {
|
||||
int rc = sqlite3rbu_step(pRbu);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
|
||||
@@ -112,6 +126,16 @@ static int test_sqlite3rbu_cmd(
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: /* dbMain_eval */ {
|
||||
sqlite3 *db = sqlite3rbu_db(pRbu, 0);
|
||||
int rc = sqlite3_exec(db, Tcl_GetString(objv[2]), 0, 0, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(db), -1));
|
||||
ret = TCL_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: /* seems unlikely */
|
||||
assert( !"cannot happen" );
|
||||
break;
|
||||
|
||||
@@ -37,9 +37,6 @@
|
||||
# LIBREADLINE Linker options needed by programs using readline() must
|
||||
# link against.
|
||||
#
|
||||
# NAWK Nawk compatible awk program. Older (obsolete?) solaris
|
||||
# systems need this to avoid using the original AT&T AWK.
|
||||
#
|
||||
# Once the macros above are defined, the rest of this make script will
|
||||
# build the SQLite library and testing tools.
|
||||
################################################################################
|
||||
@@ -582,23 +579,23 @@ tclsqlite.o: $(TOP)/src/tclsqlite.c $(HDR)
|
||||
|
||||
# Rules to build opcodes.c and opcodes.h
|
||||
#
|
||||
opcodes.c: opcodes.h $(TOP)/mkopcodec.awk
|
||||
$(NAWK) -f $(TOP)/mkopcodec.awk opcodes.h >opcodes.c
|
||||
opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl
|
||||
tclsh $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c
|
||||
|
||||
opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk
|
||||
opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/tool/mkopcodeh.tcl
|
||||
cat parse.h $(TOP)/src/vdbe.c | \
|
||||
$(NAWK) -f $(TOP)/mkopcodeh.awk >opcodes.h
|
||||
tclsh $(TOP)/tool/mkopcodeh.tcl >opcodes.h
|
||||
|
||||
# Rules to build parse.c and parse.h - the outputs of lemon.
|
||||
#
|
||||
parse.h: parse.c
|
||||
|
||||
parse.c: $(TOP)/src/parse.y lemon $(TOP)/addopcodes.awk
|
||||
parse.c: $(TOP)/src/parse.y lemon $(TOP)/tool/addopcodes.tcl
|
||||
cp $(TOP)/src/parse.y .
|
||||
rm -f parse.h
|
||||
./lemon -s $(OPTS) parse.y
|
||||
mv parse.h parse.h.temp
|
||||
$(NAWK) -f $(TOP)/addopcodes.awk parse.h.temp >parse.h
|
||||
tclsh $(TOP)/tool/addopcodes.tcl parse.h.temp >parse.h
|
||||
|
||||
sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest.uuid $(TOP)/VERSION $(TOP)/ext/rtree/sqlite3rtree.h
|
||||
tclsh $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h
|
||||
@@ -712,7 +709,7 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
|
||||
cat sqlite3.c $(TOP)/src/tclsqlite.c >> $@
|
||||
echo "static const char *tclsh_main_loop(void){" >> $@
|
||||
echo "static const char *zMainloop = " >> $@
|
||||
$(NAWK) -f $(TOP)/tool/tostr.awk $(TOP)/tool/spaceanal.tcl >> $@
|
||||
tclsh $(TOP)/tool/tostr.tcl $(TOP)/tool/spaceanal.tcl >> $@
|
||||
echo "; return zMainloop; }" >> $@
|
||||
|
||||
sqlite3_analyzer$(EXE): sqlite3_analyzer.c
|
||||
@@ -758,7 +755,7 @@ fastfuzztest: fuzzcheck$(EXE) $(FUZZDATA)
|
||||
./fuzzcheck$(EXE) --limit-mem 100M $(FUZZDATA)
|
||||
|
||||
valgrindfuzz: fuzzcheck$(EXE) $(FUZZDATA)
|
||||
valgrind ./fuzzcheck$(EXE) --cell-size-check --limit-mem 10M $(FUZZDATA)
|
||||
valgrind ./fuzzcheck$(EXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA)
|
||||
|
||||
# A very quick test using only testfixture and omitting all the slower
|
||||
# tests. Designed to run in under 3 minutes on a workstation.
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
C Version\s3.9.1
|
||||
D 2015-10-16T17:31:12.550
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in f0088ff0d2ac949fce6de7c00f13a99ac5bdb663
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
F Makefile.msc 0ed934b4ae6a5ec0b9d7e770104864f8372414ab
|
||||
F Makefile.vxworks e1b65dea203f054e71653415bd8f96dcaed47858
|
||||
C Remove\s#pragma\sthat\swas\sused\sto\swork\saround\san\sobsolete\sissue\swith\sMSVC\s2012.
|
||||
D 2015-11-05T03:26:36.026
|
||||
F Makefile.in 3a705bb4bd12e194212ddbdbf068310d17153cdb
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4
|
||||
F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7
|
||||
F VERSION a47917b59f38b632b3a8662d14fd20f94956bdd0
|
||||
F VERSION 8b9d3ac6f1962f94e06ba05462422a544f9c4e36
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
F addopcodes.awk 9eb448a552d5c0185cf62c463f9c173cedae3811
|
||||
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
|
||||
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
|
||||
F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
|
||||
@@ -18,7 +15,7 @@ F autoconf/README 14458f1046c118efa721aadec5f227e876d3cd38
|
||||
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
|
||||
F autoconf/config.guess 94cc57e2a3fdb9c235b362ace86d77e89d188cad x
|
||||
F autoconf/config.sub 1efb390a8fb4bfafd74783a15a8fb5311c84300e x
|
||||
F autoconf/configure.ac a1fe4eee429fd9d3170be41941514a2b7120ba4e
|
||||
F autoconf/configure.ac bec3caf78cf1bdbaad903dcd5c6029292eda3d2d
|
||||
F autoconf/depcomp 0b26f101e3bc9fd1ff0be1da9fb4a82371142f92 x
|
||||
F autoconf/install-sh 06ee6336e63bb845c8439d777c32eb2eccc4fbf1 x
|
||||
F autoconf/ltmain.sh 7a658a24028f02331c1d2446562758083c5eadd1
|
||||
@@ -33,13 +30,13 @@ F autoconf/tea/pkgIndex.tcl.in 3ef61715cf1c7bdcff56947ffadb26bc991ca39d
|
||||
F autoconf/tea/tclconfig/install-sh bdd5e293591621ae60d9824d86a4b1c5f22c3d00
|
||||
F autoconf/tea/tclconfig/tcl.m4 66ddf0a5d5e4b1d29bff472c0985fd7fa89d0fb5
|
||||
F autoconf/tea/win/makefile.vc f89d0184d0eee5f7e356ea407964dcd139939928
|
||||
F autoconf/tea/win/nmakehlp.c 2070e086f39866b353a482d3a14dedaf26196506
|
||||
F autoconf/tea/win/nmakehlp.c 247538ad8e8c508f33c03ec1fbd67d3a07ef6291
|
||||
F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
|
||||
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
|
||||
F config.h.in 42b71ad3fe21c9e88fa59e8458ca1a6bc72eb0c0
|
||||
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
|
||||
F configure 436b5d81c66f62d5069cdf306a74845fff9e6f9f x
|
||||
F configure.ac 1e87304e51af110950c48a1eea6ffc7a577f600e
|
||||
F configure e511ceefe595e35051933a90c848ab4fa1d48add x
|
||||
F configure.ac fcfc67b323d32daaa3e46cf7782d9465ed423a6d
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1
|
||||
F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710
|
||||
@@ -51,7 +48,7 @@ F ext/async/sqlite3async.h f489b080af7e72aec0e1ee6f1d98ab6cf2e4dcef
|
||||
F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e
|
||||
F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b
|
||||
F ext/fts1/ft_hash.h 06df7bba40dadd19597aa400a875dbc2fed705ea
|
||||
F ext/fts1/fts1.c f7739dc37500a613cc0dab8fc04d1b5577d02998
|
||||
F ext/fts1/fts1.c a39f7d21c2994d27c959ef9c3505c81542c81432
|
||||
F ext/fts1/fts1.h 6060b8f62c1d925ea8356cb1a6598073eb9159a6
|
||||
F ext/fts1/fts1_hash.c 3196cee866edbebb1c0521e21672e6d599965114
|
||||
F ext/fts1/fts1_hash.h e7f0d761353996a8175eda351104acfde23afcb0
|
||||
@@ -60,7 +57,7 @@ F ext/fts1/fts1_tokenizer.h fdea722c38a9f82ed921642981234f666e47919c
|
||||
F ext/fts1/fts1_tokenizer1.c fd00d1fe4dc30dfc5c64cba695ce34f4af20d2fa
|
||||
F ext/fts1/fulltext.c 37698e1909584f6d8ea67d1485e3ad39dbf42d19
|
||||
F ext/fts1/fulltext.h 08525a47852d1d62a0be81d3fc3fe2d23b094efd
|
||||
F ext/fts1/simple_tokenizer.c 1844d72f7194c3fd3d7e4173053911bf0661b70d
|
||||
F ext/fts1/simple_tokenizer.c bbfa4e3b2a26ef17d4edc6d98cd4a3f5396d998a
|
||||
F ext/fts1/tokenizer.h 0c53421b832366d20d720d21ea3e1f6e66a36ef9
|
||||
F ext/fts2/README.tokenizers 21e3684ea5a095b55d70f6878b4ce6af5932dfb7
|
||||
F ext/fts2/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
|
||||
@@ -106,25 +103,25 @@ 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 8b9a13b309b180e9fb88ea5666c0d8d73c6102d9
|
||||
F ext/fts5/fts5Int.h 38667e39859ff3f3bc91f47efe672023a145a118
|
||||
F ext/fts5/fts5_aux.c b09aa27dcdaa3d50a30be433fddaa48a50aa827b
|
||||
F ext/fts5/fts5_buffer.c e99224a316cc5b2c574ccccdc7f2344bca54784d
|
||||
F ext/fts5/fts5_config.c 57ee5fe71578cb494574fc0e6e51acb9a22a8695
|
||||
F ext/fts5/fts5_expr.c bc31478fd04de55150031f6e6a652939d3e335ac
|
||||
F ext/fts5/fts5_hash.c 4bf4b99708848357b8a2b5819e509eb6d3df9246
|
||||
F ext/fts5/fts5_index.c f73968357818455039ecb79dcd4b082c3baaeaeb
|
||||
F ext/fts5/fts5_main.c bf43550b8e9a68514abd179500f1917a2256cd7a
|
||||
F ext/fts5/fts5_storage.c df061a5caf9e50fbbd43113009b5b248362f4995
|
||||
F ext/fts5/fts5Int.h 06594fd3e5a3c74da6df9141e165975dc0ea6ef4
|
||||
F ext/fts5/fts5_aux.c 1f384972d606375b8fa078319f25ab4b5feb1b35
|
||||
F ext/fts5/fts5_buffer.c 1e49512a535045e621246dc7f4f65f3593fa0fc2
|
||||
F ext/fts5/fts5_config.c 88a77f5d5e4dfbb2355b8f6cc9969b7f02d94685
|
||||
F ext/fts5/fts5_expr.c 28b15c9ae296204bc0a2e5cf7a667d840a9d2900
|
||||
F ext/fts5/fts5_hash.c a9d4c1efebc2a91d26ad7ebdfcbf2678ceac405f
|
||||
F ext/fts5/fts5_index.c 356481ce027cc2ede8e462c316b578260cda29d2
|
||||
F ext/fts5/fts5_main.c 39358d3d8f0d6ea3757c40e0ddcbb6bc435604c3
|
||||
F ext/fts5/fts5_storage.c 9ea3d92178743758b6c54d9fe8836bbbdcc92e3b
|
||||
F ext/fts5/fts5_tcl.c 3bf445e66de32137d4693694ff7b1fd6074e32bd
|
||||
F ext/fts5/fts5_test_mi.c e96be827aa8f571031e65e481251dc1981d608bf
|
||||
F ext/fts5/fts5_tokenize.c f380f46f341af9c9a9908e1aade685ba1eaa157a
|
||||
F ext/fts5/fts5_tokenize.c 12c5d925286491a71bb3dad7c8924ce9cfd18320
|
||||
F ext/fts5/fts5_unicode2.c 78273fbd588d1d9bd0a7e4e0ccc9207348bae33c
|
||||
F ext/fts5/fts5_varint.c 3f86ce09cab152e3d45490d7586b7ed2e40c13f1
|
||||
F ext/fts5/fts5_vocab.c a05027ab6abb692ad27654c85137a4f1061a159e
|
||||
F ext/fts5/fts5_vocab.c 3742d0abfe8aa8c3cb4a7df56aa38f2e3c3fb1c2
|
||||
F ext/fts5/fts5parse.y e83dca6028e3309178d05b5bd920e372dc295d35
|
||||
F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba
|
||||
F ext/fts5/test/fts5_common.tcl 51f7ef3af444b89c6f6ce3896a0ac349ff4e996d
|
||||
F ext/fts5/test/fts5aa.test 4804f237005bb4ba8ea4a76120d8011ebcb5d611
|
||||
F ext/fts5/test/fts5aa.test 2c553eea4dab4bc5a75928f56729277c7bc1d206
|
||||
F ext/fts5/test/fts5ab.test 6fe3a56731d15978afbb74ae51b355fc9310f2ad
|
||||
F ext/fts5/test/fts5ac.test 9737992d08c56bfd4803e933744d2d764e23795c
|
||||
F ext/fts5/test/fts5ad.test e3dfb150fce971b4fd832498c29f56924d451b63
|
||||
@@ -143,10 +140,11 @@ F ext/fts5/test/fts5auxdata.test 141a7cbffcceb1bd2799b4b29c183ff8780d586e
|
||||
F ext/fts5/test/fts5bigpl.test 04ee0d7eebbebf17c31f5a0b5c5f9494eac3a0cb
|
||||
F ext/fts5/test/fts5columnsize.test a8cfef21ffa1c264b9f670a7d94eeaccb5341c07
|
||||
F ext/fts5/test/fts5config.test ad2ff42ddc856aed2d05bf89dc1c578c8a39ea3b
|
||||
F ext/fts5/test/fts5conflict.test 26f4e46c4d31e16221794832a990dc4e30e18de5
|
||||
F ext/fts5/test/fts5content.test 9a952c95518a14182dc3b59e3c8fa71cda82a4e1
|
||||
F ext/fts5/test/fts5corrupt.test c2ad090192708150d50d961278df10ae7a4b8b62
|
||||
F ext/fts5/test/fts5corrupt2.test 26c0a39dd9ff73207e6229f83b50b21d37c7658c
|
||||
F ext/fts5/test/fts5corrupt3.test a1429635c30f922079189e35b2b631eb7463a2fb
|
||||
F ext/fts5/test/fts5corrupt3.test a2b537c120bdd43c79c42fe2438d7b8c81fe5599
|
||||
F ext/fts5/test/fts5dlidx.test ecba5e62ea8b26c33829961602069c546228046d
|
||||
F ext/fts5/test/fts5doclist.test 8edb5b57e5f144030ed74ec00ef6fa4294fed79b
|
||||
F ext/fts5/test/fts5ea.test b01e3a18cdfabbff8104a96a5242a06a68a998a0
|
||||
@@ -155,12 +153,12 @@ F ext/fts5/test/fts5fault1.test 7a562367cb4a735b57b410dbdb62dcc8d971faec
|
||||
F ext/fts5/test/fts5fault2.test 28c36c843bb39ae855ba79827417ecc37f114341
|
||||
F ext/fts5/test/fts5fault3.test d6e9577d4312e331a913c72931bf131704efc8f3
|
||||
F ext/fts5/test/fts5fault4.test 762991d526ee67c2b374351a17248097ea38bee7
|
||||
F ext/fts5/test/fts5fault5.test 54da9fd4c3434a1d4f6abdcb6469299d91cf5875
|
||||
F ext/fts5/test/fts5fault5.test f2b8645053d48982e8979749e93994c43011c118
|
||||
F ext/fts5/test/fts5fault6.test 9682664d679643ac6736e90c225526cc84073cda
|
||||
F ext/fts5/test/fts5fault7.test f62ed4d98f137eb03f1db94d1fa41b17a771d971
|
||||
F ext/fts5/test/fts5fault7.test 01be274bfc8d9bf22451a3bf5892e9399d044f1b
|
||||
F ext/fts5/test/fts5full.test 6f6143af0c6700501d9fd597189dfab1555bb741
|
||||
F ext/fts5/test/fts5hash.test 42eb066f667e9a389a63437cb7038c51974d4fc6
|
||||
F ext/fts5/test/fts5integrity.test 29f41d2c7126c6122fbb5d54e556506456876145
|
||||
F ext/fts5/test/fts5hash.test 7cf4607b8657c383f0b520668a99971e95d8b139
|
||||
F ext/fts5/test/fts5integrity.test 87db5d4e7da0ce04a1dcba5ba91658673c997a65
|
||||
F ext/fts5/test/fts5matchinfo.test 2163b0013e824bba65499da9e34ea4da41349cc2
|
||||
F ext/fts5/test/fts5merge.test 8f3cdba2ec9c5e7e568246e81b700ad37f764367
|
||||
F ext/fts5/test/fts5near.test b214cddb1c1f1bddf45c75af768f20145f7e71cc
|
||||
@@ -170,12 +168,13 @@ F ext/fts5/test/fts5phrase.test f6d1d464da5beb25dc56277aa4f1d6102f0d9a2f
|
||||
F ext/fts5/test/fts5plan.test 6a55ecbac9890765b0e16f8c421c7e0888cfe436
|
||||
F ext/fts5/test/fts5porter.test 7cdc07bef301d70eebbfa75dcaf45c3680e1d0e1
|
||||
F ext/fts5/test/fts5porter2.test 2e65633d58a1c525d5af0f6c01e5a59155bb3487
|
||||
F ext/fts5/test/fts5prefix.test ad3069f099ff593a2196422244fa218f8942dfb9
|
||||
F ext/fts5/test/fts5prefix.test 7ccbdf180ed561a912acef520519e85af8642239
|
||||
F ext/fts5/test/fts5query.test f5ec25f5f2fbb70033424113cdffc101b1985a40
|
||||
F ext/fts5/test/fts5rank.test 11dcebba31d822f7e99685b4ea2c2ae3ec0b16f1
|
||||
F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b
|
||||
F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17
|
||||
F ext/fts5/test/fts5rowid.test 400384798349d658eaf06aefa1e364957d5d4821
|
||||
F ext/fts5/test/fts5simple.test f8463172dc2d4bf9f74c78e9df9c83e942c63a94
|
||||
F ext/fts5/test/fts5simple.test 41333e267c6145efc3620342af53dfe65d5676b7
|
||||
F ext/fts5/test/fts5synonym.test cf88c0a56d5ea9591e3939ef1f6e294f7f2d0671
|
||||
F ext/fts5/test/fts5tokenizer.test ea4df698b35cc427ebf2ba22829d0e28386d8c89
|
||||
F ext/fts5/test/fts5unicode.test fbef8d8a3b4b88470536cc57604a82ca52e51841
|
||||
@@ -183,16 +182,16 @@ F ext/fts5/test/fts5unicode2.test c1dd890ba32b7609adba78e420faa847abe43b59
|
||||
F ext/fts5/test/fts5unicode3.test 35c3d02aa7acf7d43d8de3bfe32c15ba96e8928e
|
||||
F ext/fts5/test/fts5unindexed.test e9539d5b78c677315e7ed8ea911d4fd25437c680
|
||||
F ext/fts5/test/fts5version.test 978f59541d8cef7e8591f8be2115ec5ccb863e2e
|
||||
F ext/fts5/test/fts5vocab.test cdf97b9678484e9bad5062edf9c9106e5c3b0c5c
|
||||
F ext/fts5/tool/fts5txt2db.tcl 3d19fb8ffb234031d33d7d2151acfbc55e9cfcc4
|
||||
F ext/fts5/test/fts5vocab.test c88a5554d0409494da95ba647bbdb4879b2624b0
|
||||
F ext/fts5/tool/fts5txt2db.tcl c374c4c4797e8cdfadabdfaeeb5412dcd6686e84
|
||||
F ext/fts5/tool/loadfts5.tcl 58e90407cc5c2b1770460119488fd7c0090d4dd3
|
||||
F ext/fts5/tool/mkfts5c.tcl 09ce6a7997440508360f5ba1651ab7e923a8bf31
|
||||
F ext/fts5/tool/showfts5.tcl 9eaf6c3df352f98a2ab5ce1921dd94128ab1381d
|
||||
F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45
|
||||
F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c
|
||||
F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43
|
||||
F ext/icu/icu.c b2732aef0b076e4276d9b39b5a33cec7a05e1413
|
||||
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
|
||||
F ext/misc/amatch.c 27b9b601fb1453084e18a3432ea0240d7af8decb
|
||||
F ext/misc/closure.c 636024302cde41b2bf0c542f81c40c624cfb7012
|
||||
F ext/misc/amatch.c a1a8f66c29d40bd71b075546ddeddb477b17a2bb
|
||||
F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704
|
||||
F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83
|
||||
F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
|
||||
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
|
||||
@@ -205,7 +204,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 86998fb73aefb7b5dc346ba8a58912f312da4996
|
||||
F ext/misc/spellfix.c b9065af7ab1f2597b505a8aa9892620866d502fc
|
||||
F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
|
||||
F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
|
||||
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
|
||||
@@ -233,8 +232,8 @@ F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06
|
||||
F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda
|
||||
F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48
|
||||
F ext/rbu/sqlite3rbu.c ea47de615e911b3a69a8e7fb3be3866298403a25
|
||||
F ext/rbu/sqlite3rbu.h 1d568cb33738d7900975cc5c72e6f68049f15914
|
||||
F ext/rbu/test_rbu.c 2a3652241fa45d5eaa141775e4ae68c1d3582c03
|
||||
F ext/rbu/sqlite3rbu.h 0bdeb3be211aaba7d85445fa36f4701a25a3dbde
|
||||
F ext/rbu/test_rbu.c 4a4cdcef4ef9379fc2a21f008805c80b27bcf573
|
||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||
F ext/rtree/rtree.c 0f9b595bd0debcbedf1d7a63d0e0678d619e6c9c
|
||||
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
|
||||
@@ -264,15 +263,13 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||
F main.mk 645d30a780fb304cf7fa79537b78728e32dd46fc
|
||||
F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea
|
||||
F mkopcodeh.awk 0e7f04a8eb90f92259e47d80110e4e98d7ce337a
|
||||
F main.mk ac9746f24334056c85775dbe6b7279b84a6941d7
|
||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421
|
||||
F mptest/crash02.subtest f4ef05adcd15d60e5d2bd654204f2c008b519df8
|
||||
F mptest/mptest.c fca59f0a922e03f95ed17c44b1515ed37a841c81
|
||||
F mptest/mptest.c e7b499cb0cf8c3de65eaf24dec9b36daa4e013e4
|
||||
F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d
|
||||
F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
|
||||
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
@@ -282,20 +279,20 @@ F src/alter.c 9d649e46c780166e416fb11dbd23f8d49aab8267
|
||||
F src/analyze.c 4c308880cf53c558070cb8513bdff4ffb1a38a77
|
||||
F src/attach.c e944d0052b577703b9b83aac1638452ff42a8395
|
||||
F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
|
||||
F src/backup.c c3a9c4209439b806c44cf30daf466955727bf46c
|
||||
F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc
|
||||
F src/bitvec.c d1f21d7d91690747881f03940584f4cc548c9d3d
|
||||
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
|
||||
F src/btree.c 0b74bc28b2dc907cba03b5b4b3b81584273be699
|
||||
F src/btree.h 40189aefdc2b830d25c8b58fd7d56538481bfdd7
|
||||
F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0
|
||||
F src/build.c d6162335d690396dfc5c4bd59e8b2b0c14ba6285
|
||||
F src/btree.c 233c1536927b12d820cb0a19c657c59837f9334f
|
||||
F src/btree.h b512723e4f27d7ba16b4b985cdecdb82c0f6d0c0
|
||||
F src/btreeInt.h 3ab435ed27adea54d040584b0bcc488ee7db1e38
|
||||
F src/build.c ca574d33ffb1763cfd2979383f4d507095bfbe19
|
||||
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
|
||||
F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
|
||||
F src/ctime.c 509ef9c64d1321f42448f111da86400b1799218a
|
||||
F src/date.c fb1c99172017dcc8e237339132c91a21a0788584
|
||||
F src/dbstat.c e637e7a7ff40ef32132a418c6fdf1cfb63aa27c7
|
||||
F src/delete.c 35c939eb8bacc9dd8a6715964e5f69feb8c20e44
|
||||
F src/expr.c b89dfbb8a385a45411c487355597c01f4ea4c882
|
||||
F src/dbstat.c ffd63fc8ba7541476ced189b95e95d7f2bc63f78
|
||||
F src/delete.c c4c6fb9da78b946fcba2a6aac5b24bc5c15e752a
|
||||
F src/expr.c 0080c0f12806eca91e75a23a121a68918e9da357
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c 31900763094a3736a5fc887469202eb579fef2d0
|
||||
F src/func.c ecdd69ec6a1e406f04cc73324be2ebbf6354197f
|
||||
@@ -303,18 +300,18 @@ F src/global.c 508e4087f7b41d688e4762dcf4d4fe28cfbc87f9
|
||||
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
|
||||
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
|
||||
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||
F src/insert.c 3c522beb5bf50a2efee1fca1e80fd40942e5817c
|
||||
F src/insert.c 419a947f27ce2da18eebf440a5aa80cc825defae
|
||||
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
||||
F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
|
||||
F src/lempar.c d344a95d60c24e2f490ee59db9784b1b17439012
|
||||
F src/loadext.c c5916a158f1fb74d955847c84f7ebdb6f5de9d8c
|
||||
F src/main.c fec97668771438033a7559883401067b139729e1
|
||||
F src/malloc.c 3a37ce6979a40f499d8cea9e9ab4e8517854d35d
|
||||
F src/loadext.c 18586e45a215325f15096821e9c082035d4fb810
|
||||
F src/main.c f393acc6e5d604cbe0054376d62f668a5560b3f1
|
||||
F src/malloc.c 337bbe9c7d436ef9b7d06b5dd10bbfc8f3025972
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c abe6ee469b6c5a35c7f22bfeb9c9bac664a1c987
|
||||
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
|
||||
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
|
||||
F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534
|
||||
F src/mem5.c 61eeb90134f9a5be6c2e68d8daae7628b25953fb
|
||||
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
|
||||
F src/mem5.c c1ab1153bd6443bdf6f71e4213c6fb31221b9eb7
|
||||
F src/memjournal.c 3eb2c0b51adbd869cb6a44780323f05fa904dc85
|
||||
F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495
|
||||
F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c
|
||||
@@ -327,35 +324,35 @@ 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 fc93d55f96bb978f0b0168c6ea7d6fc60b0e172c
|
||||
F src/os_unix.c cf72e06e15839ebe7121e01d3eebf256c039b0ca
|
||||
F src/os_win.c 1716291e5ec2dbfc5a1fe0b32182030f1f7d8acf
|
||||
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
||||
F src/pager.c 2fbeeba28f4e6d08a15bc106f36c43346a81f09e
|
||||
F src/pager.h ac213f8143ebfee6a8bfb91cf4ca02c9a83343c5
|
||||
F src/parse.y f599aa5e871a493330d567ced93de696f61f48f7
|
||||
F src/pager.c ed5cff11793b6a4146582aabb29ed8613a6cf89e
|
||||
F src/pager.h 7fc069c07f3120ee466ff3d48a9d376974ebffa7
|
||||
F src/parse.y 11078cd8e3af00f030505b6a86a06a4536cfdeaa
|
||||
F src/pcache.c 24be750c79272e0ca7b6e007bc94999700f3e5ef
|
||||
F src/pcache.h 9968603796240cdf83da7e7bef76edf90619cea9
|
||||
F src/pcache1.c e822007159d53a7ea7aa040d6e28964ddb6de083
|
||||
F src/pragma.c dcfe3a35d2de935feeaba1455528b4a5c4f1208c
|
||||
F src/pcache1.c 902e1bc7bdaa81b40f8543407c5e2ac8ef4dc035
|
||||
F src/pragma.c 8fd4c8a12e25f0d916426f160255ebe25415eba7
|
||||
F src/pragma.h 631a91c8b0e6ca8f051a1d8a4a0da4150e04620a
|
||||
F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1
|
||||
F src/printf.c 0c4bcdd1c2e2521024f0a69cb5eb334f86b3652a
|
||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||
F src/resolve.c 1954a0f01bf65d78d7d559aea3d5c67f33376d91
|
||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||
F src/select.c 0bc9cd2e1cacfdc9cdc9a83884cc100f166e80a4
|
||||
F src/select.c 167b4e9058bc8e997d18d6b6b20ecbb0c9c457af
|
||||
F src/shell.c d25df04168d6ba5a4fa05bdbf859df667f9eb621
|
||||
F src/sqlite.h.in dc35357824c6bb84a04acd4e99dee3e07299a8c6
|
||||
F src/sqlite.h.in 3cfc86c55e57c63d86b9e1e92869e2bfb162ca8e
|
||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||
F src/sqlite3ext.h 4b66e3e3435da4b4c8c83696d0349f0c503b3924
|
||||
F src/sqliteInt.h e21cc96bc24161df7373f6b24367cf580496889d
|
||||
F src/sqliteInt.h b1e72ffe282c91ae30a2bf403319126dbaebd556
|
||||
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
|
||||
F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
|
||||
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
|
||||
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
|
||||
F src/tclsqlite.c d9439b6a910985b7fff43ba6756bcef00de22649
|
||||
F src/test1.c 8fff9c5aa63d6490f516d018b70c12a9cb9a4d8a
|
||||
F src/test2.c 577961fe48961b2f2e5c8b56ee50c3f459d3359d
|
||||
F src/test3.c 64d2afdd68feac1bb5e2ffb8226c8c639f798622
|
||||
F src/test1.c 9ac5cbfe3c859ab7518edc5109a2959d6bf7b059
|
||||
F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b
|
||||
F src/test3.c a8887dabbbee3059af338f20d290084a63ed1b0f
|
||||
F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e
|
||||
F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1
|
||||
F src/test6.c 41cacf3b0dd180823919bf9e1fbab287c9266723
|
||||
@@ -367,7 +364,7 @@ F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12
|
||||
F src/test_backup.c 2e6e6a081870150f20c526a2e9d0d29cda47d803
|
||||
F src/test_blob.c e5a7a81d61a780da79101aeb1e60d300af169e07
|
||||
F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f
|
||||
F src/test_config.c ada6f38b0acb6722fb7f0ed8c54fd66df41085b9
|
||||
F src/test_config.c 426527fbb12fc23669a1e973ecdc8c5e92c2e2cf
|
||||
F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852
|
||||
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
|
||||
F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f
|
||||
@@ -399,30 +396,30 @@ F src/test_vfs.c 3b65d42e18b262805716bd96178c81da8f2d9283
|
||||
F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c bbfb74450643cb5372a43ad4f6cffd7e9dfcecb0
|
||||
F src/tokenize.c 83c6ed569423a3af83a83973b444cf7123be33a6
|
||||
F src/tokenize.c 338bc8f7c9dd103188952cda7964696bacac6d22
|
||||
F src/treeview.c 154f0acc622fa3514de8777dcedf4c8a8802b4ce
|
||||
F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f
|
||||
F src/update.c dc37664095ca8604293ff1de2d9a547c6efb5e6e
|
||||
F src/update.c 40e51cd0883cb5bfd6abb7d8a7cd8aa47fab2945
|
||||
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
|
||||
F src/util.c fc612367108b74573c5fd13a85d0a23027f438bd
|
||||
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
|
||||
F src/vdbe.c 1e0bf8d6a2308ce916d444ef399921407fd5d972
|
||||
F src/vdbe.h 4bc88bd0e06f8046ee6ab7487c0015e85ad949ad
|
||||
F src/vdbeInt.h 8b867eac234e28627ffcace3cd4b4b79bbec664b
|
||||
F src/vdbe.c dfbaae2570172c523bce14299021d352b8508f7f
|
||||
F src/vdbe.h efb7a8c1459e31f3ea4377824c6a7e4cb5068637
|
||||
F src/vdbeInt.h 33403622c6a8feaaac5f0f3f17f5d1bf6df42286
|
||||
F src/vdbeapi.c 020681b943e77766b32ae1cddf86d7831b7374ca
|
||||
F src/vdbeaux.c fd00b489ab3f44f2dca1e4344faf289b7bfcf649
|
||||
F src/vdbeaux.c 717bc2ae9cc0b58ef398fff44bd9164bfd96772a
|
||||
F src/vdbeblob.c 565fabd302f5fca3bdf3d56cac330483616a39b6
|
||||
F src/vdbemem.c 19b3036aa4d676e7103b0fb5efd6327da455f915
|
||||
F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b
|
||||
F src/vdbemem.c fdd1578e47bea61390d472de53c565781d81e045
|
||||
F src/vdbesort.c 8b23930a1289526f6d2a3a9f2e965bcc963e4a68
|
||||
F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0
|
||||
F src/vtab.c 2a8b44aa372c33f6154208e7a7f6c44254549806
|
||||
F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
|
||||
F src/wal.c 18b0ed49830cf04fe2d68224b41838a73ac6cd24
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba
|
||||
F src/where.c 4c4646675e794ac71e701289edefd7cd81bac844
|
||||
F src/where.c 6aceb72cc58dc06922a9e1604d559c8ca4c3e728
|
||||
F src/whereInt.h 7892bb54cf9ca0ae5c7e6094491b94c9286dc647
|
||||
F src/wherecode.c cdfff200d065e7fb1af827b3274ed46b10a91d65
|
||||
F src/wherecode.c 4c96182e7b25e4be54008dee2da5b9c2f8480b9b
|
||||
F src/whereexpr.c e63244ca06c503e5f3c5b7f3c9aea0db826089ed
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
||||
@@ -470,7 +467,7 @@ F test/autoindex1.test 14b63a9f1e405fe6d5bfc8c8d00249c2ebaf13ea
|
||||
F test/autoindex2.test af7e595c6864cc6ef5fc38d5db579a3e34940cb8
|
||||
F test/autoindex3.test a3be0d1a53a7d2edff208a5e442312957047e972
|
||||
F test/autoindex4.test 49d3cd791a9baa16fb461d7ea3de80d019a819cf
|
||||
F test/autoindex5.test 6f487290ce2a667c24517191651bfb8c7d86b6dc
|
||||
F test/autoindex5.test 96f084a5e6024ea07cace5888df3223f3ea86990
|
||||
F test/autovacuum.test 941892505d2c0f410a0cb5970dfa1c7c4e5f6e74
|
||||
F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
|
||||
F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85
|
||||
@@ -483,7 +480,7 @@ F test/backup_ioerr.test 4c3c7147cee85b024ecf6e150e090c32fdbb5135
|
||||
F test/backup_malloc.test 7162d604ec2b4683c4b3799a48657fb8b5e2d450
|
||||
F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f
|
||||
F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f
|
||||
F test/bc_common.tcl 5c8689cc6d2fb44b7c0968ae4f85eb26d50022fa
|
||||
F test/bc_common.tcl 3eda41ef9cda7d5f6c205462c96228b301da4191
|
||||
F test/between.test 34d375fb5ce1ae283ffe82b6b233e9f38e84fc6c
|
||||
F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59
|
||||
F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc
|
||||
@@ -506,6 +503,7 @@ F test/btree02.test fe69453d474d8154d19b904157ff1db4812fed99
|
||||
F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3
|
||||
F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0
|
||||
F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de
|
||||
F test/cacheflush.test a755c93482ce2e20c04825304bef27e7b7ea0111
|
||||
F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738
|
||||
F test/capi3.test bf6f0308bbbba1e770dac13aa08e5c2ac61c7324
|
||||
F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
|
||||
@@ -513,6 +511,7 @@ F test/capi3c.test fdc0d67a2cb8e8fc400d5b7735e330161ea057a2
|
||||
F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82
|
||||
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
|
||||
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
|
||||
F test/cffault.test 1647eef45512817265c360ed4539538eed26ac69
|
||||
F test/check.test 5831ddb6f2c687782eaf2e1a07b6e17f24c4f763
|
||||
F test/close.test 340bd24cc58b16c6bc01967402755027c37eb815
|
||||
F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4
|
||||
@@ -568,6 +567,7 @@ F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
|
||||
F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8
|
||||
F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
|
||||
F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47
|
||||
F test/cursorhint.test 432811b62bd5ffb812729f49bba3b9ad687550bb
|
||||
F test/date.test 42973251b9429f2c41b77eb98a7b0b0ba2d3b2c0
|
||||
F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204
|
||||
F test/dbstatus2.test 10418e62b3db5dca070f0c3eef3ea13946f339c2
|
||||
@@ -601,7 +601,7 @@ F test/e_select.test 52692ff3849541e828ad4661fe3773a9b8711763
|
||||
F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f
|
||||
F test/e_totalchanges.test b12ee5809d3e63aeb83238dd501a7bca7fd72c10
|
||||
F test/e_update.test f46c2554d915c9197548681e8d8c33a267e84528
|
||||
F test/e_uri.test 5ae33760fb2039c61aa2d90886f1664664173585
|
||||
F test/e_uri.test eed3eb41b22d051a1164110dacdc778899126e14
|
||||
F test/e_vacuum.test 5bfbdc21b65c0abf24398d0ba31dc88d93ca77a9
|
||||
F test/e_wal.test ae9a593207a77d711443ee69ffe081fda9243625
|
||||
F test/e_walauto.test 280714ddf14e1a47dcbc59d515cd0b026dfd5567
|
||||
@@ -633,6 +633,7 @@ F test/fkey6.test abb59f866c1b44926fd02d1fdd217d831fe04f48
|
||||
F test/fkey7.test 72e915890ee4a005daaf3002cb208e8fe973ac13
|
||||
F test/fkey8.test 8f08203458321e6c19a263829de4cfc936274ab0
|
||||
F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749
|
||||
F test/fordelete.test ba12ec1d27cc34a4c23db4446029126d773f3849
|
||||
F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb
|
||||
F test/fts-9fd058691.test 78b887e30ae6816df0e1fed6259de4b5a64ad33c
|
||||
F test/fts1a.test 46090311f85da51bb33bd5ce84f7948359c6d8d7
|
||||
@@ -753,7 +754,7 @@ F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1
|
||||
F test/fuzz3.test 53fabcd5f0f430f8b221282f6c12c4d0903c21eb
|
||||
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
|
||||
F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
|
||||
F test/fuzzcheck.c c84086021a514360268190a1bc6ae8ed78d7c94f
|
||||
F test/fuzzcheck.c ee926f1d4090d053ed542899720d4e4d30811bcc
|
||||
F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664
|
||||
F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973
|
||||
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
|
||||
@@ -783,7 +784,7 @@ F test/incrvacuum3.test 75256fb1377e7c39ef2de62bfc42bbff67be295a
|
||||
F test/incrvacuum_ioerr.test 6ae2f783424e47a0033304808fe27789cf93e635
|
||||
F test/index.test fe3c7a1aad82af92623747e9c3f3aa94ccd51238
|
||||
F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407
|
||||
F test/index3.test fa3e49bbaa4f38091c9c742e36a1abe67c4ef1fc
|
||||
F test/index3.test 81bc47890b8abfb181bc35f8d10b56c069803386
|
||||
F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6
|
||||
F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7
|
||||
F test/index6.test 7102ec371414c42dfb1d5ca37eb4519aa9edc23a
|
||||
@@ -820,7 +821,7 @@ F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307
|
||||
F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa
|
||||
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
|
||||
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
|
||||
F test/json101.test 83e6ebfb3cef6329853ab854403ec82b1787b537
|
||||
F test/json101.test f0178422b3a2418f423fd0d3caf3571c8d1b9863
|
||||
F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a
|
||||
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
|
||||
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
|
||||
@@ -912,7 +913,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 14fec2796c2b6fe431c7823750e8a18a761176d7
|
||||
F test/oserror.test 361346396ae18462c7393c1ac5c3f17237bd89b2
|
||||
F test/ovfl.test 4f7ca651cba5c059a12d8c67dddd49bec5747799
|
||||
F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa
|
||||
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
|
||||
@@ -927,7 +928,7 @@ F test/parser1.test 222b5cbf3e2e659fec1bf7d723488c8b9c94f1d0
|
||||
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
|
||||
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
|
||||
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
|
||||
F test/permutations.test ac3b00c299250cc087d4a527b5c75a0f8aef4e54
|
||||
F test/permutations.test 0be620cfc7309d72b0608b3f1cbadef1034417fa
|
||||
F test/pragma.test a44253f911e7d50127d4a08f927f47c861a4c772
|
||||
F test/pragma2.test b5e2ce4c892afceb308c6ae6163a9099b2a0d8d7
|
||||
F test/pragma3.test 6f849ccffeee7e496d2f2b5e74152306c0b8757c
|
||||
@@ -947,7 +948,7 @@ F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736
|
||||
F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8
|
||||
F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
|
||||
F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
|
||||
F test/releasetest.tcl 67a82199e6ddee609211488bc04ed3f9ea3aa28a
|
||||
F test/releasetest.tcl c12c4122a7b2ddec16b5f8fb9163f7a008886005
|
||||
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
|
||||
F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea
|
||||
F test/rollback2.test fc14cf6d1a2b250d2735ef16124b971bce152f14
|
||||
@@ -1031,7 +1032,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523
|
||||
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
|
||||
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
|
||||
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
|
||||
F test/speedtest1.c 857439869d1cb4db35e1c720ee9c2756eb9ea2a0
|
||||
F test/speedtest1.c f8bf04214e7b5f745feea99f7bde68b1c4870666
|
||||
F test/spellfix.test 0597065ff57042df1f138e6a2611ae19c2698135
|
||||
F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3
|
||||
F test/sqldiff1.test 8f6bc7c6a5b3585d350d779c6078869ba402f8f5
|
||||
@@ -1045,8 +1046,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 2513f7c030df0f435c6415687ba8b739f3d312df
|
||||
F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85
|
||||
F test/syscall.test d2fdaad713f103ac611fe7ef9b724c7b69f8149c
|
||||
F test/syscall.test fba9ebdc6905d05bba6a835e691f20ed9ea2cc88
|
||||
F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6
|
||||
F test/tabfunc01.test 03c4ad422c6ab596cff6dcaf86dd061a9f039525
|
||||
F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f
|
||||
@@ -1334,25 +1336,30 @@ F test/without_rowid3.test aad4f9d383e199349b6c7e508a778f7dff5dff79
|
||||
F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a
|
||||
F test/without_rowid5.test 61256715b686359df48ca1742db50cc7e3e7b862
|
||||
F test/without_rowid6.test 1f99644e6508447fb050f73697350c7ceca3392e
|
||||
F test/wordcount.c 9915e06cb33d8ca8109b8700791afe80d305afda
|
||||
F test/wordcount.c 2a0a6c0d0e8e8bbbac1f06d72a6791828c37c0cf
|
||||
F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa
|
||||
F test/zerodamage.test cf6748bad89553cc1632be51a6f54e487e4039ac
|
||||
F tool/build-all-msvc.bat 761d8c82a1a529261291812732a853a1b4256d85 x
|
||||
F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5
|
||||
F tool/GetTclKit.bat 8606413d3035c05373a0d7fae82ebf59ae9e16c3
|
||||
F tool/addopcodes.tcl 26892c394964c194fe96b9a79b8b9f87347c7151
|
||||
F tool/build-all-msvc.bat e42141ca3c3812315432f9813ef9eb78aa8d99c9 x
|
||||
F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367
|
||||
F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2
|
||||
F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2
|
||||
F tool/fast_vacuum.c 5ba0d6f5963a0a63bdc42840f678bad75b2ebce1
|
||||
F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439
|
||||
F tool/fuzzershell.c b36096cdbcb4af985a2d6c20093d61e55b49bfe1
|
||||
F tool/fuzzershell.c 94019b185caceffc9f7c7b678a6489e42bc2aefa
|
||||
F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4
|
||||
F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5
|
||||
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
|
||||
F tool/lemon.c 039f813b520b9395740c52f9cbf36c90b5d8df03
|
||||
F tool/lemon.c 799e73e19a33b8dd7767a7fa34618ed2a9c2397d
|
||||
F tool/lempar.c 3617143ddb9b176c3605defe6a9c798793280120
|
||||
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
|
||||
F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6
|
||||
F tool/mkautoconfamal.sh d1a2da0e15b2ed33d60af35c7e9d483f13a8eb9f
|
||||
F tool/mkautoconfamal.sh 4bdf61548a143e5977bd86ab93d68b694d10c8fa
|
||||
F tool/mkkeywordhash.c dfff09dbbfaf950e89af294f48f902181b144670
|
||||
F tool/mkopcodec.tcl edde8adc42621b5e598127f8cdc6d52cfe21f52b
|
||||
F tool/mkopcodeh.tcl e04177031532b7aa9379ded50e820231ac4abd6e
|
||||
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
|
||||
F tool/mkpragmatab.tcl 84af2b180484323a2ea22a2279e8bd9e3e1e492e
|
||||
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
||||
@@ -1364,36 +1371,37 @@ F tool/mkvsix.tcl bbe57cd9ae11c6cc70319241101ef8d2b8c3765b
|
||||
F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091
|
||||
F tool/omittest.tcl 34d7ac01fe4fd18e3637f64abe12c40eca0f6b97
|
||||
F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b
|
||||
F tool/replace.tcl 7727c60a04299b65a92f5e1590896fea0f25b9e0
|
||||
F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
|
||||
F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5
|
||||
F tool/showdb.c b1e16174385d5bd0815823a7fda1ecc82ed6088b
|
||||
F tool/showjournal.c 053eb1cc774710c6890b7dd6293300cc297b16a5
|
||||
F tool/showdb.c d4476e000a64eca9f5e2c2f68741e747b9778e8d
|
||||
F tool/showjournal.c 5bad7ae8784a43d2b270d953060423b8bd480818
|
||||
F tool/showlocks.c 9920bcc64f58378ff1118caead34147201f48c68
|
||||
F tool/showstat4.c 9515faa8ec176599d4a8288293ba8ec61f7b728a
|
||||
F tool/showwal.c 85cb36d4fe3e93e2fbd63e786e0d1ce42d0c4fad
|
||||
F tool/showstat4.c bda40d6e395df7edb6e9ea630784d3d762c35b4b
|
||||
F tool/showwal.c ec79959834f7b21f1e0a2aa52bb7c056d2203977
|
||||
F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
|
||||
F tool/spaceanal.tcl 93c1fdc9733c525b17a2024c7df193daa002e037
|
||||
F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355
|
||||
F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
||||
F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e
|
||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd
|
||||
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
|
||||
F tool/sqldiff.c b318efc2eaf7a7fac4d281a0ce736193cb2506df
|
||||
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
|
||||
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
|
||||
F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f
|
||||
F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576
|
||||
F tool/tostr.tcl 96022f35ada2194f6f8ccf6fd95809e90ed277c4
|
||||
F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003
|
||||
F tool/vdbe-compress.tcl 5926c71f9c12d2ab73ef35c29376e756eb68361c
|
||||
F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P 746fcd2fd412ddc27071827fb20eb6df0741dfb1
|
||||
R d66bf398f8de1fb81851cd37ab3877c3
|
||||
T +bgcolor * #d0c0ff
|
||||
T +sym-release *
|
||||
T +sym-version-3.9.1 *
|
||||
U drh
|
||||
Z 1827cdee71f363c0f73376b432ed6e27
|
||||
P 2aa50f6f2029e3c91a4cb91224df8ec1194f215e
|
||||
R 8f915e54b493516d25c62a2e6e65196c
|
||||
T *branch * reoptimizeArm
|
||||
T *sym-reoptimizeArm *
|
||||
T -sym-trunk *
|
||||
U mistachkin
|
||||
Z fcf933a8c4c4c19e441c1b9f4ebd2411
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
767c1727fec4ce11b83f25b3f1bfcfe68a2c8b02
|
||||
b9b22fae69000ca506656f9cf847e713c6304b75
|
||||
@@ -1,50 +0,0 @@
|
||||
#!/usr/bin/awk -f
|
||||
#
|
||||
# This AWK script scans the opcodes.h file (which is itself generated by
|
||||
# another awk script) and uses the information gleaned to create the
|
||||
# opcodes.c source file.
|
||||
#
|
||||
# Opcodes.c contains strings which are the symbolic names for the various
|
||||
# opcodes used by the VDBE. These strings are used when disassembling a
|
||||
# VDBE program during tracing or as a result of the EXPLAIN keyword.
|
||||
#
|
||||
BEGIN {
|
||||
print "/* Automatically generated. Do not edit */"
|
||||
print "/* See the mkopcodec.awk script for details. */"
|
||||
printf "#if !defined(SQLITE_OMIT_EXPLAIN)"
|
||||
printf " || defined(VDBE_PROFILE)"
|
||||
print " || defined(SQLITE_DEBUG)"
|
||||
print "#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) || defined(SQLITE_DEBUG)"
|
||||
print "# define OpHelp(X) \"\\0\" X"
|
||||
print "#else"
|
||||
print "# define OpHelp(X)"
|
||||
print "#endif"
|
||||
print "const char *sqlite3OpcodeName(int i){"
|
||||
print " static const char *const azName[] = { \"?\","
|
||||
mx = 0
|
||||
}
|
||||
/^.define OP_/ {
|
||||
sub("OP_","",$2)
|
||||
i = $3+0
|
||||
label[i] = $2
|
||||
if( mx<i ) mx = i
|
||||
for(j=5; j<NF; j++) if( $j=="synopsis:" ) break
|
||||
if( j<NF ){
|
||||
j++
|
||||
x = $j
|
||||
for(j=j+1; j<NF; j++) x = x " " $j
|
||||
synopsis[i] = x
|
||||
}else{
|
||||
synopsis[i] = ""
|
||||
}
|
||||
}
|
||||
END {
|
||||
for(i=1; i<=mx; i++){
|
||||
printf " /* %3d */ %-18s OpHelp(\"%s\"),\n", i, \
|
||||
"\"" label[i] "\"", synopsis[i]
|
||||
}
|
||||
print " };"
|
||||
print " return azName[i];"
|
||||
print "}"
|
||||
print "#endif"
|
||||
}
|
||||
-228
@@ -1,228 +0,0 @@
|
||||
#!/usr/bin/awk -f
|
||||
#
|
||||
# Generate the file opcodes.h.
|
||||
#
|
||||
# This AWK script scans a concatenation of the parse.h output file from the
|
||||
# parser and the vdbe.c source file in order to generate the opcodes numbers
|
||||
# for all opcodes.
|
||||
#
|
||||
# The lines of the vdbe.c that we are interested in are of the form:
|
||||
#
|
||||
# case OP_aaaa: /* same as TK_bbbbb */
|
||||
#
|
||||
# The TK_ comment is optional. If it is present, then the value assigned to
|
||||
# the OP_ is the same as the TK_ value. If missing, the OP_ value is assigned
|
||||
# a small integer that is different from every other OP_ value.
|
||||
#
|
||||
# We go to the trouble of making some OP_ values the same as TK_ values
|
||||
# as an optimization. During parsing, things like expression operators
|
||||
# are coded with TK_ values such as TK_ADD, TK_DIVIDE, and so forth. Later
|
||||
# during code generation, we need to generate corresponding opcodes like
|
||||
# OP_Add and OP_Divide. By making TK_ADD==OP_Add and TK_DIVIDE==OP_Divide,
|
||||
# code to translate from one to the other is avoided. This makes the
|
||||
# code generator run (infinitesimally) faster and more importantly it makes
|
||||
# the library footprint smaller.
|
||||
#
|
||||
# This script also scans for lines of the form:
|
||||
#
|
||||
# case OP_aaaa: /* jump, in1, in2, in3, out2-prerelease, out3 */
|
||||
#
|
||||
# When such comments are found on an opcode, it means that certain
|
||||
# properties apply to that opcode. Set corresponding flags using the
|
||||
# OPFLG_INITIALIZER macro.
|
||||
#
|
||||
|
||||
|
||||
# Remember the TK_ values from the parse.h file
|
||||
/^#define TK_/ {
|
||||
tk[$2] = 0+$3 # tk[x] holds the numeric value for TK symbol X
|
||||
}
|
||||
|
||||
# Find "/* Opcode: " lines in the vdbe.c file. Each one introduces
|
||||
# a new opcode. Remember which parameters are used.
|
||||
/^.. Opcode: / {
|
||||
currentOp = "OP_" $3
|
||||
m = 0
|
||||
for(i=4; i<=NF; i++){
|
||||
x = $i
|
||||
if( x=="P1" ) m += 1
|
||||
if( x=="P2" ) m += 2
|
||||
if( x=="P3" ) m += 4
|
||||
if( x=="P4" ) m += 8
|
||||
if( x=="P5" ) m += 16
|
||||
}
|
||||
paramused[currentOp] = m
|
||||
}
|
||||
|
||||
# Find "** Synopsis: " lines that follow Opcode:
|
||||
/^.. Synopsis: / {
|
||||
if( currentOp ){
|
||||
x = $3
|
||||
for(i=4; i<=NF; i++){
|
||||
x = x " " $i
|
||||
}
|
||||
synopsis[currentOp] = x
|
||||
}
|
||||
}
|
||||
|
||||
# Scan for "case OP_aaaa:" lines in the vdbe.c file
|
||||
/^case OP_/ {
|
||||
name = $2
|
||||
sub(/:/,"",name)
|
||||
sub("\r","",name)
|
||||
op[name] = -1 # op[x] holds the numeric value for OP symbol x
|
||||
jump[name] = 0
|
||||
in1[name] = 0
|
||||
in2[name] = 0
|
||||
in3[name] = 0
|
||||
out2[name] = 0
|
||||
out3[name] = 0
|
||||
for(i=3; i<NF; i++){
|
||||
if($i=="same" && $(i+1)=="as"){
|
||||
sym = $(i+2)
|
||||
sub(/,/,"",sym)
|
||||
val = tk[sym]
|
||||
op[name] = val
|
||||
used[val] = 1
|
||||
sameas[val] = sym
|
||||
def[val] = name
|
||||
}
|
||||
x = $i
|
||||
sub(",","",x)
|
||||
if(x=="jump"){
|
||||
jump[name] = 1
|
||||
}else if(x=="in1"){
|
||||
in1[name] = 1
|
||||
}else if(x=="in2"){
|
||||
in2[name] = 1
|
||||
}else if(x=="in3"){
|
||||
in3[name] = 1
|
||||
}else if(x=="out2"){
|
||||
out2[name] = 1
|
||||
}else if(x=="out3"){
|
||||
out3[name] = 1
|
||||
}
|
||||
}
|
||||
order[n_op++] = name;
|
||||
}
|
||||
|
||||
# Assign numbers to all opcodes and output the result.
|
||||
END {
|
||||
cnt = 0
|
||||
max = 0
|
||||
print "/* Automatically generated. Do not edit */"
|
||||
print "/* See the mkopcodeh.awk script for details */"
|
||||
op["OP_Noop"] = -1;
|
||||
order[n_op++] = "OP_Noop";
|
||||
op["OP_Explain"] = -1;
|
||||
order[n_op++] = "OP_Explain";
|
||||
|
||||
# Assign small values to opcodes that are processed by resolveP2Values()
|
||||
# to make code generation for the switch() statement smaller and faster.
|
||||
for(i=0; i<n_op; i++){
|
||||
name = order[i];
|
||||
if( op[name]>=0 ) continue;
|
||||
if( name=="OP_Transaction" \
|
||||
|| name=="OP_AutoCommit" \
|
||||
|| name=="OP_Savepoint" \
|
||||
|| name=="OP_Checkpoint" \
|
||||
|| name=="OP_Vacuum" \
|
||||
|| name=="OP_JournalMode" \
|
||||
|| name=="OP_VUpdate" \
|
||||
|| name=="OP_VFilter" \
|
||||
|| name=="OP_Next" \
|
||||
|| name=="OP_NextIfOpen" \
|
||||
|| name=="OP_SorterNext" \
|
||||
|| name=="OP_Prev" \
|
||||
|| name=="OP_PrevIfOpen" \
|
||||
){
|
||||
cnt++
|
||||
while( used[cnt] ) cnt++
|
||||
op[name] = cnt
|
||||
used[cnt] = 1
|
||||
def[cnt] = name
|
||||
}
|
||||
}
|
||||
|
||||
# Generate the numeric values for opcodes
|
||||
for(i=0; i<n_op; i++){
|
||||
name = order[i];
|
||||
if( op[name]<0 ){
|
||||
cnt++
|
||||
while( used[cnt] ) cnt++
|
||||
op[name] = cnt
|
||||
used[cnt] = 1
|
||||
def[cnt] = name
|
||||
}
|
||||
}
|
||||
max = cnt
|
||||
for(i=1; i<=max; i++){
|
||||
if( !used[i] ){
|
||||
def[i] = "OP_NotUsed_" i
|
||||
}
|
||||
printf "#define %-16s %3d", def[i], i
|
||||
com = ""
|
||||
if( sameas[i] ){
|
||||
com = "same as " sameas[i]
|
||||
}
|
||||
x = synopsis[def[i]]
|
||||
if( x ){
|
||||
if( com=="" ){
|
||||
com = "synopsis: " x
|
||||
} else {
|
||||
com = com ", synopsis: " x
|
||||
}
|
||||
}
|
||||
if( com!="" ){
|
||||
printf " /* %-42s */", com
|
||||
}
|
||||
printf "\n"
|
||||
}
|
||||
|
||||
# Generate the bitvectors:
|
||||
#
|
||||
# bit 0: jump
|
||||
# bit 1: pushes a result onto stack
|
||||
# bit 2: output to p1. release p1 before opcode runs
|
||||
#
|
||||
for(i=0; i<=max; i++){
|
||||
name = def[i]
|
||||
a0 = a1 = a2 = a3 = a4 = a5 = a6 = a7 = 0
|
||||
if( jump[name] ) a0 = 1;
|
||||
if( in1[name] ) a2 = 2;
|
||||
if( in2[name] ) a3 = 4;
|
||||
if( in3[name] ) a4 = 8;
|
||||
if( out2[name] ) a5 = 16;
|
||||
if( out3[name] ) a6 = 32;
|
||||
bv[i] = a0+a1+a2+a3+a4+a5+a6;
|
||||
}
|
||||
print "\n"
|
||||
print "/* Properties such as \"out2\" or \"jump\" that are specified in"
|
||||
print "** comments following the \"case\" for each opcode in the vdbe.c"
|
||||
print "** are encoded into bitvectors as follows:"
|
||||
print "*/"
|
||||
print "#define OPFLG_JUMP 0x0001 /* jump: P2 holds jmp target */"
|
||||
print "#define OPFLG_IN1 0x0002 /* in1: P1 is an input */"
|
||||
print "#define OPFLG_IN2 0x0004 /* in2: P2 is an input */"
|
||||
print "#define OPFLG_IN3 0x0008 /* in3: P3 is an input */"
|
||||
print "#define OPFLG_OUT2 0x0010 /* out2: P2 is an output */"
|
||||
print "#define OPFLG_OUT3 0x0020 /* out3: P3 is an output */"
|
||||
print "#define OPFLG_INITIALIZER {\\"
|
||||
for(i=0; i<=max; i++){
|
||||
if( i%8==0 ) printf("/* %3d */",i)
|
||||
printf " 0x%02x,", bv[i]
|
||||
if( i%8==7 ) printf("\\\n");
|
||||
}
|
||||
print "}"
|
||||
if( 0 ){
|
||||
print "\n/* Bitmask to indicate which fields (P1..P5) of each opcode are"
|
||||
print "** actually used.\n*/"
|
||||
print "#define OP_PARAM_USED_INITIALIZER {\\"
|
||||
for(i=0; i<=max; i++){
|
||||
if( i%8==0 ) printf("/* %3d */",i)
|
||||
printf " 0x%02x,", paramused[def[i]]
|
||||
if( i%8==7 ) printf("\\\n");
|
||||
}
|
||||
print "}"
|
||||
}
|
||||
}
|
||||
+22
-19
@@ -46,6 +46,9 @@
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define ISSPACE(X) isspace((unsigned char)(X))
|
||||
#define ISDIGIT(X) isdigit((unsigned char)(X))
|
||||
|
||||
/* The suffix to append to the child command lines, if any */
|
||||
#if defined(_WIN32)
|
||||
# define GETPID (int)GetCurrentProcessId
|
||||
@@ -187,10 +190,10 @@ int strglob(const char *zGlob, const char *z){
|
||||
}
|
||||
if( c2==0 || (seen ^ invert)==0 ) return 0;
|
||||
}else if( c=='#' ){
|
||||
if( (z[0]=='-' || z[0]=='+') && isdigit(z[1]) ) z++;
|
||||
if( !isdigit(z[0]) ) return 0;
|
||||
if( (z[0]=='-' || z[0]=='+') && ISDIGIT(z[1]) ) z++;
|
||||
if( !ISDIGIT(z[0]) ) return 0;
|
||||
z++;
|
||||
while( isdigit(z[0]) ){ z++; }
|
||||
while( ISDIGIT(z[0]) ){ z++; }
|
||||
}else{
|
||||
if( c!=(*(z++)) ) return 0;
|
||||
}
|
||||
@@ -289,7 +292,7 @@ static void logMessage(const char *zFormat, ...){
|
||||
*/
|
||||
static int clipLength(const char *z){
|
||||
int n = (int)strlen(z);
|
||||
while( n>0 && isspace(z[n-1]) ){ n--; }
|
||||
while( n>0 && ISSPACE(z[n-1]) ){ n--; }
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -444,7 +447,7 @@ static void stringAppendTerm(String *p, const char *z){
|
||||
stringAppend(p, "nil", 3);
|
||||
return;
|
||||
}
|
||||
for(i=0; z[i] && !isspace(z[i]); i++){}
|
||||
for(i=0; z[i] && !ISSPACE(z[i]); i++){}
|
||||
if( i>0 && z[i]==0 ){
|
||||
stringAppend(p, z, i);
|
||||
return;
|
||||
@@ -699,7 +702,7 @@ static char *readFile(const char *zFilename){
|
||||
*/
|
||||
static int tokenLength(const char *z, int *pnLine){
|
||||
int n = 0;
|
||||
if( isspace(z[0]) || (z[0]=='/' && z[1]=='*') ){
|
||||
if( ISSPACE(z[0]) || (z[0]=='/' && z[1]=='*') ){
|
||||
int inC = 0;
|
||||
int c;
|
||||
if( z[0]=='/' ){
|
||||
@@ -708,7 +711,7 @@ static int tokenLength(const char *z, int *pnLine){
|
||||
}
|
||||
while( (c = z[n++])!=0 ){
|
||||
if( c=='\n' ) (*pnLine)++;
|
||||
if( isspace(c) ) continue;
|
||||
if( ISSPACE(c) ) continue;
|
||||
if( inC && c=='*' && z[n]=='/' ){
|
||||
n++;
|
||||
inC = 0;
|
||||
@@ -734,7 +737,7 @@ static int tokenLength(const char *z, int *pnLine){
|
||||
}
|
||||
}else{
|
||||
int c;
|
||||
for(n=1; (c = z[n])!=0 && !isspace(c) && c!='"' && c!='\'' && c!=';'; n++){}
|
||||
for(n=1; (c = z[n])!=0 && !ISSPACE(c) && c!='"' && c!='\'' && c!=';'; n++){}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
@@ -748,7 +751,7 @@ static int extractToken(const char *zIn, int nIn, char *zOut, int nOut){
|
||||
zOut[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
for(i=0; i<nIn && i<nOut-1 && !isspace(zIn[i]); i++){ zOut[i] = zIn[i]; }
|
||||
for(i=0; i<nIn && i<nOut-1 && !ISSPACE(zIn[i]); i++){ zOut[i] = zIn[i]; }
|
||||
zOut[i] = 0;
|
||||
return i;
|
||||
}
|
||||
@@ -758,7 +761,7 @@ static int extractToken(const char *zIn, int nIn, char *zOut, int nOut){
|
||||
*/
|
||||
static int findEnd(const char *z, int *pnLine){
|
||||
int n = 0;
|
||||
while( z[n] && (strncmp(z+n,"--end",5) || !isspace(z[n+5])) ){
|
||||
while( z[n] && (strncmp(z+n,"--end",5) || !ISSPACE(z[n+5])) ){
|
||||
n += tokenLength(z+n, pnLine);
|
||||
}
|
||||
return n;
|
||||
@@ -773,12 +776,12 @@ static int findEndif(const char *z, int stopAtElse, int *pnLine){
|
||||
int n = 0;
|
||||
while( z[n] ){
|
||||
int len = tokenLength(z+n, pnLine);
|
||||
if( (strncmp(z+n,"--endif",7)==0 && isspace(z[n+7]))
|
||||
|| (stopAtElse && strncmp(z+n,"--else",6)==0 && isspace(z[n+6]))
|
||||
if( (strncmp(z+n,"--endif",7)==0 && ISSPACE(z[n+7]))
|
||||
|| (stopAtElse && strncmp(z+n,"--else",6)==0 && ISSPACE(z[n+6]))
|
||||
){
|
||||
return n+len;
|
||||
}
|
||||
if( strncmp(z+n,"--if",4)==0 && isspace(z[n+4]) ){
|
||||
if( strncmp(z+n,"--if",4)==0 && ISSPACE(z[n+4]) ){
|
||||
int skip = findEndif(z+n+len, 0, pnLine);
|
||||
n += skip + len;
|
||||
}else{
|
||||
@@ -888,7 +891,7 @@ static void runScript(
|
||||
while( (c = zScript[ii])!=0 ){
|
||||
prevLine = lineno;
|
||||
len = tokenLength(zScript+ii, &lineno);
|
||||
if( isspace(c) || (c=='/' && zScript[ii+1]=='*') ){
|
||||
if( ISSPACE(c) || (c=='/' && zScript[ii+1]=='*') ){
|
||||
ii += len;
|
||||
continue;
|
||||
}
|
||||
@@ -909,7 +912,7 @@ static void runScript(
|
||||
if( g.iTrace>=2 ) logMessage("%.*s", len, zScript+ii);
|
||||
n = extractToken(zScript+ii+2, len-2, zCmd, sizeof(zCmd));
|
||||
for(nArg=0; n<len-2 && nArg<MX_ARG; nArg++){
|
||||
while( n<len-2 && isspace(zScript[ii+2+n]) ){ n++; }
|
||||
while( n<len-2 && ISSPACE(zScript[ii+2+n]) ){ n++; }
|
||||
if( n>=len-2 ) break;
|
||||
n += extractToken(zScript+ii+2+n, len-2-n,
|
||||
azArg[nArg], sizeof(azArg[nArg]));
|
||||
@@ -976,7 +979,7 @@ static void runScript(
|
||||
if( strcmp(zCmd, "match")==0 ){
|
||||
int jj;
|
||||
char *zAns = zScript+ii;
|
||||
for(jj=7; jj<len-1 && isspace(zAns[jj]); jj++){}
|
||||
for(jj=7; jj<len-1 && ISSPACE(zAns[jj]); jj++){}
|
||||
zAns += jj;
|
||||
if( len-jj-1!=sResult.n || strncmp(sResult.z, zAns, len-jj-1) ){
|
||||
errorMessage("line %d of %s:\nExpected [%.*s]\n Got [%s]",
|
||||
@@ -998,7 +1001,7 @@ static void runScript(
|
||||
char *zAns = zScript+ii;
|
||||
char *zCopy;
|
||||
int isGlob = (zCmd[0]=='g');
|
||||
for(jj=9-3*isGlob; jj<len-1 && isspace(zAns[jj]); jj++){}
|
||||
for(jj=9-3*isGlob; jj<len-1 && ISSPACE(zAns[jj]); jj++){}
|
||||
zAns += jj;
|
||||
zCopy = sqlite3_mprintf("%.*s", len-jj-1, zAns);
|
||||
if( (sqlite3_strglob(zCopy, sResult.z)==0)^isGlob ){
|
||||
@@ -1050,7 +1053,7 @@ static void runScript(
|
||||
*/
|
||||
if( strcmp(zCmd, "print")==0 ){
|
||||
int jj;
|
||||
for(jj=7; jj<len && isspace(zScript[ii+jj]); jj++){}
|
||||
for(jj=7; jj<len && ISSPACE(zScript[ii+jj]); jj++){}
|
||||
logMessage("%.*s", len-jj, zScript+ii+jj);
|
||||
}else
|
||||
|
||||
@@ -1062,7 +1065,7 @@ static void runScript(
|
||||
if( strcmp(zCmd, "if")==0 ){
|
||||
int jj, rc;
|
||||
sqlite3_stmt *pStmt;
|
||||
for(jj=4; jj<len && isspace(zScript[ii+jj]); jj++){}
|
||||
for(jj=4; jj<len && ISSPACE(zScript[ii+jj]); jj++){}
|
||||
pStmt = prepareSql("SELECT %.*s", len-jj, zScript+ii+jj);
|
||||
rc = sqlite3_step(pStmt);
|
||||
if( rc!=SQLITE_ROW || sqlite3_column_int(pStmt, 0)==0 ){
|
||||
|
||||
+4
-5
@@ -293,7 +293,7 @@ static int backupOnePage(
|
||||
DbPage *pDestPg = 0;
|
||||
Pgno iDest = (Pgno)(iOff/nDestPgsz)+1;
|
||||
if( iDest==PENDING_BYTE_PAGE(p->pDest->pBt) ) continue;
|
||||
if( SQLITE_OK==(rc = sqlite3PagerGet(pDestPager, iDest, &pDestPg))
|
||||
if( SQLITE_OK==(rc = sqlite3PagerGet(pDestPager, iDest, &pDestPg, 0))
|
||||
&& SQLITE_OK==(rc = sqlite3PagerWrite(pDestPg))
|
||||
){
|
||||
const u8 *zIn = &zSrcData[iOff%nSrcPgsz];
|
||||
@@ -419,8 +419,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
const Pgno iSrcPg = p->iNext; /* Source page number */
|
||||
if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
|
||||
DbPage *pSrcPg; /* Source page object */
|
||||
rc = sqlite3PagerAcquire(pSrcPager, iSrcPg, &pSrcPg,
|
||||
PAGER_GET_READONLY);
|
||||
rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg,PAGER_GET_READONLY);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0);
|
||||
sqlite3PagerUnref(pSrcPg);
|
||||
@@ -520,7 +519,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
for(iPg=nDestTruncate; rc==SQLITE_OK && iPg<=(Pgno)nDstPage; iPg++){
|
||||
if( iPg!=PENDING_BYTE_PAGE(p->pDest->pBt) ){
|
||||
DbPage *pPg;
|
||||
rc = sqlite3PagerGet(pDestPager, iPg, &pPg);
|
||||
rc = sqlite3PagerGet(pDestPager, iPg, &pPg, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3PagerWrite(pPg);
|
||||
sqlite3PagerUnref(pPg);
|
||||
@@ -540,7 +539,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
){
|
||||
PgHdr *pSrcPg = 0;
|
||||
const Pgno iSrcPg = (Pgno)((iOff/pgszSrc)+1);
|
||||
rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
|
||||
rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
u8 *zData = sqlite3PagerGetData(pSrcPg);
|
||||
rc = sqlite3OsWrite(pFile, zData, pgszSrc, iOff);
|
||||
|
||||
+48
-34
@@ -858,6 +858,26 @@ int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_CURSOR_HINTS
|
||||
/*
|
||||
** Provide hints to the cursor. The particular hint given (and the type
|
||||
** and number of the varargs parameters) is determined by the eHintType
|
||||
** parameter. See the definitions of the BTREE_HINT_* macros for details.
|
||||
*/
|
||||
void sqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){
|
||||
/* Used only by system that substitute their own storage engine */
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Provide flag hints to the cursor.
|
||||
*/
|
||||
void sqlite3BtreeCursorHintFlags(BtCursor *pCur, unsigned x){
|
||||
assert( x==BTREE_SEEK_EQ || x==BTREE_BULKLOAD || x==0 );
|
||||
pCur->hints = x;
|
||||
}
|
||||
|
||||
|
||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||
/*
|
||||
** Given a page number of a regular database page, return the page
|
||||
@@ -911,7 +931,7 @@ static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){
|
||||
return;
|
||||
}
|
||||
iPtrmap = PTRMAP_PAGENO(pBt, key);
|
||||
rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage);
|
||||
rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
*pRC = rc;
|
||||
return;
|
||||
@@ -954,7 +974,7 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
|
||||
assert( sqlite3_mutex_held(pBt->mutex) );
|
||||
|
||||
iPtrmap = PTRMAP_PAGENO(pBt, key);
|
||||
rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage);
|
||||
rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0);
|
||||
if( rc!=0 ){
|
||||
return rc;
|
||||
}
|
||||
@@ -1881,11 +1901,14 @@ static void zeroPage(MemPage *pPage, int flags){
|
||||
*/
|
||||
static MemPage *btreePageFromDbPage(DbPage *pDbPage, Pgno pgno, BtShared *pBt){
|
||||
MemPage *pPage = (MemPage*)sqlite3PagerGetExtra(pDbPage);
|
||||
pPage->aData = sqlite3PagerGetData(pDbPage);
|
||||
pPage->pDbPage = pDbPage;
|
||||
pPage->pBt = pBt;
|
||||
pPage->pgno = pgno;
|
||||
pPage->hdrOffset = pgno==1 ? 100 : 0;
|
||||
if( pgno!=pPage->pgno ){
|
||||
pPage->aData = sqlite3PagerGetData(pDbPage);
|
||||
pPage->pDbPage = pDbPage;
|
||||
pPage->pBt = pBt;
|
||||
pPage->pgno = pgno;
|
||||
pPage->hdrOffset = pgno==1 ? 100 : 0;
|
||||
}
|
||||
assert( pPage->aData==sqlite3PagerGetData(pDbPage) );
|
||||
return pPage;
|
||||
}
|
||||
|
||||
@@ -1911,7 +1934,7 @@ static int btreeGetPage(
|
||||
|
||||
assert( flags==0 || flags==PAGER_GET_NOCONTENT || flags==PAGER_GET_READONLY );
|
||||
assert( sqlite3_mutex_held(pBt->mutex) );
|
||||
rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, flags);
|
||||
rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, flags);
|
||||
if( rc ) return rc;
|
||||
*ppPage = btreePageFromDbPage(pDbPage, pgno, pBt);
|
||||
return SQLITE_OK;
|
||||
@@ -1976,24 +1999,25 @@ static int getAndInitPage(
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
goto getAndInitPage_error;
|
||||
}
|
||||
rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, bReadOnly);
|
||||
rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, bReadOnly);
|
||||
if( rc ){
|
||||
goto getAndInitPage_error;
|
||||
}
|
||||
*ppPage = btreePageFromDbPage(pDbPage, pgno, pBt);
|
||||
*ppPage = (MemPage*)sqlite3PagerGetExtra(pDbPage);
|
||||
if( (*ppPage)->isInit==0 ){
|
||||
btreePageFromDbPage(pDbPage, pgno, pBt);
|
||||
rc = btreeInitPage(*ppPage);
|
||||
if( rc!=SQLITE_OK ){
|
||||
releasePage(*ppPage);
|
||||
goto getAndInitPage_error;
|
||||
}
|
||||
}
|
||||
assert( (*ppPage)->pgno==pgno );
|
||||
assert( (*ppPage)->aData==sqlite3PagerGetData(pDbPage) );
|
||||
|
||||
/* If obtaining a child page for a cursor, we must verify that the page is
|
||||
** compatible with the root page. */
|
||||
if( pCur
|
||||
&& ((*ppPage)->nCell<1 || (*ppPage)->intKey!=pCur->curIntKey)
|
||||
){
|
||||
if( pCur && ((*ppPage)->nCell<1 || (*ppPage)->intKey!=pCur->curIntKey) ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
releasePage(*ppPage);
|
||||
goto getAndInitPage_error;
|
||||
@@ -4055,13 +4079,16 @@ static int btreeCursor(
|
||||
BtCursor *pX; /* Looping over other all cursors */
|
||||
|
||||
assert( sqlite3BtreeHoldsMutex(p) );
|
||||
assert( wrFlag==0 || wrFlag==1 );
|
||||
assert( wrFlag==0
|
||||
|| wrFlag==BTREE_WRCSR
|
||||
|| wrFlag==(BTREE_WRCSR|BTREE_FORDELETE)
|
||||
);
|
||||
|
||||
/* The following assert statements verify that if this is a sharable
|
||||
** b-tree database, the connection is holding the required table locks,
|
||||
** and that no other connection has any open cursor that conflicts with
|
||||
** this lock. */
|
||||
assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, wrFlag+1) );
|
||||
assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, (wrFlag?2:1)) );
|
||||
assert( wrFlag==0 || !hasReadConflicts(p, iTable) );
|
||||
|
||||
/* Assert that the caller has opened the required transaction. */
|
||||
@@ -4086,8 +4113,7 @@ static int btreeCursor(
|
||||
pCur->pKeyInfo = pKeyInfo;
|
||||
pCur->pBtree = p;
|
||||
pCur->pBt = pBt;
|
||||
assert( wrFlag==0 || wrFlag==BTCF_WriteFlag );
|
||||
pCur->curFlags = wrFlag;
|
||||
pCur->curFlags = wrFlag ? BTCF_WriteFlag : 0;
|
||||
pCur->curPagerFlags = wrFlag ? 0 : PAGER_GET_READONLY;
|
||||
/* If there are two or more cursors on the same btree, then all such
|
||||
** cursors *must* have the BTCF_Multiple flag set. */
|
||||
@@ -4499,7 +4525,9 @@ static int accessPayload(
|
||||
|
||||
/* If required, populate the overflow page-list cache. */
|
||||
if( (pCur->curFlags & BTCF_ValidOvfl)!=0 ){
|
||||
assert(!pCur->aOverflow[iIdx] || pCur->aOverflow[iIdx]==nextPage);
|
||||
assert( pCur->aOverflow[iIdx]==0
|
||||
|| pCur->aOverflow[iIdx]==nextPage
|
||||
|| CORRUPT_DB );
|
||||
pCur->aOverflow[iIdx] = nextPage;
|
||||
}
|
||||
|
||||
@@ -4569,7 +4597,7 @@ static int accessPayload(
|
||||
|
||||
{
|
||||
DbPage *pDbPage;
|
||||
rc = sqlite3PagerAcquire(pBt->pPager, nextPage, &pDbPage,
|
||||
rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage,
|
||||
((eOp&0x01)==0 ? PAGER_GET_READONLY : 0)
|
||||
);
|
||||
if( rc==SQLITE_OK ){
|
||||
@@ -6936,9 +6964,6 @@ static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){
|
||||
** If aOvflSpace is set to a null pointer, this function returns
|
||||
** SQLITE_NOMEM.
|
||||
*/
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
|
||||
#pragma optimize("", off)
|
||||
#endif
|
||||
static int balance_nonroot(
|
||||
MemPage *pParent, /* Parent page of siblings being balanced */
|
||||
int iParentIdx, /* Index of "the page" in pParent */
|
||||
@@ -7684,9 +7709,6 @@ balance_cleanup:
|
||||
|
||||
return rc;
|
||||
}
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
|
||||
#pragma optimize("", on)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
@@ -8885,7 +8907,7 @@ static void checkList(
|
||||
break;
|
||||
}
|
||||
if( checkRef(pCheck, iPage) ) break;
|
||||
if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage) ){
|
||||
if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){
|
||||
checkAppendMsg(pCheck, "failed to get page %d", iPage);
|
||||
break;
|
||||
}
|
||||
@@ -9622,14 +9644,6 @@ int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** set the mask of hint flags for cursor pCsr.
|
||||
*/
|
||||
void sqlite3BtreeCursorHints(BtCursor *pCsr, unsigned int mask){
|
||||
assert( mask==BTREE_BULKLOAD || mask==BTREE_SEEK_EQ || mask==0 );
|
||||
pCsr->hints = mask;
|
||||
}
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
/*
|
||||
** Return true if the cursor has a hint specified. This routine is
|
||||
|
||||
+51
-3
@@ -150,8 +150,37 @@ int sqlite3BtreeNewDb(Btree *p);
|
||||
#define BTREE_DATA_VERSION 15 /* A virtual meta-value */
|
||||
|
||||
/*
|
||||
** Values that may be OR'd together to form the second argument of an
|
||||
** sqlite3BtreeCursorHints() call.
|
||||
** Kinds of hints that can be passed into the sqlite3BtreeCursorHint()
|
||||
** interface.
|
||||
**
|
||||
** BTREE_HINT_RANGE (arguments: Expr*, Mem*)
|
||||
**
|
||||
** The first argument is an Expr* (which is guaranteed to be constant for
|
||||
** the lifetime of the cursor) that defines constraints on which rows
|
||||
** might be fetched with this cursor. The Expr* tree may contain
|
||||
** TK_REGISTER nodes that refer to values stored in the array of registers
|
||||
** passed as the second parameter. In other words, if Expr.op==TK_REGISTER
|
||||
** then the value of the node is the value in Mem[pExpr.iTable]. Any
|
||||
** TK_COLUMN node in the expression tree refers to the Expr.iColumn-th
|
||||
** column of the b-tree of the cursor. The Expr tree will not contain
|
||||
** any function calls nor subqueries nor references to b-trees other than
|
||||
** the cursor being hinted.
|
||||
**
|
||||
** The design of the _RANGE hint is aid b-tree implementations that try
|
||||
** to prefetch content from remote machines - to provide those
|
||||
** implementations with limits on what needs to be prefetched and thereby
|
||||
** reduce network bandwidth.
|
||||
**
|
||||
** Note that BTREE_HINT_FLAGS with BTREE_BULKLOAD is the only hint used by
|
||||
** standard SQLite. The other hints are provided for extentions that use
|
||||
** the SQLite parser and code generator but substitute their own storage
|
||||
** engine.
|
||||
*/
|
||||
#define BTREE_HINT_RANGE 0 /* Range constraints on queries */
|
||||
|
||||
/*
|
||||
** Values that may be OR'd together to form the argument to the
|
||||
** BTREE_HINT_FLAGS hint for sqlite3BtreeCursorHint():
|
||||
**
|
||||
** The BTREE_BULKLOAD flag is set on index cursors when the index is going
|
||||
** to be filled with content that is already in sorted order.
|
||||
@@ -165,6 +194,22 @@ int sqlite3BtreeNewDb(Btree *p);
|
||||
#define BTREE_BULKLOAD 0x00000001 /* Used to full index in sorted order */
|
||||
#define BTREE_SEEK_EQ 0x00000002 /* EQ seeks only - no range seeks */
|
||||
|
||||
/*
|
||||
** Flags passed as the third argument to sqlite3BtreeCursor().
|
||||
**
|
||||
** For read-only cursors the wrFlag argument is always zero. For read-write
|
||||
** cursors it may be set to either (BTREE_WRCSR|BTREE_FORDELETE) or
|
||||
** (BTREE_WRCSR). If the BTREE_FORDELETE flag is set, then the cursor will
|
||||
** only be used by SQLite for the following:
|
||||
**
|
||||
** * to seek to and delete specific entries, and/or
|
||||
**
|
||||
** * to read values that will be used to create keys that other
|
||||
** BTREE_FORDELETE cursors will seek to and delete.
|
||||
*/
|
||||
#define BTREE_WRCSR 0x00000004 /* read-write cursor */
|
||||
#define BTREE_FORDELETE 0x00000008 /* Cursor is for seek/delete only */
|
||||
|
||||
int sqlite3BtreeCursor(
|
||||
Btree*, /* BTree containing table to open */
|
||||
int iTable, /* Index of root page */
|
||||
@@ -174,6 +219,10 @@ int sqlite3BtreeCursor(
|
||||
);
|
||||
int sqlite3BtreeCursorSize(void);
|
||||
void sqlite3BtreeCursorZero(BtCursor*);
|
||||
void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned);
|
||||
#ifdef SQLITE_ENABLE_CURSOR_HINTS
|
||||
void sqlite3BtreeCursorHint(BtCursor*, int, ...);
|
||||
#endif
|
||||
|
||||
int sqlite3BtreeCloseCursor(BtCursor*);
|
||||
int sqlite3BtreeMovetoUnpacked(
|
||||
@@ -208,7 +257,6 @@ int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
|
||||
void sqlite3BtreeIncrblobCursor(BtCursor *);
|
||||
void sqlite3BtreeClearCursor(BtCursor *);
|
||||
int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
|
||||
void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask);
|
||||
#ifdef SQLITE_DEBUG
|
||||
int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask);
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -517,7 +517,7 @@ struct BtCursor {
|
||||
int skipNext; /* Prev() is noop if negative. Next() is noop if positive.
|
||||
** Error code if eState==CURSOR_FAULT */
|
||||
u8 curFlags; /* zero or more BTCF_* flags defined below */
|
||||
u8 curPagerFlags; /* Flags to send to sqlite3PagerAcquire() */
|
||||
u8 curPagerFlags; /* Flags to send to sqlite3PagerGet() */
|
||||
u8 eState; /* One of the CURSOR_XXX constants (see below) */
|
||||
u8 hints; /* As configured by CursorSetHints() */
|
||||
/* All fields above are zeroed when the cursor is allocated. See
|
||||
|
||||
+25
-24
@@ -1271,6 +1271,30 @@ void sqlite3AddDefaultValue(Parse *pParse, ExprSpan *pSpan){
|
||||
sqlite3ExprDelete(db, pSpan->pExpr);
|
||||
}
|
||||
|
||||
/*
|
||||
** Backwards Compatibility Hack:
|
||||
**
|
||||
** Historical versions of SQLite accepted strings as column names in
|
||||
** indexes and PRIMARY KEY constraints and in UNIQUE constraints. Example:
|
||||
**
|
||||
** CREATE TABLE xyz(a,b,c,d,e,PRIMARY KEY('a'),UNIQUE('b','c' COLLATE trim)
|
||||
** CREATE INDEX abc ON xyz('c','d' DESC,'e' COLLATE nocase DESC);
|
||||
**
|
||||
** This is goofy. But to preserve backwards compatibility we continue to
|
||||
** accept it. This routine does the necessary conversion. It converts
|
||||
** the expression given in its argument from a TK_STRING into a TK_ID
|
||||
** if the expression is just a TK_STRING with an optional COLLATE clause.
|
||||
** If the epxression is anything other than TK_STRING, the expression is
|
||||
** unchanged.
|
||||
*/
|
||||
static void sqlite3StringToId(Expr *p){
|
||||
if( p->op==TK_STRING ){
|
||||
p->op = TK_ID;
|
||||
}else if( p->op==TK_COLLATE && p->pLeft->op==TK_STRING ){
|
||||
p->pLeft->op = TK_ID;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Designate the PRIMARY KEY for the table. pList is a list of names
|
||||
** of columns that form the primary key. If pList is NULL, then the
|
||||
@@ -1317,6 +1341,7 @@ void sqlite3AddPrimaryKey(
|
||||
for(i=0; i<nTerm; i++){
|
||||
Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[i].pExpr);
|
||||
assert( pCExpr!=0 );
|
||||
sqlite3StringToId(pCExpr);
|
||||
if( pCExpr->op==TK_ID ){
|
||||
const char *zCName = pCExpr->u.zToken;
|
||||
for(iCol=0; iCol<pTab->nCol; iCol++){
|
||||
@@ -2855,30 +2880,6 @@ Index *sqlite3AllocateIndexObject(
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
** Backwards Compatibility Hack:
|
||||
**
|
||||
** Historical versions of SQLite accepted strings as column names in
|
||||
** indexes and PRIMARY KEY constraints and in UNIQUE constraints. Example:
|
||||
**
|
||||
** CREATE TABLE xyz(a,b,c,d,e,PRIMARY KEY('a'),UNIQUE('b','c' COLLATE trim)
|
||||
** CREATE INDEX abc ON xyz('c','d' DESC,'e' COLLATE nocase DESC);
|
||||
**
|
||||
** This is goofy. But to preserve backwards compatibility we continue to
|
||||
** accept it. This routine does the necessary conversion. It converts
|
||||
** the expression given in its argument from a TK_STRING into a TK_ID
|
||||
** if the expression is just a TK_STRING with an optional COLLATE clause.
|
||||
** If the epxression is anything other than TK_STRING, the expression is
|
||||
** unchanged.
|
||||
*/
|
||||
static void sqlite3StringToId(Expr *p){
|
||||
if( p->op==TK_STRING ){
|
||||
p->op = TK_ID;
|
||||
}else if( p->op==TK_COLLATE && p->pLeft->op==TK_STRING ){
|
||||
p->pLeft->op = TK_ID;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Create a new index for an SQL table. pName1.pName2 is the name of the index
|
||||
** and pTblList is the name of the table that is to be indexed. Both will
|
||||
|
||||
+3
-3
@@ -386,7 +386,7 @@ static int statDecodePage(Btree *pBt, StatPage *p){
|
||||
int rc;
|
||||
u32 iPrev = pCell->aOvfl[j-1];
|
||||
DbPage *pPg = 0;
|
||||
rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPrev, &pPg);
|
||||
rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPrev, &pPg, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
assert( pPg==0 );
|
||||
return rc;
|
||||
@@ -454,7 +454,7 @@ statNextRestart:
|
||||
pCsr->isEof = 1;
|
||||
return sqlite3_reset(pCsr->pStmt);
|
||||
}
|
||||
rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg);
|
||||
rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg, 0);
|
||||
pCsr->aPage[0].iPgno = iRoot;
|
||||
pCsr->aPage[0].iCell = 0;
|
||||
pCsr->aPage[0].zPath = z = sqlite3_mprintf("/");
|
||||
@@ -514,7 +514,7 @@ statNextRestart:
|
||||
}else{
|
||||
p[1].iPgno = p->aCell[p->iCell].iChildPg;
|
||||
}
|
||||
rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg);
|
||||
rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg, 0);
|
||||
p[1].iCell = 0;
|
||||
p[1].zPath = z = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell);
|
||||
p->iCell++;
|
||||
|
||||
+3
-2
@@ -478,12 +478,13 @@ void sqlite3DeleteFrom(
|
||||
*/
|
||||
if( !isView ){
|
||||
int iAddrOnce = 0;
|
||||
u8 p5 = (eOnePass==ONEPASS_OFF ? 0 : OPFLAG_FORDELETE);
|
||||
if( eOnePass==ONEPASS_MULTI ){
|
||||
iAddrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
|
||||
}
|
||||
testcase( IsVirtual(pTab) );
|
||||
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iTabCur, aToOpen,
|
||||
&iDataCur, &iIdxCur);
|
||||
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, p5, iTabCur,
|
||||
aToOpen, &iDataCur, &iIdxCur);
|
||||
assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur );
|
||||
assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 );
|
||||
if( eOnePass==ONEPASS_MULTI ) sqlite3VdbeJumpHere(v, iAddrOnce);
|
||||
|
||||
+40
-6
@@ -548,11 +548,11 @@ Expr *sqlite3PExpr(
|
||||
const Token *pToken /* Argument token */
|
||||
){
|
||||
Expr *p;
|
||||
if( op==TK_AND && pLeft && pRight && pParse->nErr==0 ){
|
||||
if( op==TK_AND && pParse->nErr==0 ){
|
||||
/* Take advantage of short-circuit false optimization for AND */
|
||||
p = sqlite3ExprAnd(pParse->db, pLeft, pRight);
|
||||
}else{
|
||||
p = sqlite3ExprAlloc(pParse->db, op, pToken, 1);
|
||||
p = sqlite3ExprAlloc(pParse->db, op & TKFLG_MASK, pToken, 1);
|
||||
sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
|
||||
}
|
||||
if( p ) {
|
||||
@@ -1415,6 +1415,22 @@ int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){
|
||||
return exprIsConst(p, 4+isInit, 0);
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_CURSOR_HINTS
|
||||
/*
|
||||
** Walk an expression tree. Return 1 if the expression contains a
|
||||
** subquery of some kind. Return 0 if there are no subqueries.
|
||||
*/
|
||||
int sqlite3ExprContainsSubquery(Expr *p){
|
||||
Walker w;
|
||||
memset(&w, 0, sizeof(w));
|
||||
w.eCode = 1;
|
||||
w.xExprCallback = sqlite3ExprWalkNoop;
|
||||
w.xSelectCallback = selectNodeIsConstant;
|
||||
sqlite3WalkExpr(&w, p);
|
||||
return w.eCode==0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** If the expression p codes a constant integer that is small enough
|
||||
** to fit in a 32-bit integer, return 1 and put the value of the integer
|
||||
@@ -2481,9 +2497,12 @@ void sqlite3ExprCodeGetColumnOfTable(
|
||||
|
||||
/*
|
||||
** Generate code that will extract the iColumn-th column from
|
||||
** table pTab and store the column value in a register. An effort
|
||||
** is made to store the column value in register iReg, but this is
|
||||
** not guaranteed. The location of the column value is returned.
|
||||
** table pTab and store the column value in a register.
|
||||
**
|
||||
** An effort is made to store the column value in register iReg. This
|
||||
** is not garanteeed for GetColumn() - the result can be stored in
|
||||
** any register. But the result is guaranteed to land in register iReg
|
||||
** for GetColumnToReg().
|
||||
**
|
||||
** There must be an open cursor to pTab in iTable when this routine
|
||||
** is called. If iColumn<0 then code is generated that extracts the rowid.
|
||||
@@ -2494,7 +2513,7 @@ int sqlite3ExprCodeGetColumn(
|
||||
int iColumn, /* Index of the table column */
|
||||
int iTable, /* The cursor pointing to the table */
|
||||
int iReg, /* Store results here */
|
||||
u8 p5 /* P5 value for OP_Column */
|
||||
u8 p5 /* P5 value for OP_Column + FLAGS */
|
||||
){
|
||||
Vdbe *v = pParse->pVdbe;
|
||||
int i;
|
||||
@@ -2516,6 +2535,17 @@ int sqlite3ExprCodeGetColumn(
|
||||
}
|
||||
return iReg;
|
||||
}
|
||||
void sqlite3ExprCodeGetColumnToReg(
|
||||
Parse *pParse, /* Parsing and code generating context */
|
||||
Table *pTab, /* Description of the table we are reading from */
|
||||
int iColumn, /* Index of the table column */
|
||||
int iTable, /* The cursor pointing to the table */
|
||||
int iReg /* Store results here */
|
||||
){
|
||||
int r1 = sqlite3ExprCodeGetColumn(pParse, pTab, iColumn, iTable, iReg, 0);
|
||||
if( r1!=iReg ) sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, r1, iReg);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Clear all column cache entries.
|
||||
@@ -3342,6 +3372,10 @@ void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){
|
||||
**
|
||||
** The SQLITE_ECEL_FACTOR argument allows constant arguments to be
|
||||
** factored out into initialization code.
|
||||
**
|
||||
** The SQLITE_ECEL_REF flag means that expressions in the list with
|
||||
** ExprList.a[].u.x.iOrderByCol>0 have already been evaluated and stored
|
||||
** in registers at srcReg, and so the value can be copied from there.
|
||||
*/
|
||||
int sqlite3ExprCodeExprList(
|
||||
Parse *pParse, /* Parsing context */
|
||||
|
||||
+5
-2
@@ -762,7 +762,7 @@ void sqlite3Insert(
|
||||
/* If this is not a view, open the table and and all indices */
|
||||
if( !isView ){
|
||||
int nIdx;
|
||||
nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, -1, 0,
|
||||
nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0,
|
||||
&iDataCur, &iIdxCur);
|
||||
aRegIdx = sqlite3DbMallocRaw(db, sizeof(int)*(nIdx+1));
|
||||
if( aRegIdx==0 ){
|
||||
@@ -1422,7 +1422,7 @@ void sqlite3GenerateConstraintChecks(
|
||||
}else{
|
||||
x = iField + regNewData + 1;
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_SCopy, x, regIdx+i);
|
||||
sqlite3VdbeAddOp2(v, iField<0 ? OP_IntCopy : OP_SCopy, x, regIdx+i);
|
||||
VdbeComment((v, "%s", iField<0 ? "rowid" : pTab->aCol[iField].zName));
|
||||
}
|
||||
}
|
||||
@@ -1650,6 +1650,7 @@ int sqlite3OpenTableAndIndices(
|
||||
Parse *pParse, /* Parsing context */
|
||||
Table *pTab, /* Table to be opened */
|
||||
int op, /* OP_OpenRead or OP_OpenWrite */
|
||||
u8 p5, /* P5 value for OP_Open* instructions */
|
||||
int iBase, /* Use this for the table cursor, if there is one */
|
||||
u8 *aToOpen, /* If not NULL: boolean for each table and index */
|
||||
int *piDataCur, /* Write the database source cursor number here */
|
||||
@@ -1662,6 +1663,7 @@ int sqlite3OpenTableAndIndices(
|
||||
Vdbe *v;
|
||||
|
||||
assert( op==OP_OpenRead || op==OP_OpenWrite );
|
||||
assert( op==OP_OpenWrite || p5==0 );
|
||||
if( IsVirtual(pTab) ){
|
||||
/* This routine is a no-op for virtual tables. Leave the output
|
||||
** variables *piDataCur and *piIdxCur uninitialized so that valgrind
|
||||
@@ -1689,6 +1691,7 @@ int sqlite3OpenTableAndIndices(
|
||||
if( aToOpen==0 || aToOpen[i+1] ){
|
||||
sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb);
|
||||
sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
|
||||
sqlite3VdbeChangeP5(v, p5);
|
||||
VdbeComment((v, "%s", pIdx->zName));
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -615,7 +615,7 @@ int sqlite3_enable_load_extension(sqlite3 *db, int onoff){
|
||||
** dummy pointer.
|
||||
*/
|
||||
#ifdef SQLITE_OMIT_LOAD_EXTENSION
|
||||
static const sqlite3_api_routines sqlite3Apis;
|
||||
static const sqlite3_api_routines sqlite3Apis = { 0 };
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
+45
@@ -740,6 +740,36 @@ int sqlite3_db_release_memory(sqlite3 *db){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Flush any dirty pages in the pager-cache for any attached database
|
||||
** to disk.
|
||||
*/
|
||||
int sqlite3_db_cacheflush(sqlite3 *db){
|
||||
int i;
|
||||
int rc = SQLITE_OK;
|
||||
int bSeenBusy = 0;
|
||||
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
sqlite3BtreeEnterAll(db);
|
||||
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
|
||||
Btree *pBt = db->aDb[i].pBt;
|
||||
if( pBt && sqlite3BtreeIsInTrans(pBt) ){
|
||||
Pager *pPager = sqlite3BtreePager(pBt);
|
||||
rc = sqlite3PagerFlush(pPager);
|
||||
if( rc==SQLITE_BUSY ){
|
||||
bSeenBusy = 1;
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlite3BtreeLeaveAll(db);
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return ((rc==SQLITE_OK && bSeenBusy) ? SQLITE_BUSY : rc);
|
||||
}
|
||||
|
||||
/*
|
||||
** Configuration settings for an individual database connection
|
||||
*/
|
||||
@@ -2954,6 +2984,21 @@ opendb_out:
|
||||
void *pArg = sqlite3GlobalConfig.pSqllogArg;
|
||||
sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0);
|
||||
}
|
||||
#endif
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
if( rc==SQLITE_OK ){
|
||||
const char *zHexKey = sqlite3_uri_parameter(zOpen, "hexkey");
|
||||
if( zHexKey && zHexKey[0] ){
|
||||
u8 iByte;
|
||||
int i;
|
||||
char zKey[40];
|
||||
for(i=0, iByte=0; i<sizeof(zKey)*2 && sqlite3Isxdigit(zHexKey[i]); i++){
|
||||
iByte = (iByte<<4) + sqlite3HexToInt(zHexKey[i]);
|
||||
if( (i&1)!=0 ) zKey[i/2] = iByte;
|
||||
}
|
||||
sqlite3_key_v2(db, 0, zKey, i/2);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return rc & 0xff;
|
||||
}
|
||||
|
||||
+6
-7
@@ -131,9 +131,7 @@ int sqlite3MallocInit(void){
|
||||
sqlite3MemSetDefault();
|
||||
}
|
||||
memset(&mem0, 0, sizeof(mem0));
|
||||
if( sqlite3GlobalConfig.bCoreMutex ){
|
||||
mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
|
||||
}
|
||||
mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
|
||||
if( sqlite3GlobalConfig.pScratch && sqlite3GlobalConfig.szScratch>=100
|
||||
&& sqlite3GlobalConfig.nScratch>0 ){
|
||||
int i, n, sz;
|
||||
@@ -224,7 +222,7 @@ static int mallocWithAlarm(int n, void **pp){
|
||||
void *p;
|
||||
assert( sqlite3_mutex_held(mem0.mutex) );
|
||||
nFull = sqlite3GlobalConfig.m.xRoundup(n);
|
||||
sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n);
|
||||
sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n);
|
||||
if( mem0.alarmThreshold>0 ){
|
||||
sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
|
||||
if( nUsed >= mem0.alarmThreshold - nFull ){
|
||||
@@ -316,7 +314,7 @@ void *sqlite3ScratchMalloc(int n){
|
||||
assert( n>0 );
|
||||
|
||||
sqlite3_mutex_enter(mem0.mutex);
|
||||
sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n);
|
||||
sqlite3StatusHighwater(SQLITE_STATUS_SCRATCH_SIZE, n);
|
||||
if( mem0.nScratchFree && sqlite3GlobalConfig.szScratch>=n ){
|
||||
p = mem0.pScratchFree;
|
||||
mem0.pScratchFree = mem0.pScratchFree->pNext;
|
||||
@@ -411,6 +409,7 @@ int sqlite3MallocSize(void *p){
|
||||
return sqlite3GlobalConfig.m.xSize(p);
|
||||
}
|
||||
int sqlite3DbMallocSize(sqlite3 *db, void *p){
|
||||
assert( p!=0 );
|
||||
if( db==0 || !isLookaside(db,p) ){
|
||||
#if SQLITE_DEBUG
|
||||
if( db==0 ){
|
||||
@@ -430,7 +429,7 @@ int sqlite3DbMallocSize(sqlite3 *db, void *p){
|
||||
sqlite3_uint64 sqlite3_msize(void *p){
|
||||
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
|
||||
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
|
||||
return (sqlite3_uint64)sqlite3GlobalConfig.m.xSize(p);
|
||||
return p ? sqlite3GlobalConfig.m.xSize(p) : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -518,7 +517,7 @@ void *sqlite3Realloc(void *pOld, u64 nBytes){
|
||||
pNew = pOld;
|
||||
}else if( sqlite3GlobalConfig.bMemstat ){
|
||||
sqlite3_mutex_enter(mem0.mutex);
|
||||
sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes);
|
||||
sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes);
|
||||
nDiff = nNew - nOld;
|
||||
if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >=
|
||||
mem0.alarmThreshold-nDiff ){
|
||||
|
||||
+3
-2
@@ -172,10 +172,11 @@ static void sqlite3MemFree(void *pPrior){
|
||||
*/
|
||||
static int sqlite3MemSize(void *pPrior){
|
||||
#ifdef SQLITE_MALLOCSIZE
|
||||
return pPrior ? (int)SQLITE_MALLOCSIZE(pPrior) : 0;
|
||||
assert( pPrior!=0 );
|
||||
return (int)SQLITE_MALLOCSIZE(pPrior);
|
||||
#else
|
||||
sqlite3_int64 *p;
|
||||
if( pPrior==0 ) return 0;
|
||||
assert( pPrior!=0 );
|
||||
p = (sqlite3_int64*)pPrior;
|
||||
p--;
|
||||
return (int)p[0];
|
||||
|
||||
+1
-1
@@ -476,7 +476,7 @@ static void memsys3FreeUnsafe(void *pOld){
|
||||
*/
|
||||
static int memsys3Size(void *p){
|
||||
Mem3Block *pBlock;
|
||||
if( p==0 ) return 0;
|
||||
assert( p!=0 );
|
||||
pBlock = (Mem3Block*)p;
|
||||
assert( (pBlock[-1].u.hdr.size4x&1)!=0 );
|
||||
return (pBlock[-1].u.hdr.size4x&~3)*2 - 4;
|
||||
|
||||
+5
-6
@@ -200,12 +200,11 @@ static void memsys5Leave(void){
|
||||
** works for chunks that are currently checked out.
|
||||
*/
|
||||
static int memsys5Size(void *p){
|
||||
int iSize = 0;
|
||||
if( p ){
|
||||
int i = (int)(((u8 *)p-mem5.zPool)/mem5.szAtom);
|
||||
assert( i>=0 && i<mem5.nBlock );
|
||||
iSize = mem5.szAtom * (1 << (mem5.aCtrl[i]&CTRL_LOGSIZE));
|
||||
}
|
||||
int iSize, i;
|
||||
assert( p!=0 );
|
||||
i = (int)(((u8 *)p-mem5.zPool)/mem5.szAtom);
|
||||
assert( i>=0 && i<mem5.nBlock );
|
||||
iSize = mem5.szAtom * (1 << (mem5.aCtrl[i]&CTRL_LOGSIZE));
|
||||
return iSize;
|
||||
}
|
||||
|
||||
|
||||
+47
-7
@@ -464,6 +464,9 @@ static struct unix_syscall {
|
||||
{ "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 },
|
||||
#define osGetpagesize ((int(*)(void))aSyscall[24].pCurrent)
|
||||
|
||||
{ "readlink", (sqlite3_syscall_ptr)readlink, 0 },
|
||||
#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[25].pCurrent)
|
||||
|
||||
#endif
|
||||
|
||||
}; /* End of the overrideable system calls */
|
||||
@@ -6026,6 +6029,7 @@ static int unixFullPathname(
|
||||
int nOut, /* Size of output buffer in bytes */
|
||||
char *zOut /* Output buffer */
|
||||
){
|
||||
int nByte;
|
||||
|
||||
/* 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
|
||||
@@ -6037,17 +6041,53 @@ static int unixFullPathname(
|
||||
assert( pVfs->mxPathname==MAX_PATHNAME );
|
||||
UNUSED_PARAMETER(pVfs);
|
||||
|
||||
zOut[nOut-1] = '\0';
|
||||
if( zPath[0]=='/' ){
|
||||
sqlite3_snprintf(nOut, zOut, "%s", zPath);
|
||||
/* 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);
|
||||
}
|
||||
zOut[nOut-1] = '\0';
|
||||
sqlite3_snprintf(nOut-1, zOut, "%s", zPath);
|
||||
nByte = sqlite3Strlen30(zOut);
|
||||
}else{
|
||||
zOut[nByte] = '\0';
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
if( zOut[0]!='/' ){
|
||||
int nCwd;
|
||||
if( osGetcwd(zOut, nOut-1)==0 ){
|
||||
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 = (int)strlen(zOut);
|
||||
sqlite3_snprintf(nOut-nCwd, &zOut[nCwd], "/%s", zPath);
|
||||
nCwd = sqlite3Strlen30(zOut);
|
||||
assert( nCwd<=nRem-1 );
|
||||
zOut[nCwd] = '/';
|
||||
memmove(&zOut[nCwd+1], &zOut[nRem], nByte+1);
|
||||
}
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -7542,7 +7582,7 @@ int sqlite3_os_init(void){
|
||||
|
||||
/* Double-check that the aSyscall[] array has been constructed
|
||||
** correctly. See ticket [bb3a86e890c8e96ab] */
|
||||
assert( ArraySize(aSyscall)==25 );
|
||||
assert( ArraySize(aSyscall)==26 );
|
||||
|
||||
/* Register all VFSes defined in the aVfs[] array */
|
||||
for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
|
||||
|
||||
+39
-16
@@ -2333,7 +2333,7 @@ static int pager_playback_one_page(
|
||||
assert( isSavepnt );
|
||||
assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)==0 );
|
||||
pPager->doNotSpill |= SPILLFLAG_ROLLBACK;
|
||||
rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1);
|
||||
rc = sqlite3PagerGet(pPager, pgno, &pPg, 1);
|
||||
assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 );
|
||||
pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK;
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
@@ -4473,6 +4473,25 @@ static int pagerStress(void *p, PgHdr *pPg){
|
||||
return pager_error(pPager, rc);
|
||||
}
|
||||
|
||||
/*
|
||||
** Flush all unreferenced dirty pages to disk.
|
||||
*/
|
||||
int sqlite3PagerFlush(Pager *pPager){
|
||||
int rc = pPager->errCode;
|
||||
if( !MEMDB ){
|
||||
PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache);
|
||||
assert( assert_pager_state(pPager) );
|
||||
while( rc==SQLITE_OK && pList ){
|
||||
PgHdr *pNext = pList->pDirty;
|
||||
if( pList->nRef==0 ){
|
||||
rc = pagerStress((void*)pPager, pList);
|
||||
}
|
||||
pList = pNext;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Allocate and initialize a new Pager object and put a pointer to it
|
||||
@@ -4950,7 +4969,7 @@ static int hasHotJournal(Pager *pPager, int *pExists){
|
||||
|
||||
/*
|
||||
** This function is called to obtain a shared lock on the database file.
|
||||
** It is illegal to call sqlite3PagerAcquire() until after this function
|
||||
** It is illegal to call sqlite3PagerGet() until after this function
|
||||
** has been successfully called. If a shared-lock is already held when
|
||||
** this function is called, it is a no-op.
|
||||
**
|
||||
@@ -5253,7 +5272,7 @@ static void pagerUnlockIfUnused(Pager *pPager){
|
||||
** Since Lookup() never goes to disk, it never has to deal with locks
|
||||
** or journal files.
|
||||
*/
|
||||
int sqlite3PagerAcquire(
|
||||
int sqlite3PagerGet(
|
||||
Pager *pPager, /* The pager open on the database file */
|
||||
Pgno pgno, /* Page number to fetch */
|
||||
DbPage **ppPage, /* Write a pointer to the page here */
|
||||
@@ -5839,7 +5858,7 @@ static SQLITE_NOINLINE int pagerWriteLargeSector(PgHdr *pPg){
|
||||
PgHdr *pPage;
|
||||
if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){
|
||||
if( pg!=PAGER_MJ_PGNO(pPager) ){
|
||||
rc = sqlite3PagerGet(pPager, pg, &pPage);
|
||||
rc = sqlite3PagerGet(pPager, pg, &pPage, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = pager_write(pPage);
|
||||
if( pPage->flags&PGHDR_NEED_SYNC ){
|
||||
@@ -5896,9 +5915,10 @@ int sqlite3PagerWrite(PgHdr *pPg){
|
||||
Pager *pPager = pPg->pPager;
|
||||
assert( (pPg->flags & PGHDR_MMAP)==0 );
|
||||
assert( pPager->eState>=PAGER_WRITER_LOCKED );
|
||||
assert( pPager->eState!=PAGER_ERROR );
|
||||
assert( assert_pager_state(pPager) );
|
||||
if( (pPg->flags & PGHDR_WRITEABLE)!=0 && pPager->dbSize>=pPg->pgno ){
|
||||
if( pPager->errCode ){
|
||||
return pPager->errCode;
|
||||
}else if( (pPg->flags & PGHDR_WRITEABLE)!=0 && pPager->dbSize>=pPg->pgno ){
|
||||
if( pPager->nSavepoint ) return subjournalPageIfRequired(pPg);
|
||||
return SQLITE_OK;
|
||||
}else if( pPager->sectorSize > (u32)pPager->pageSize ){
|
||||
@@ -5998,7 +6018,7 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
|
||||
assert( !pPager->tempFile && isOpen(pPager->fd) );
|
||||
|
||||
/* Open page 1 of the file for writing. */
|
||||
rc = sqlite3PagerGet(pPager, 1, &pPgHdr);
|
||||
rc = sqlite3PagerGet(pPager, 1, &pPgHdr, 0);
|
||||
assert( pPgHdr==0 || rc==SQLITE_OK );
|
||||
|
||||
/* If page one was fetched successfully, and this function is not
|
||||
@@ -6076,14 +6096,17 @@ int sqlite3PagerSync(Pager *pPager, const char *zMaster){
|
||||
** returned.
|
||||
*/
|
||||
int sqlite3PagerExclusiveLock(Pager *pPager){
|
||||
int rc = SQLITE_OK;
|
||||
assert( pPager->eState==PAGER_WRITER_CACHEMOD
|
||||
|| pPager->eState==PAGER_WRITER_DBMOD
|
||||
|| pPager->eState==PAGER_WRITER_LOCKED
|
||||
);
|
||||
int rc = pPager->errCode;
|
||||
assert( assert_pager_state(pPager) );
|
||||
if( 0==pagerUseWal(pPager) ){
|
||||
rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
|
||||
if( rc==SQLITE_OK ){
|
||||
assert( pPager->eState==PAGER_WRITER_CACHEMOD
|
||||
|| pPager->eState==PAGER_WRITER_DBMOD
|
||||
|| pPager->eState==PAGER_WRITER_LOCKED
|
||||
);
|
||||
assert( assert_pager_state(pPager) );
|
||||
if( 0==pagerUseWal(pPager) ){
|
||||
rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -6150,7 +6173,7 @@ int sqlite3PagerCommitPhaseOne(
|
||||
if( pList==0 ){
|
||||
/* Must have at least one page for the WAL commit flag.
|
||||
** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */
|
||||
rc = sqlite3PagerGet(pPager, 1, &pPageOne);
|
||||
rc = sqlite3PagerGet(pPager, 1, &pPageOne, 0);
|
||||
pList = pPageOne;
|
||||
pList->pDirty = 0;
|
||||
}
|
||||
@@ -6855,7 +6878,7 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){
|
||||
** the journal file twice, but that is not a problem.
|
||||
*/
|
||||
PgHdr *pPgHdr;
|
||||
rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr);
|
||||
rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
if( needSyncPgno<=pPager->dbOrigSize ){
|
||||
assert( pPager->pTmpSpace!=0 );
|
||||
|
||||
+3
-3
@@ -79,7 +79,7 @@ typedef struct PgHdr DbPage;
|
||||
#define PAGER_JOURNALMODE_WAL 5 /* Use write-ahead logging */
|
||||
|
||||
/*
|
||||
** Flags that make up the mask passed to sqlite3PagerAcquire().
|
||||
** Flags that make up the mask passed to sqlite3PagerGet().
|
||||
*/
|
||||
#define PAGER_GET_NOCONTENT 0x01 /* Do not load data from disk */
|
||||
#define PAGER_GET_READONLY 0x02 /* Read-only page is acceptable */
|
||||
@@ -132,10 +132,10 @@ int sqlite3PagerGetJournalMode(Pager*);
|
||||
int sqlite3PagerOkToChangeJournalMode(Pager*);
|
||||
i64 sqlite3PagerJournalSizeLimit(Pager *, i64);
|
||||
sqlite3_backup **sqlite3PagerBackupPtr(Pager*);
|
||||
int sqlite3PagerFlush(Pager*);
|
||||
|
||||
/* Functions used to obtain and release page references. */
|
||||
int sqlite3PagerAcquire(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag);
|
||||
#define sqlite3PagerGet(A,B,C) sqlite3PagerAcquire(A,B,C,0)
|
||||
int sqlite3PagerGet(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag);
|
||||
DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno);
|
||||
void sqlite3PagerRef(DbPage*);
|
||||
void sqlite3PagerUnref(DbPage*);
|
||||
|
||||
+13
-6
@@ -929,6 +929,13 @@ term(A) ::= CTIME_KW(OP). {
|
||||
pOut->zStart = pLeft->zStart;
|
||||
pOut->zEnd = pRight->zEnd;
|
||||
}
|
||||
|
||||
/* If doNot is true, then add a TK_NOT Expr-node wrapper around the
|
||||
** outside of *ppExpr.
|
||||
*/
|
||||
static void exprNot(Parse *pParse, int doNot, Expr **ppExpr){
|
||||
if( doNot ) *ppExpr = sqlite3PExpr(pParse, TK_NOT, *ppExpr, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
expr(A) ::= expr(X) AND(OP) expr(Y). {spanBinaryExpr(&A,pParse,@OP,&X,&Y);}
|
||||
@@ -951,7 +958,7 @@ expr(A) ::= expr(X) likeop(OP) expr(Y). [LIKE_KW] {
|
||||
pList = sqlite3ExprListAppend(pParse,0, Y.pExpr);
|
||||
pList = sqlite3ExprListAppend(pParse,pList, X.pExpr);
|
||||
A.pExpr = sqlite3ExprFunction(pParse, pList, &OP.eOperator);
|
||||
if( OP.bNot ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0);
|
||||
exprNot(pParse, OP.bNot, &A.pExpr);
|
||||
A.zStart = X.zStart;
|
||||
A.zEnd = Y.zEnd;
|
||||
if( A.pExpr ) A.pExpr->flags |= EP_InfixFunc;
|
||||
@@ -962,7 +969,7 @@ expr(A) ::= expr(X) likeop(OP) expr(Y) ESCAPE expr(E). [LIKE_KW] {
|
||||
pList = sqlite3ExprListAppend(pParse,pList, X.pExpr);
|
||||
pList = sqlite3ExprListAppend(pParse,pList, E.pExpr);
|
||||
A.pExpr = sqlite3ExprFunction(pParse, pList, &OP.eOperator);
|
||||
if( OP.bNot ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0);
|
||||
exprNot(pParse, OP.bNot, &A.pExpr);
|
||||
A.zStart = X.zStart;
|
||||
A.zEnd = E.zEnd;
|
||||
if( A.pExpr ) A.pExpr->flags |= EP_InfixFunc;
|
||||
@@ -1052,7 +1059,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
}else{
|
||||
sqlite3ExprListDelete(pParse->db, pList);
|
||||
}
|
||||
if( N ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0);
|
||||
exprNot(pParse, N, &A.pExpr);
|
||||
A.zStart = W.zStart;
|
||||
A.zEnd = Y.zEnd;
|
||||
}
|
||||
@@ -1107,7 +1114,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
}else{
|
||||
sqlite3ExprListDelete(pParse->db, Y);
|
||||
}
|
||||
if( N ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0);
|
||||
exprNot(pParse, N, &A.pExpr);
|
||||
}
|
||||
A.zStart = X.zStart;
|
||||
A.zEnd = &E.z[E.n];
|
||||
@@ -1133,7 +1140,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
}else{
|
||||
sqlite3SelectDelete(pParse->db, Y);
|
||||
}
|
||||
if( N ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0);
|
||||
exprNot(pParse, N, &A.pExpr);
|
||||
A.zStart = X.zStart;
|
||||
A.zEnd = &E.z[E.n];
|
||||
}
|
||||
@@ -1147,7 +1154,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
}else{
|
||||
sqlite3SrcListDelete(pParse->db, pSrc);
|
||||
}
|
||||
if( N ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0);
|
||||
exprNot(pParse, N, &A.pExpr);
|
||||
A.zStart = X.zStart;
|
||||
A.zEnd = Z.z ? &Z.z[Z.n] : &Y.z[Y.n];
|
||||
}
|
||||
|
||||
+2
-2
@@ -320,7 +320,7 @@ static void *pcache1Alloc(int nByte){
|
||||
pcache1.nFreeSlot--;
|
||||
pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
|
||||
assert( pcache1.nFreeSlot>=0 );
|
||||
sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
|
||||
sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
|
||||
sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1);
|
||||
}
|
||||
sqlite3_mutex_leave(pcache1.mutex);
|
||||
@@ -334,7 +334,7 @@ static void *pcache1Alloc(int nByte){
|
||||
if( p ){
|
||||
int sz = sqlite3MallocSize(p);
|
||||
sqlite3_mutex_enter(pcache1.mutex);
|
||||
sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
|
||||
sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
|
||||
sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
|
||||
sqlite3_mutex_leave(pcache1.mutex);
|
||||
}
|
||||
|
||||
+1
-1
@@ -1465,7 +1465,7 @@ void sqlite3Pragma(
|
||||
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
sqlite3ExprCacheClear(pParse);
|
||||
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead,
|
||||
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
|
||||
1, 0, &iDataCur, &iIdxCur);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, 7);
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||
|
||||
+5
-10
@@ -4452,7 +4452,7 @@ static int selectExpander(Walker *pWalker, Select *p){
|
||||
** Walker.xSelectCallback is set to do something useful for every
|
||||
** subquery in the parser tree.
|
||||
*/
|
||||
static int exprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
|
||||
int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
|
||||
UNUSED_PARAMETER2(NotUsed, NotUsed2);
|
||||
return WRC_Continue;
|
||||
}
|
||||
@@ -4473,7 +4473,7 @@ static int exprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
|
||||
static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
|
||||
Walker w;
|
||||
memset(&w, 0, sizeof(w));
|
||||
w.xExprCallback = exprWalkNoop;
|
||||
w.xExprCallback = sqlite3ExprWalkNoop;
|
||||
w.pParse = pParse;
|
||||
if( pParse->hasCompound ){
|
||||
w.xSelectCallback = convertCompoundSelectToSubquery;
|
||||
@@ -4540,7 +4540,7 @@ static void sqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){
|
||||
Walker w;
|
||||
memset(&w, 0, sizeof(w));
|
||||
w.xSelectCallback2 = selectAddSubqueryTypeInfo;
|
||||
w.xExprCallback = exprWalkNoop;
|
||||
w.xExprCallback = sqlite3ExprWalkNoop;
|
||||
w.pParse = pParse;
|
||||
sqlite3WalkSelect(&w, pSelect);
|
||||
#endif
|
||||
@@ -5295,13 +5295,8 @@ int sqlite3Select(
|
||||
struct AggInfo_col *pCol = &sAggInfo.aCol[i];
|
||||
if( pCol->iSorterColumn>=j ){
|
||||
int r1 = j + regBase;
|
||||
int r2;
|
||||
|
||||
r2 = sqlite3ExprCodeGetColumn(pParse,
|
||||
pCol->pTab, pCol->iColumn, pCol->iTable, r1, 0);
|
||||
if( r1!=r2 ){
|
||||
sqlite3VdbeAddOp2(v, OP_SCopy, r2, r1);
|
||||
}
|
||||
sqlite3ExprCodeGetColumnToReg(pParse,
|
||||
pCol->pTab, pCol->iColumn, pCol->iTable, r1);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
+32
-1
@@ -478,6 +478,7 @@ int sqlite3_exec(
|
||||
#define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8))
|
||||
#define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8))
|
||||
#define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8))
|
||||
#define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8))
|
||||
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
|
||||
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
|
||||
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
|
||||
@@ -6572,7 +6573,8 @@ int sqlite3_status64(
|
||||
** The value written into the *pCurrent parameter is undefined.</dd>)^
|
||||
**
|
||||
** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt>
|
||||
** <dd>This parameter records the deepest parser stack. It is only
|
||||
** <dd>The *pHighwater parameter records the deepest parser stack.
|
||||
** The *pCurrent value is undefined. The *pHighwater value is only
|
||||
** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].</dd>)^
|
||||
** </dl>
|
||||
**
|
||||
@@ -7790,6 +7792,35 @@ int sqlite3_stmt_scanstatus(
|
||||
*/
|
||||
void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Flush caches to disk mid-transaction
|
||||
**
|
||||
** If a write-transaction is open when this function is called, any dirty
|
||||
** pages in the pager-cache that are not currently in use are written out
|
||||
** to disk. A dirty page may be in use if a database cursor created by an
|
||||
** active SQL statement is reading from it, or if it is page 1 of a database
|
||||
** file (page 1 is always "in use"). Dirty pages are flushed for all
|
||||
** databases - "main", "temp" and any attached databases.
|
||||
**
|
||||
** If this function needs to obtain extra database locks before dirty pages
|
||||
** can be flushed to disk, it does so. If said locks cannot be obtained
|
||||
** immediately and there is a busy-handler callback configured, it is invoked
|
||||
** in the usual manner. If the required lock still cannot be obtained, then
|
||||
** the database is skipped and an attempt made to flush any dirty pages
|
||||
** belonging to the next (if any) database. If any databases are skipped
|
||||
** because locks cannot be obtained, but no other error occurs, this
|
||||
** function returns SQLITE_BUSY.
|
||||
**
|
||||
** If any other error occurs while flushing dirty pages to disk (for
|
||||
** example an IO error or out-of-memory condition), then processing is
|
||||
** abandoned and an SQLite error code returned to the caller immediately.
|
||||
**
|
||||
** Otherwise, if no error occurs, SQLITE_OK is returned.
|
||||
**
|
||||
** This function does not set the database handle error code or message
|
||||
** returned by the sqlite3_errcode() and sqlite3_errmsg() functions.
|
||||
*/
|
||||
int sqlite3_db_cacheflush(sqlite3*);
|
||||
|
||||
/*
|
||||
** Undo the hack that converts floating point types to integer for
|
||||
|
||||
+11
-3
@@ -1310,6 +1310,7 @@ struct sqlite3 {
|
||||
#define SQLITE_Transitive 0x0200 /* Transitive constraints */
|
||||
#define SQLITE_OmitNoopJoin 0x0400 /* Omit unused tables in joins */
|
||||
#define SQLITE_Stat34 0x0800 /* Use STAT3 or STAT4 data */
|
||||
#define SQLITE_CursorHints 0x2000 /* Add OP_CursorHint opcodes */
|
||||
#define SQLITE_AllOpts 0xffff /* All optimizations */
|
||||
|
||||
/*
|
||||
@@ -2794,7 +2795,8 @@ struct AuthContext {
|
||||
#define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */
|
||||
#define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
|
||||
#define OPFLAG_SEEKEQ 0x02 /* OP_Open** cursor uses EQ seek only */
|
||||
#define OPFLAG_P2ISREG 0x04 /* P2 to OP_Open** is a register number */
|
||||
#define OPFLAG_FORDELETE 0x08 /* OP_Open is opening for-delete csr */
|
||||
#define OPFLAG_P2ISREG 0x10 /* P2 to OP_Open** is a register number */
|
||||
#define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */
|
||||
|
||||
/*
|
||||
@@ -3023,6 +3025,7 @@ struct Walker {
|
||||
int iCur; /* A cursor number */
|
||||
SrcList *pSrcList; /* FROM clause */
|
||||
struct SrcCount *pSrcCount; /* Counting column references */
|
||||
struct CCurHint *pCCurHint; /* Used by codeCursorHint() */
|
||||
} u;
|
||||
};
|
||||
|
||||
@@ -3032,6 +3035,7 @@ int sqlite3WalkExprList(Walker*, ExprList*);
|
||||
int sqlite3WalkSelect(Walker*, Select*);
|
||||
int sqlite3WalkSelectExpr(Walker*, Select*);
|
||||
int sqlite3WalkSelectFrom(Walker*, Select*);
|
||||
int sqlite3ExprWalkNoop(Walker*, Expr*);
|
||||
|
||||
/*
|
||||
** Return code from the parse-tree walking primitives and their
|
||||
@@ -3209,7 +3213,7 @@ const sqlite3_mem_methods *sqlite3MemGetMemsys5(void);
|
||||
sqlite3_int64 sqlite3StatusValue(int);
|
||||
void sqlite3StatusUp(int, int);
|
||||
void sqlite3StatusDown(int, int);
|
||||
void sqlite3StatusSet(int, int);
|
||||
void sqlite3StatusHighwater(int, int);
|
||||
|
||||
/* Access to mutexes used by sqlite3_status() */
|
||||
sqlite3_mutex *sqlite3Pcache1Mutex(void);
|
||||
@@ -3393,6 +3397,7 @@ int sqlite3WhereOkOnePass(WhereInfo*, int*);
|
||||
#define ONEPASS_MULTI 2 /* ONEPASS is valid for multiple rows */
|
||||
void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int);
|
||||
int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
|
||||
void sqlite3ExprCodeGetColumnToReg(Parse*, Table*, int, int, int);
|
||||
void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
|
||||
void sqlite3ExprCodeMove(Parse*, int, int, int);
|
||||
void sqlite3ExprCacheStore(Parse*, int, int, int);
|
||||
@@ -3447,6 +3452,9 @@ int sqlite3ExprIsConstant(Expr*);
|
||||
int sqlite3ExprIsConstantNotJoin(Expr*);
|
||||
int sqlite3ExprIsConstantOrFunction(Expr*, u8);
|
||||
int sqlite3ExprIsTableConstant(Expr*,int);
|
||||
#ifdef SQLITE_ENABLE_CURSOR_HINTS
|
||||
int sqlite3ExprContainsSubquery(Expr*);
|
||||
#endif
|
||||
int sqlite3ExprIsInteger(Expr*, int*);
|
||||
int sqlite3ExprCanBeNull(const Expr*);
|
||||
int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
|
||||
@@ -3459,7 +3467,7 @@ void sqlite3ResolvePartIdxLabel(Parse*,int);
|
||||
void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
|
||||
u8,u8,int,int*);
|
||||
void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int);
|
||||
int sqlite3OpenTableAndIndices(Parse*, Table*, int, int, u8*, int*, int*);
|
||||
int sqlite3OpenTableAndIndices(Parse*, Table*, int, u8, int, u8*, int*, int*);
|
||||
void sqlite3BeginWriteOperation(Parse*, int, int);
|
||||
void sqlite3MultiWrite(Parse*);
|
||||
void sqlite3MayAbort(Parse*);
|
||||
|
||||
+23
-17
@@ -19,15 +19,15 @@
|
||||
/*
|
||||
** Variables in which to record status information.
|
||||
*/
|
||||
#if SQLITE_PTRSIZE>4
|
||||
typedef sqlite3_int64 sqlite3StatValueType;
|
||||
#else
|
||||
typedef u32 sqlite3StatValueType;
|
||||
#endif
|
||||
typedef struct sqlite3StatType sqlite3StatType;
|
||||
static SQLITE_WSD struct sqlite3StatType {
|
||||
#if SQLITE_PTRSIZE>4
|
||||
sqlite3_int64 nowValue[10]; /* Current value */
|
||||
sqlite3_int64 mxValue[10]; /* Maximum value */
|
||||
#else
|
||||
u32 nowValue[10]; /* Current value */
|
||||
u32 mxValue[10]; /* Maximum value */
|
||||
#endif
|
||||
sqlite3StatValueType nowValue[10]; /* Current value */
|
||||
sqlite3StatValueType mxValue[10]; /* Maximum value */
|
||||
} sqlite3Stat = { {0,}, {0,} };
|
||||
|
||||
/*
|
||||
@@ -108,18 +108,24 @@ void sqlite3StatusDown(int op, int N){
|
||||
}
|
||||
|
||||
/*
|
||||
** Set the value of a status to X. The highwater mark is adjusted if
|
||||
** necessary. The caller must hold the appropriate mutex.
|
||||
** Adjust the highwater mark if necessary.
|
||||
** The caller must hold the appropriate mutex.
|
||||
*/
|
||||
void sqlite3StatusSet(int op, int X){
|
||||
void sqlite3StatusHighwater(int op, int X){
|
||||
sqlite3StatValueType newValue;
|
||||
wsdStatInit;
|
||||
assert( X>=0 );
|
||||
newValue = (sqlite3StatValueType)X;
|
||||
assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
|
||||
assert( op>=0 && op<ArraySize(statMutex) );
|
||||
assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
|
||||
: sqlite3MallocMutex()) );
|
||||
wsdStat.nowValue[op] = X;
|
||||
if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
|
||||
wsdStat.mxValue[op] = wsdStat.nowValue[op];
|
||||
assert( op==SQLITE_STATUS_MALLOC_SIZE
|
||||
|| op==SQLITE_STATUS_PAGECACHE_SIZE
|
||||
|| op==SQLITE_STATUS_SCRATCH_SIZE
|
||||
|| op==SQLITE_STATUS_PARSER_STACK );
|
||||
if( newValue>wsdStat.mxValue[op] ){
|
||||
wsdStat.mxValue[op] = newValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,10 +258,10 @@ int sqlite3_db_status(
|
||||
+ pSchema->idxHash.count
|
||||
+ pSchema->fkeyHash.count
|
||||
);
|
||||
nByte += sqlite3MallocSize(pSchema->tblHash.ht);
|
||||
nByte += sqlite3MallocSize(pSchema->trigHash.ht);
|
||||
nByte += sqlite3MallocSize(pSchema->idxHash.ht);
|
||||
nByte += sqlite3MallocSize(pSchema->fkeyHash.ht);
|
||||
nByte += sqlite3_msize(pSchema->tblHash.ht);
|
||||
nByte += sqlite3_msize(pSchema->trigHash.ht);
|
||||
nByte += sqlite3_msize(pSchema->idxHash.ht);
|
||||
nByte += sqlite3_msize(pSchema->fkeyHash.ht);
|
||||
|
||||
for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){
|
||||
sqlite3DeleteTrigger(db, (Trigger*)sqliteHashData(p));
|
||||
|
||||
+29
@@ -4688,6 +4688,34 @@ static int test_db_release_memory(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_db_cacheflush DB
|
||||
**
|
||||
** Attempt to flush any dirty pages to disk.
|
||||
*/
|
||||
static int test_db_cacheflush(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
sqlite3 *db;
|
||||
int rc;
|
||||
if( objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "DB");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
|
||||
rc = sqlite3_db_cacheflush(db);
|
||||
if( rc ){
|
||||
Tcl_SetResult(interp, (char *)sqlite3ErrStr(rc), TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
Tcl_ResetResult(interp);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_db_filename DB DBNAME
|
||||
**
|
||||
@@ -6876,6 +6904,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
|
||||
{ "sqlite3_release_memory", test_release_memory, 0},
|
||||
{ "sqlite3_db_release_memory", test_db_release_memory, 0},
|
||||
{ "sqlite3_db_cacheflush", test_db_cacheflush, 0},
|
||||
{ "sqlite3_db_filename", test_db_filename, 0},
|
||||
{ "sqlite3_db_readonly", test_db_readonly, 0},
|
||||
{ "sqlite3_soft_heap_limit", test_soft_heap_limit, 0},
|
||||
|
||||
+1
-1
@@ -322,7 +322,7 @@ static int page_get(
|
||||
if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR;
|
||||
rc = sqlite3PagerSharedLock(pPager);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3PagerGet(pPager, pgno, &pPage);
|
||||
rc = sqlite3PagerGet(pPager, pgno, &pPage, 0);
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
|
||||
|
||||
+52
-1
@@ -214,16 +214,19 @@ static int btree_cursor(
|
||||
pBt = sqlite3TestTextToPtr(argv[1]);
|
||||
if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR;
|
||||
if( Tcl_GetBoolean(interp, argv[3], &wrFlag) ) return TCL_ERROR;
|
||||
if( wrFlag ) wrFlag = BTREE_WRCSR;
|
||||
pCur = (BtCursor *)ckalloc(sqlite3BtreeCursorSize());
|
||||
memset(pCur, 0, sqlite3BtreeCursorSize());
|
||||
sqlite3_mutex_enter(pBt->db->mutex);
|
||||
sqlite3BtreeEnter(pBt);
|
||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||
rc = sqlite3BtreeLockTable(pBt, iTable, wrFlag);
|
||||
rc = sqlite3BtreeLockTable(pBt, iTable, !!wrFlag);
|
||||
#endif
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3BtreeCursor(pBt, iTable, wrFlag, 0, pCur);
|
||||
}
|
||||
sqlite3BtreeLeave(pBt);
|
||||
sqlite3_mutex_leave(pBt->db->mutex);
|
||||
if( rc ){
|
||||
ckfree((char *)pCur);
|
||||
Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
|
||||
@@ -256,9 +259,11 @@ static int btree_close_cursor(
|
||||
}
|
||||
pCur = sqlite3TestTextToPtr(argv[1]);
|
||||
pBt = pCur->pBtree;
|
||||
sqlite3_mutex_enter(pBt->db->mutex);
|
||||
sqlite3BtreeEnter(pBt);
|
||||
rc = sqlite3BtreeCloseCursor(pCur);
|
||||
sqlite3BtreeLeave(pBt);
|
||||
sqlite3_mutex_leave(pBt->db->mutex);
|
||||
ckfree((char *)pCur);
|
||||
if( rc ){
|
||||
Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
|
||||
@@ -598,6 +603,50 @@ static int btree_set_cache_size(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** usage: btree_insert CSR ?KEY? VALUE
|
||||
**
|
||||
** Set the size of the cache used by btree $ID.
|
||||
*/
|
||||
static int btree_insert(
|
||||
ClientData clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *const objv[]
|
||||
){
|
||||
BtCursor *pCur;
|
||||
int rc;
|
||||
void *pKey = 0;
|
||||
int nKey = 0;
|
||||
void *pData = 0;
|
||||
int nData = 0;
|
||||
|
||||
if( objc!=4 && objc!=3 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?-intkey? CSR KEY VALUE");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( objc==4 ){
|
||||
if( Tcl_GetIntFromObj(interp, objv[2], &nKey) ) return TCL_ERROR;
|
||||
pData = (void*)Tcl_GetByteArrayFromObj(objv[3], &nData);
|
||||
}else{
|
||||
pKey = (void*)Tcl_GetByteArrayFromObj(objv[2], &nKey);
|
||||
}
|
||||
pCur = (BtCursor*)sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
|
||||
|
||||
sqlite3_mutex_enter(pCur->pBtree->db->mutex);
|
||||
sqlite3BtreeEnter(pCur->pBtree);
|
||||
rc = sqlite3BtreeInsert(pCur, pKey, nKey, pData, nData, 0, 0, 0);
|
||||
sqlite3BtreeLeave(pCur->pBtree);
|
||||
sqlite3_mutex_leave(pCur->pBtree->db->mutex);
|
||||
|
||||
Tcl_ResetResult(interp);
|
||||
if( rc ){
|
||||
Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@@ -629,5 +678,7 @@ int Sqlitetest3_Init(Tcl_Interp *interp){
|
||||
Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
|
||||
}
|
||||
|
||||
Tcl_CreateObjCommand(interp, "btree_insert", btree_insert, 0, 0);
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -119,6 +119,12 @@ static void set_options(Tcl_Interp *interp){
|
||||
Tcl_SetVar2(interp, "sqlite_options", "8_3_names", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_ENABLE_CURSOR_HINTS
|
||||
Tcl_SetVar2(interp, "sqlite_options", "cursorhints", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "cursorhints", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_ENABLE_MEMSYS3
|
||||
Tcl_SetVar2(interp, "sqlite_options", "mem3", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
|
||||
+1
-1
@@ -467,7 +467,7 @@ abort_parse:
|
||||
}
|
||||
#ifdef YYTRACKMAXSTACKDEPTH
|
||||
sqlite3_mutex_enter(sqlite3MallocMutex());
|
||||
sqlite3StatusSet(SQLITE_STATUS_PARSER_STACK,
|
||||
sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK,
|
||||
sqlite3ParserStackPeak(pEngine)
|
||||
);
|
||||
sqlite3_mutex_leave(sqlite3MallocMutex());
|
||||
|
||||
+2
-2
@@ -429,7 +429,7 @@ void sqlite3Update(
|
||||
if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0;
|
||||
if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0;
|
||||
}
|
||||
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iBaseCur, aToOpen,
|
||||
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, aToOpen,
|
||||
0, 0);
|
||||
}
|
||||
|
||||
@@ -522,7 +522,7 @@ void sqlite3Update(
|
||||
*/
|
||||
testcase( i==31 );
|
||||
testcase( i==32 );
|
||||
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i);
|
||||
sqlite3ExprCodeGetColumnToReg(pParse, pTab, i, iDataCur, regNew+i);
|
||||
}else{
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
|
||||
}
|
||||
|
||||
+89
-54
@@ -518,16 +518,24 @@ static int checkSavepointCount(sqlite3 *db){
|
||||
/*
|
||||
** Return the register of pOp->p2 after first preparing it to be
|
||||
** overwritten with an integer value.
|
||||
*/
|
||||
*/
|
||||
static SQLITE_NOINLINE Mem *out2PrereleaseWithClear(Mem *pOut){
|
||||
sqlite3VdbeMemSetNull(pOut);
|
||||
pOut->flags = MEM_Int;
|
||||
return pOut;
|
||||
}
|
||||
static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){
|
||||
Mem *pOut;
|
||||
assert( pOp->p2>0 );
|
||||
assert( pOp->p2<=(p->nMem-p->nCursor) );
|
||||
pOut = &p->aMem[pOp->p2];
|
||||
memAboutToChange(p, pOut);
|
||||
if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut);
|
||||
pOut->flags = MEM_Int;
|
||||
return pOut;
|
||||
if( VdbeMemDynamic(pOut) ){
|
||||
return out2PrereleaseWithClear(pOut);
|
||||
}else{
|
||||
pOut->flags = MEM_Int;
|
||||
return pOut;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1265,6 +1273,22 @@ case OP_SCopy: { /* out2 */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: IntCopy P1 P2 * * *
|
||||
** Synopsis: r[P2]=r[P1]
|
||||
**
|
||||
** Transfer the integer value held in register P1 into register P2.
|
||||
**
|
||||
** This is an optimized version of SCopy that works only for integer
|
||||
** values.
|
||||
*/
|
||||
case OP_IntCopy: { /* out2 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
assert( (pIn1->flags & MEM_Int)!=0 );
|
||||
pOut = &aMem[pOp->p2];
|
||||
sqlite3VdbeMemSetInt64(pOut, pIn1->u.i);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: ResultRow P1 P2 * * *
|
||||
** Synopsis: output=r[P1@P2]
|
||||
**
|
||||
@@ -2344,7 +2368,7 @@ case OP_Column: {
|
||||
const u8 *zHdr; /* Next unparsed byte of the header */
|
||||
const u8 *zEndHdr; /* Pointer to first byte after the header */
|
||||
u32 offset; /* Offset into the data */
|
||||
u32 szField; /* Number of bytes in the content of a field */
|
||||
u64 offset64; /* 64-bit offset */
|
||||
u32 avail; /* Number of bytes of available data */
|
||||
u32 t; /* A type code from the record header */
|
||||
u16 fx; /* pDest->flags value */
|
||||
@@ -2415,19 +2439,6 @@ case OP_Column: {
|
||||
pC->nHdrParsed = 0;
|
||||
aOffset[0] = offset;
|
||||
|
||||
/* Make sure a corrupt database has not given us an oversize header.
|
||||
** Do this now to avoid an oversize memory allocation.
|
||||
**
|
||||
** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte
|
||||
** types use so much data space that there can only be 4096 and 32 of
|
||||
** them, respectively. So the maximum header length results from a
|
||||
** 3-byte type for each of the maximum of 32768 columns plus three
|
||||
** extra bytes for the header length itself. 32768*3 + 3 = 98307.
|
||||
*/
|
||||
if( offset > 98307 || offset > pC->payloadSize ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
goto op_column_error;
|
||||
}
|
||||
|
||||
if( avail<offset ){
|
||||
/* pC->aRow does not have to hold the entire row, but it does at least
|
||||
@@ -2436,6 +2447,20 @@ case OP_Column: {
|
||||
** dynamically allocated. */
|
||||
pC->aRow = 0;
|
||||
pC->szRow = 0;
|
||||
|
||||
/* Make sure a corrupt database has not given us an oversize header.
|
||||
** Do this now to avoid an oversize memory allocation.
|
||||
**
|
||||
** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte
|
||||
** types use so much data space that there can only be 4096 and 32 of
|
||||
** them, respectively. So the maximum header length results from a
|
||||
** 3-byte type for each of the maximum of 32768 columns plus three
|
||||
** extra bytes for the header length itself. 32768*3 + 3 = 98307.
|
||||
*/
|
||||
if( offset > 98307 || offset > pC->payloadSize ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
goto op_column_error;
|
||||
}
|
||||
}
|
||||
|
||||
/* The following goto is an optimization. It can be omitted and
|
||||
@@ -2458,11 +2483,8 @@ case OP_Column: {
|
||||
/* Make sure zData points to enough of the record to cover the header. */
|
||||
if( pC->aRow==0 ){
|
||||
memset(&sMem, 0, sizeof(sMem));
|
||||
rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0],
|
||||
!pC->isTable, &sMem);
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto op_column_error;
|
||||
}
|
||||
rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0], !pC->isTable, &sMem);
|
||||
if( rc!=SQLITE_OK ) goto op_column_error;
|
||||
zData = (u8*)sMem.z;
|
||||
}else{
|
||||
zData = pC->aRow;
|
||||
@@ -2470,44 +2492,32 @@ case OP_Column: {
|
||||
|
||||
/* Fill in pC->aType[i] and aOffset[i] values through the p2-th field. */
|
||||
i = pC->nHdrParsed;
|
||||
offset = aOffset[i];
|
||||
offset64 = aOffset[i];
|
||||
zHdr = zData + pC->iHdrOffset;
|
||||
zEndHdr = zData + aOffset[0];
|
||||
assert( i<=p2 && zHdr<zEndHdr );
|
||||
do{
|
||||
if( zHdr[0]<0x80 ){
|
||||
t = zHdr[0];
|
||||
if( (t = zHdr[0])<0x80 ){
|
||||
zHdr++;
|
||||
offset64 += sqlite3VdbeOneByteSerialTypeLen(t);
|
||||
}else{
|
||||
zHdr += sqlite3GetVarint32(zHdr, &t);
|
||||
offset64 += sqlite3VdbeSerialTypeLen(t);
|
||||
}
|
||||
pC->aType[i] = t;
|
||||
szField = sqlite3VdbeSerialTypeLen(t);
|
||||
offset += szField;
|
||||
if( offset<szField ){ /* True if offset overflows */
|
||||
zHdr = &zEndHdr[1]; /* Forces SQLITE_CORRUPT return below */
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
aOffset[i] = offset;
|
||||
pC->aType[i++] = t;
|
||||
aOffset[i] = (u32)(offset64 & 0xffffffff);
|
||||
}while( i<=p2 && zHdr<zEndHdr );
|
||||
pC->nHdrParsed = i;
|
||||
pC->iHdrOffset = (u32)(zHdr - zData);
|
||||
if( pC->aRow==0 ){
|
||||
sqlite3VdbeMemRelease(&sMem);
|
||||
sMem.flags = MEM_Null;
|
||||
}
|
||||
if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem);
|
||||
|
||||
/* The record is corrupt if any of the following are true:
|
||||
** (1) the bytes of the header extend past the declared header size
|
||||
** (zHdr>zEndHdr)
|
||||
** (2) the entire header was used but not all data was used
|
||||
** (zHdr==zEndHdr && offset!=pC->payloadSize)
|
||||
** (3) the end of the data extends beyond the end of the record.
|
||||
** (offset > pC->payloadSize)
|
||||
*/
|
||||
if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset!=pC->payloadSize))
|
||||
|| (offset > pC->payloadSize)
|
||||
if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset64!=pC->payloadSize))
|
||||
|| (offset64 > pC->payloadSize)
|
||||
){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
goto op_column_error;
|
||||
@@ -2526,6 +2536,8 @@ case OP_Column: {
|
||||
}
|
||||
goto op_column_out;
|
||||
}
|
||||
}else{
|
||||
t = pC->aType[p2];
|
||||
}
|
||||
|
||||
/* Extract the content for the p2+1-th column. Control can only
|
||||
@@ -2536,7 +2548,7 @@ case OP_Column: {
|
||||
assert( rc==SQLITE_OK );
|
||||
assert( sqlite3VdbeCheckMemInvariants(pDest) );
|
||||
if( VdbeMemDynamic(pDest) ) sqlite3VdbeMemSetNull(pDest);
|
||||
t = pC->aType[p2];
|
||||
assert( t==pC->aType[p2] );
|
||||
if( pC->szRow>=aOffset[p2+1] ){
|
||||
/* This is the common case where the desired content fits on the original
|
||||
** page - where the content is not on an overflow page */
|
||||
@@ -2648,7 +2660,7 @@ case OP_MakeRecord: {
|
||||
int file_format; /* File format to use for encoding */
|
||||
int i; /* Space used in zNewRecord[] header */
|
||||
int j; /* Space used in zNewRecord[] content */
|
||||
int len; /* Length of a field */
|
||||
u32 len; /* Length of a field */
|
||||
|
||||
/* Assuming the record contains N fields, the record format looks
|
||||
** like this:
|
||||
@@ -2698,8 +2710,7 @@ case OP_MakeRecord: {
|
||||
pRec = pLast;
|
||||
do{
|
||||
assert( memIsValid(pRec) );
|
||||
pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format);
|
||||
len = sqlite3VdbeSerialTypeLen(serial_type);
|
||||
pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format, &len);
|
||||
if( pRec->flags & MEM_Zero ){
|
||||
if( nData ){
|
||||
if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
|
||||
@@ -3313,7 +3324,6 @@ case OP_ReopenIdx: {
|
||||
case OP_OpenRead:
|
||||
case OP_OpenWrite:
|
||||
|
||||
assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR|OPFLAG_SEEKEQ))==pOp->p5 );
|
||||
assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ );
|
||||
assert( p->bIsReader );
|
||||
assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx
|
||||
@@ -3334,7 +3344,8 @@ case OP_OpenWrite:
|
||||
pX = pDb->pBt;
|
||||
assert( pX!=0 );
|
||||
if( pOp->opcode==OP_OpenWrite ){
|
||||
wrFlag = 1;
|
||||
assert( OPFLAG_FORDELETE==BTREE_FORDELETE );
|
||||
wrFlag = BTREE_WRCSR | (pOp->p5 & OPFLAG_FORDELETE);
|
||||
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
|
||||
if( pDb->pSchema->file_format < p->minWriteFileFormat ){
|
||||
p->minWriteFileFormat = pDb->pSchema->file_format;
|
||||
@@ -3386,8 +3397,12 @@ case OP_OpenWrite:
|
||||
open_cursor_set_hints:
|
||||
assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
|
||||
assert( OPFLAG_SEEKEQ==BTREE_SEEK_EQ );
|
||||
sqlite3BtreeCursorHints(pCur->pCursor,
|
||||
(pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ)));
|
||||
testcase( pOp->p5 & OPFLAG_BULKCSR );
|
||||
#ifdef SQLITE_ENABLE_CURSOR_HINT
|
||||
testcase( pOp->p2 & OPFLAG_SEEKEQ );
|
||||
#endif
|
||||
sqlite3BtreeCursorHintFlags(pCur->pCursor,
|
||||
(pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ)));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3454,11 +3469,11 @@ case OP_OpenEphemeral: {
|
||||
assert( pKeyInfo->db==db );
|
||||
assert( pKeyInfo->enc==ENC(db) );
|
||||
pCx->pKeyInfo = pKeyInfo;
|
||||
rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, pKeyInfo, pCx->pCursor);
|
||||
rc = sqlite3BtreeCursor(pCx->pBt, pgno, BTREE_WRCSR, pKeyInfo, pCx->pCursor);
|
||||
}
|
||||
pCx->isTable = 0;
|
||||
}else{
|
||||
rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, pCx->pCursor);
|
||||
rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, BTREE_WRCSR, 0, pCx->pCursor);
|
||||
pCx->isTable = 1;
|
||||
}
|
||||
}
|
||||
@@ -6576,6 +6591,26 @@ case OP_Init: { /* jump */
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_CURSOR_HINTS
|
||||
/* Opcode: CursorHint P1 * * P4 *
|
||||
**
|
||||
** Provide a hint to cursor P1 that it only needs to return rows that
|
||||
** satisfy the Expr in P4. TK_REGISTER terms in the P4 expression refer
|
||||
** to values currently held in registers. TK_COLUMN terms in the P4
|
||||
** expression refer to columns in the b-tree to which cursor P1 is pointing.
|
||||
*/
|
||||
case OP_CursorHint: {
|
||||
VdbeCursor *pC;
|
||||
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
assert( pOp->p4type==P4_EXPR );
|
||||
pC = p->apCsr[pOp->p1];
|
||||
if( pC ){
|
||||
sqlite3BtreeCursorHint(pC->pCursor, BTREE_HINT_RANGE, pOp->p4.pExpr, aMem);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_CURSOR_HINTS */
|
||||
|
||||
/* Opcode: Noop * * * * *
|
||||
**
|
||||
|
||||
@@ -60,6 +60,9 @@ struct VdbeOp {
|
||||
KeyInfo *pKeyInfo; /* Used when p4type is P4_KEYINFO */
|
||||
int *ai; /* Used when p4type is P4_INTARRAY */
|
||||
SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */
|
||||
#ifdef SQLITE_ENABLE_CURSOR_HINTS
|
||||
Expr *pExpr; /* Used when p4type is P4_EXPR */
|
||||
#endif
|
||||
int (*xAdvance)(BtCursor *, int *);
|
||||
} p4;
|
||||
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
@@ -110,6 +113,7 @@ typedef struct VdbeOpList VdbeOpList;
|
||||
#define P4_COLLSEQ (-4) /* P4 is a pointer to a CollSeq structure */
|
||||
#define P4_FUNCDEF (-5) /* P4 is a pointer to a FuncDef structure */
|
||||
#define P4_KEYINFO (-6) /* P4 is a pointer to a KeyInfo structure */
|
||||
#define P4_EXPR (-7) /* P4 is a pointer to an Expr tree */
|
||||
#define P4_MEM (-8) /* P4 is a pointer to a Mem* structure */
|
||||
#define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */
|
||||
#define P4_VTAB (-10) /* P4 is a pointer to an sqlite3_vtab structure */
|
||||
|
||||
+13
-1
@@ -26,6 +26,17 @@
|
||||
# define SQLITE_MAX_SCHEMA_RETRY 50
|
||||
#endif
|
||||
|
||||
/*
|
||||
** VDBE_DISPLAY_P4 is true or false depending on whether or not the
|
||||
** "explain" P4 display logic is enabled.
|
||||
*/
|
||||
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
|
||||
|| defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
|
||||
# define VDBE_DISPLAY_P4 1
|
||||
#else
|
||||
# define VDBE_DISPLAY_P4 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
** SQL is translated into a sequence of instructions to be
|
||||
** executed by a virtual machine. Each instruction is an instance
|
||||
@@ -412,7 +423,8 @@ int sqlite3VdbeCursorRestore(VdbeCursor*);
|
||||
void sqlite3VdbePrintOp(FILE*, int, Op*);
|
||||
#endif
|
||||
u32 sqlite3VdbeSerialTypeLen(u32);
|
||||
u32 sqlite3VdbeSerialType(Mem*, int);
|
||||
u8 sqlite3VdbeOneByteSerialTypeLen(u8);
|
||||
u32 sqlite3VdbeSerialType(Mem*, int, u32*);
|
||||
u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
|
||||
u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
|
||||
void sqlite3VdbeDeleteAuxData(Vdbe*, int, int);
|
||||
|
||||
+140
-14
@@ -763,6 +763,12 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){
|
||||
if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4);
|
||||
break;
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_CURSOR_HINTS
|
||||
case P4_EXPR: {
|
||||
sqlite3ExprDelete(db, (Expr*)p4);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case P4_MPRINTF: {
|
||||
if( db->pnBytesFreed==0 ) sqlite3_free(p4);
|
||||
break;
|
||||
@@ -895,6 +901,15 @@ void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
|
||||
}else if( n==P4_KEYINFO ){
|
||||
pOp->p4.p = (void*)zP4;
|
||||
pOp->p4type = P4_KEYINFO;
|
||||
#ifdef SQLITE_ENABLE_CURSOR_HINTS
|
||||
}else if( n==P4_EXPR ){
|
||||
/* Responsibility for deleting the Expr tree is handed over to the
|
||||
** VDBE by this operation. The caller should have already invoked
|
||||
** sqlite3ExprDup() or whatever other routine is needed to make a
|
||||
** private copy of the tree. */
|
||||
pOp->p4.pExpr = (Expr*)zP4;
|
||||
pOp->p4type = P4_EXPR;
|
||||
#endif
|
||||
}else if( n==P4_VTAB ){
|
||||
pOp->p4.p = (void*)zP4;
|
||||
pOp->p4type = P4_VTAB;
|
||||
@@ -1085,9 +1100,84 @@ static int displayComment(
|
||||
}
|
||||
#endif /* SQLITE_DEBUG */
|
||||
|
||||
#if VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS)
|
||||
/*
|
||||
** Translate the P4.pExpr value for an OP_CursorHint opcode into text
|
||||
** that can be displayed in the P4 column of EXPLAIN output.
|
||||
*/
|
||||
static int displayP4Expr(int nTemp, char *zTemp, Expr *pExpr){
|
||||
const char *zOp = 0;
|
||||
int n;
|
||||
switch( pExpr->op ){
|
||||
case TK_STRING:
|
||||
sqlite3_snprintf(nTemp, zTemp, "%Q", pExpr->u.zToken);
|
||||
break;
|
||||
case TK_INTEGER:
|
||||
sqlite3_snprintf(nTemp, zTemp, "%d", pExpr->u.iValue);
|
||||
break;
|
||||
case TK_NULL:
|
||||
sqlite3_snprintf(nTemp, zTemp, "NULL");
|
||||
break;
|
||||
case TK_REGISTER: {
|
||||
sqlite3_snprintf(nTemp, zTemp, "r[%d]", pExpr->iTable);
|
||||
break;
|
||||
}
|
||||
case TK_COLUMN: {
|
||||
if( pExpr->iColumn<0 ){
|
||||
sqlite3_snprintf(nTemp, zTemp, "rowid");
|
||||
}else{
|
||||
sqlite3_snprintf(nTemp, zTemp, "c%d", (int)pExpr->iColumn);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TK_LT: zOp = "LT"; break;
|
||||
case TK_LE: zOp = "LE"; break;
|
||||
case TK_GT: zOp = "GT"; break;
|
||||
case TK_GE: zOp = "GE"; break;
|
||||
case TK_NE: zOp = "NE"; break;
|
||||
case TK_EQ: zOp = "EQ"; break;
|
||||
case TK_IS: zOp = "IS"; break;
|
||||
case TK_ISNOT: zOp = "ISNOT"; break;
|
||||
case TK_AND: zOp = "AND"; break;
|
||||
case TK_OR: zOp = "OR"; break;
|
||||
case TK_PLUS: zOp = "ADD"; break;
|
||||
case TK_STAR: zOp = "MUL"; break;
|
||||
case TK_MINUS: zOp = "SUB"; break;
|
||||
case TK_REM: zOp = "REM"; break;
|
||||
case TK_BITAND: zOp = "BITAND"; break;
|
||||
case TK_BITOR: zOp = "BITOR"; break;
|
||||
case TK_SLASH: zOp = "DIV"; break;
|
||||
case TK_LSHIFT: zOp = "LSHIFT"; break;
|
||||
case TK_RSHIFT: zOp = "RSHIFT"; break;
|
||||
case TK_CONCAT: zOp = "CONCAT"; break;
|
||||
case TK_UMINUS: zOp = "MINUS"; break;
|
||||
case TK_UPLUS: zOp = "PLUS"; break;
|
||||
case TK_BITNOT: zOp = "BITNOT"; break;
|
||||
case TK_NOT: zOp = "NOT"; break;
|
||||
case TK_ISNULL: zOp = "ISNULL"; break;
|
||||
case TK_NOTNULL: zOp = "NOTNULL"; break;
|
||||
|
||||
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
|
||||
|| defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
|
||||
default:
|
||||
sqlite3_snprintf(nTemp, zTemp, "%s", "expr");
|
||||
break;
|
||||
}
|
||||
|
||||
if( zOp ){
|
||||
sqlite3_snprintf(nTemp, zTemp, "%s(", zOp);
|
||||
n = sqlite3Strlen30(zTemp);
|
||||
n += displayP4Expr(nTemp-n, zTemp+n, pExpr->pLeft);
|
||||
if( n<nTemp-1 && pExpr->pRight ){
|
||||
zTemp[n++] = ',';
|
||||
n += displayP4Expr(nTemp-n, zTemp+n, pExpr->pRight);
|
||||
}
|
||||
sqlite3_snprintf(nTemp-n, zTemp+n, ")");
|
||||
}
|
||||
return sqlite3Strlen30(zTemp);
|
||||
}
|
||||
#endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */
|
||||
|
||||
|
||||
#if VDBE_DISPLAY_P4
|
||||
/*
|
||||
** Compute a string that describes the P4 parameter for an opcode.
|
||||
** Use zTemp for any required temporary buffer space.
|
||||
@@ -1127,6 +1217,12 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
|
||||
assert( i<nTemp );
|
||||
break;
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_CURSOR_HINTS
|
||||
case P4_EXPR: {
|
||||
displayP4Expr(nTemp, zTemp, pOp->p4.pExpr);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case P4_COLLSEQ: {
|
||||
CollSeq *pColl = pOp->p4.pColl;
|
||||
sqlite3_snprintf(nTemp, zTemp, "(%.20s)", pColl->zName);
|
||||
@@ -1202,7 +1298,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
|
||||
assert( zP4!=0 );
|
||||
return zP4;
|
||||
}
|
||||
#endif
|
||||
#endif /* VDBE_DISPLAY_P4 */
|
||||
|
||||
/*
|
||||
** Declare to the Vdbe that the BTree object at db->aDb[i] is used.
|
||||
@@ -1516,12 +1612,12 @@ int sqlite3VdbeList(
|
||||
pMem->u.i = pOp->p3; /* P3 */
|
||||
pMem++;
|
||||
|
||||
if( sqlite3VdbeMemClearAndResize(pMem, 32) ){ /* P4 */
|
||||
if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */
|
||||
assert( p->db->mallocFailed );
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
pMem->flags = MEM_Str|MEM_Term;
|
||||
zP4 = displayP4(pOp, pMem->z, 32);
|
||||
zP4 = displayP4(pOp, pMem->z, pMem->szMalloc);
|
||||
if( zP4!=pMem->z ){
|
||||
sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
|
||||
}else{
|
||||
@@ -2940,11 +3036,13 @@ int sqlite3VdbeCursorMoveto(VdbeCursor *p){
|
||||
/*
|
||||
** Return the serial-type for the value stored in pMem.
|
||||
*/
|
||||
u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
|
||||
u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
|
||||
int flags = pMem->flags;
|
||||
u32 n;
|
||||
|
||||
assert( pLen!=0 );
|
||||
if( flags&MEM_Null ){
|
||||
*pLen = 0;
|
||||
return 0;
|
||||
}
|
||||
if( flags&MEM_Int ){
|
||||
@@ -2958,15 +3056,23 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
|
||||
u = i;
|
||||
}
|
||||
if( u<=127 ){
|
||||
return ((i&1)==i && file_format>=4) ? 8+(u32)u : 1;
|
||||
if( (i&1)==i && file_format>=4 ){
|
||||
*pLen = 0;
|
||||
return 8+(u32)u;
|
||||
}else{
|
||||
*pLen = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if( u<=32767 ) return 2;
|
||||
if( u<=8388607 ) return 3;
|
||||
if( u<=2147483647 ) return 4;
|
||||
if( u<=MAX_6BYTE ) return 5;
|
||||
if( u<=32767 ){ *pLen = 2; return 2; }
|
||||
if( u<=8388607 ){ *pLen = 3; return 3; }
|
||||
if( u<=2147483647 ){ *pLen = 4; return 4; }
|
||||
if( u<=MAX_6BYTE ){ *pLen = 6; return 5; }
|
||||
*pLen = 8;
|
||||
return 6;
|
||||
}
|
||||
if( flags&MEM_Real ){
|
||||
*pLen = 8;
|
||||
return 7;
|
||||
}
|
||||
assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) );
|
||||
@@ -2975,26 +3081,46 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
|
||||
if( flags & MEM_Zero ){
|
||||
n += pMem->u.nZero;
|
||||
}
|
||||
*pLen = n;
|
||||
return ((n*2) + 12 + ((flags&MEM_Str)!=0));
|
||||
}
|
||||
|
||||
/*
|
||||
** The sizes for serial types less than 12
|
||||
** The sizes for serial types less than 128
|
||||
*/
|
||||
static const u8 sqlite3SmallTypeSizes[] = {
|
||||
0, 1, 2, 3, 4, 6, 8, 8, 0, 0, 0, 0
|
||||
/* 0 1 2 3 4 5 6 7 8 9 */
|
||||
/* 0 */ 0, 1, 2, 3, 4, 6, 8, 8, 0, 0,
|
||||
/* 10 */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
|
||||
/* 20 */ 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
|
||||
/* 30 */ 9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
|
||||
/* 40 */ 14, 14, 15, 15, 16, 16, 17, 17, 18, 18,
|
||||
/* 50 */ 19, 19, 20, 20, 21, 21, 22, 22, 23, 23,
|
||||
/* 60 */ 24, 24, 25, 25, 26, 26, 27, 27, 28, 28,
|
||||
/* 70 */ 29, 29, 30, 30, 31, 31, 32, 32, 33, 33,
|
||||
/* 80 */ 34, 34, 35, 35, 36, 36, 37, 37, 38, 38,
|
||||
/* 90 */ 39, 39, 40, 40, 41, 41, 42, 42, 43, 43,
|
||||
/* 100 */ 44, 44, 45, 45, 46, 46, 47, 47, 48, 48,
|
||||
/* 110 */ 49, 49, 50, 50, 51, 51, 52, 52, 53, 53,
|
||||
/* 120 */ 54, 54, 55, 55, 56, 56, 57, 57
|
||||
};
|
||||
|
||||
/*
|
||||
** Return the length of the data corresponding to the supplied serial-type.
|
||||
*/
|
||||
u32 sqlite3VdbeSerialTypeLen(u32 serial_type){
|
||||
if( serial_type>=12 ){
|
||||
if( serial_type>=128 ){
|
||||
return (serial_type-12)/2;
|
||||
}else{
|
||||
assert( serial_type<12
|
||||
|| sqlite3SmallTypeSizes[serial_type]==(serial_type - 12)/2 );
|
||||
return sqlite3SmallTypeSizes[serial_type];
|
||||
}
|
||||
}
|
||||
u8 sqlite3VdbeOneByteSerialTypeLen(u8 serial_type){
|
||||
assert( serial_type<128 );
|
||||
return sqlite3SmallTypeSizes[serial_type];
|
||||
}
|
||||
|
||||
/*
|
||||
** If we are on an architecture with mixed-endian floating
|
||||
|
||||
+3
-4
@@ -1427,17 +1427,16 @@ static void recordFunc(
|
||||
sqlite3_value **argv
|
||||
){
|
||||
const int file_format = 1;
|
||||
int iSerial; /* Serial type */
|
||||
u32 iSerial; /* Serial type */
|
||||
int nSerial; /* Bytes of space for iSerial as varint */
|
||||
int nVal; /* Bytes of space required for argv[0] */
|
||||
u32 nVal; /* Bytes of space required for argv[0] */
|
||||
int nRet;
|
||||
sqlite3 *db;
|
||||
u8 *aRet;
|
||||
|
||||
UNUSED_PARAMETER( argc );
|
||||
iSerial = sqlite3VdbeSerialType(argv[0], file_format);
|
||||
iSerial = sqlite3VdbeSerialType(argv[0], file_format, &nVal);
|
||||
nSerial = sqlite3VarintLen(iSerial);
|
||||
nVal = sqlite3VdbeSerialTypeLen(iSerial);
|
||||
db = sqlite3_context_db_handle(context);
|
||||
|
||||
nRet = 1 + nSerial + nVal;
|
||||
|
||||
+1
-1
@@ -978,7 +978,7 @@ int sqlite3VdbeSorterInit(
|
||||
}
|
||||
pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
|
||||
pSorter->nTask = nWorker + 1;
|
||||
pSorter->iPrev = nWorker-1;
|
||||
pSorter->iPrev = (u8)(nWorker - 1);
|
||||
pSorter->bUseThreads = (pSorter->nTask>1);
|
||||
pSorter->db = db;
|
||||
for(i=0; i<pSorter->nTask; i++){
|
||||
|
||||
+42
-11
@@ -485,14 +485,20 @@ static LogEst estLog(LogEst N){
|
||||
** Convert OP_Column opcodes to OP_Copy in previously generated code.
|
||||
**
|
||||
** This routine runs over generated VDBE code and translates OP_Column
|
||||
** opcodes into OP_Copy, and OP_Rowid into OP_Null, when the table is being
|
||||
** accessed via co-routine instead of via table lookup.
|
||||
** opcodes into OP_Copy when the table is being accessed via co-routine
|
||||
** instead of via table lookup.
|
||||
**
|
||||
** If the bIncrRowid parameter is 0, then any OP_Rowid instructions on
|
||||
** cursor iTabCur are transformed into OP_Null. Or, if bIncrRowid is non-zero,
|
||||
** then each OP_Rowid is transformed into an instruction to increment the
|
||||
** value stored in its output register.
|
||||
*/
|
||||
static void translateColumnToCopy(
|
||||
Vdbe *v, /* The VDBE containing code to translate */
|
||||
int iStart, /* Translate from this opcode to the end */
|
||||
int iTabCur, /* OP_Column/OP_Rowid references to this table */
|
||||
int iRegister /* The first column is in this register */
|
||||
int iRegister, /* The first column is in this register */
|
||||
int bIncrRowid /* If non-zero, transform OP_rowid to OP_AddImm(1) */
|
||||
){
|
||||
VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart);
|
||||
int iEnd = sqlite3VdbeCurrentAddr(v);
|
||||
@@ -504,9 +510,16 @@ static void translateColumnToCopy(
|
||||
pOp->p2 = pOp->p3;
|
||||
pOp->p3 = 0;
|
||||
}else if( pOp->opcode==OP_Rowid ){
|
||||
pOp->opcode = OP_Null;
|
||||
pOp->p1 = 0;
|
||||
pOp->p3 = 0;
|
||||
if( bIncrRowid ){
|
||||
/* Increment the value stored in the P2 operand of the OP_Rowid. */
|
||||
pOp->opcode = OP_AddImm;
|
||||
pOp->p1 = pOp->p2;
|
||||
pOp->p2 = 1;
|
||||
}else{
|
||||
pOp->opcode = OP_Null;
|
||||
pOp->p1 = 0;
|
||||
pOp->p3 = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -614,6 +627,8 @@ static void constructAutomaticIndex(
|
||||
Expr *pPartial = 0; /* Partial Index Expression */
|
||||
int iContinue = 0; /* Jump here to skip excluded rows */
|
||||
struct SrcList_item *pTabItem; /* FROM clause term being indexed */
|
||||
int addrCounter = 0; /* Address where integer counter is initialized */
|
||||
int regBase; /* Array of registers where record is assembled */
|
||||
|
||||
/* Generate code to skip over the creation and initialization of the
|
||||
** transient index on 2nd and subsequent iterations of the loop. */
|
||||
@@ -742,6 +757,7 @@ static void constructAutomaticIndex(
|
||||
pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom];
|
||||
if( pTabItem->fg.viaCoroutine ){
|
||||
int regYield = pTabItem->regReturn;
|
||||
addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
|
||||
sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
|
||||
addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield);
|
||||
VdbeCoverage(v);
|
||||
@@ -755,12 +771,15 @@ static void constructAutomaticIndex(
|
||||
pLoop->wsFlags |= WHERE_PARTIALIDX;
|
||||
}
|
||||
regRecord = sqlite3GetTempReg(pParse);
|
||||
sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0);
|
||||
regBase = sqlite3GenerateIndexKey(
|
||||
pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0
|
||||
);
|
||||
sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
|
||||
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
|
||||
if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
|
||||
if( pTabItem->fg.viaCoroutine ){
|
||||
translateColumnToCopy(v, addrTop, pLevel->iTabCur, pTabItem->regResult);
|
||||
sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
|
||||
translateColumnToCopy(v, addrTop, pLevel->iTabCur, pTabItem->regResult, 1);
|
||||
sqlite3VdbeGoto(v, addrTop);
|
||||
pTabItem->fg.viaCoroutine = 0;
|
||||
}else{
|
||||
@@ -3991,6 +4010,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
int ii; /* Loop counter */
|
||||
sqlite3 *db; /* Database connection */
|
||||
int rc; /* Return code */
|
||||
u8 bFordelete = 0;
|
||||
|
||||
assert( (wctrlFlags & WHERE_ONEPASS_MULTIROW)==0 || (
|
||||
(wctrlFlags & WHERE_ONEPASS_DESIRED)!=0
|
||||
@@ -4246,8 +4266,11 @@ WhereInfo *sqlite3WhereBegin(
|
||||
&& 0==(wsFlags & WHERE_VIRTUALTABLE)
|
||||
)){
|
||||
pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI;
|
||||
if( HasRowid(pTabList->a[0].pTab) ){
|
||||
pWInfo->a[0].pWLoop->wsFlags &= ~WHERE_IDX_ONLY;
|
||||
if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){
|
||||
if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){
|
||||
bFordelete = OPFLAG_FORDELETE;
|
||||
}
|
||||
pWInfo->a[0].pWLoop->wsFlags = (wsFlags & ~WHERE_IDX_ONLY);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4295,6 +4318,14 @@ WhereInfo *sqlite3WhereBegin(
|
||||
SQLITE_INT_TO_PTR(n), P4_INT32);
|
||||
assert( n<=pTab->nCol );
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_CURSOR_HINTS
|
||||
if( pLoop->u.btree.pIndex!=0 ){
|
||||
sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ|bFordelete);
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
sqlite3VdbeChangeP5(v, bFordelete);
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
|
||||
sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, pTabItem->iCursor, 0, 0,
|
||||
(const u8*)&pTabItem->colUsed, P4_INT64);
|
||||
@@ -4509,7 +4540,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
||||
*/
|
||||
if( pTabItem->fg.viaCoroutine && !db->mallocFailed ){
|
||||
translateColumnToCopy(v, pLevel->addrBody, pLevel->iTabCur,
|
||||
pTabItem->regResult);
|
||||
pTabItem->regResult, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
+162
-15
@@ -590,6 +590,154 @@ static void whereLikeOptimizationStringFixup(
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_CURSOR_HINTS
|
||||
/*
|
||||
** Information is passed from codeCursorHint() down to individual nodes of
|
||||
** the expression tree (by sqlite3WalkExpr()) using an instance of this
|
||||
** structure.
|
||||
*/
|
||||
struct CCurHint {
|
||||
int iTabCur; /* Cursor for the main table */
|
||||
int iIdxCur; /* Cursor for the index, if pIdx!=0. Unused otherwise */
|
||||
Index *pIdx; /* The index used to access the table */
|
||||
};
|
||||
|
||||
/*
|
||||
** This function is called for every node of an expression that is a candidate
|
||||
** for a cursor hint on an index cursor. For TK_COLUMN nodes that reference
|
||||
** the table CCurHint.iTabCur, verify that the same column can be
|
||||
** accessed through the index. If it cannot, then set pWalker->eCode to 1.
|
||||
*/
|
||||
static int codeCursorHintCheckExpr(Walker *pWalker, Expr *pExpr){
|
||||
struct CCurHint *pHint = pWalker->u.pCCurHint;
|
||||
assert( pHint->pIdx!=0 );
|
||||
if( pExpr->op==TK_COLUMN
|
||||
&& pExpr->iTable==pHint->iTabCur
|
||||
&& sqlite3ColumnOfIndex(pHint->pIdx, pExpr->iColumn)<0
|
||||
){
|
||||
pWalker->eCode = 1;
|
||||
}
|
||||
return WRC_Continue;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** This function is called on every node of an expression tree used as an
|
||||
** argument to the OP_CursorHint instruction. If the node is a TK_COLUMN
|
||||
** that accesses any table other than the one identified by
|
||||
** CCurHint.iTabCur, then do the following:
|
||||
**
|
||||
** 1) allocate a register and code an OP_Column instruction to read
|
||||
** the specified column into the new register, and
|
||||
**
|
||||
** 2) transform the expression node to a TK_REGISTER node that reads
|
||||
** from the newly populated register.
|
||||
**
|
||||
** Also, if the node is a TK_COLUMN that does access the table idenified
|
||||
** by pCCurHint.iTabCur, and an index is being used (which we will
|
||||
** know because CCurHint.pIdx!=0) then transform the TK_COLUMN into
|
||||
** an access of the index rather than the original table.
|
||||
*/
|
||||
static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){
|
||||
int rc = WRC_Continue;
|
||||
struct CCurHint *pHint = pWalker->u.pCCurHint;
|
||||
if( pExpr->op==TK_COLUMN ){
|
||||
if( pExpr->iTable!=pHint->iTabCur ){
|
||||
Vdbe *v = pWalker->pParse->pVdbe;
|
||||
int reg = ++pWalker->pParse->nMem; /* Register for column value */
|
||||
sqlite3ExprCodeGetColumnOfTable(
|
||||
v, pExpr->pTab, pExpr->iTable, pExpr->iColumn, reg
|
||||
);
|
||||
pExpr->op = TK_REGISTER;
|
||||
pExpr->iTable = reg;
|
||||
}else if( pHint->pIdx!=0 ){
|
||||
pExpr->iTable = pHint->iIdxCur;
|
||||
pExpr->iColumn = sqlite3ColumnOfIndex(pHint->pIdx, pExpr->iColumn);
|
||||
assert( pExpr->iColumn>=0 );
|
||||
}
|
||||
}else if( pExpr->op==TK_AGG_FUNCTION ){
|
||||
/* An aggregate function in the WHERE clause of a query means this must
|
||||
** be a correlated sub-query, and expression pExpr is an aggregate from
|
||||
** the parent context. Do not walk the function arguments in this case.
|
||||
**
|
||||
** todo: It should be possible to replace this node with a TK_REGISTER
|
||||
** expression, as the result of the expression must be stored in a
|
||||
** register at this point. The same holds for TK_AGG_COLUMN nodes. */
|
||||
rc = WRC_Prune;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Insert an OP_CursorHint instruction if it is appropriate to do so.
|
||||
*/
|
||||
static void codeCursorHint(
|
||||
WhereInfo *pWInfo, /* The where clause */
|
||||
WhereLevel *pLevel, /* Which loop to provide hints for */
|
||||
WhereTerm *pEndRange /* Hint this end-of-scan boundary term if not NULL */
|
||||
){
|
||||
Parse *pParse = pWInfo->pParse;
|
||||
sqlite3 *db = pParse->db;
|
||||
Vdbe *v = pParse->pVdbe;
|
||||
Expr *pExpr = 0;
|
||||
WhereLoop *pLoop = pLevel->pWLoop;
|
||||
int iCur;
|
||||
WhereClause *pWC;
|
||||
WhereTerm *pTerm;
|
||||
int i, j;
|
||||
struct CCurHint sHint;
|
||||
Walker sWalker;
|
||||
|
||||
if( OptimizationDisabled(db, SQLITE_CursorHints) ) return;
|
||||
iCur = pLevel->iTabCur;
|
||||
assert( iCur==pWInfo->pTabList->a[pLevel->iFrom].iCursor );
|
||||
sHint.iTabCur = iCur;
|
||||
sHint.iIdxCur = pLevel->iIdxCur;
|
||||
sHint.pIdx = pLoop->u.btree.pIndex;
|
||||
memset(&sWalker, 0, sizeof(sWalker));
|
||||
sWalker.pParse = pParse;
|
||||
sWalker.u.pCCurHint = &sHint;
|
||||
pWC = &pWInfo->sWC;
|
||||
for(i=0; i<pWC->nTerm; i++){
|
||||
pTerm = &pWC->a[i];
|
||||
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
|
||||
if( pTerm->prereqAll & pLevel->notReady ) continue;
|
||||
if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue;
|
||||
|
||||
/* All terms in pWLoop->aLTerm[] except pEndRange are used to initialize
|
||||
** the cursor. These terms are not needed as hints for a pure range
|
||||
** scan (that has no == terms) so omit them. */
|
||||
if( pLoop->u.btree.nEq==0 && pTerm!=pEndRange ){
|
||||
for(j=0; j<pLoop->nLTerm && pLoop->aLTerm[j]!=pTerm; j++){}
|
||||
if( j<pLoop->nLTerm ) continue;
|
||||
}
|
||||
|
||||
/* No subqueries or non-deterministic functions allowed */
|
||||
if( sqlite3ExprContainsSubquery(pTerm->pExpr) ) continue;
|
||||
|
||||
/* For an index scan, make sure referenced columns are actually in
|
||||
** the index. */
|
||||
if( sHint.pIdx!=0 ){
|
||||
sWalker.eCode = 0;
|
||||
sWalker.xExprCallback = codeCursorHintCheckExpr;
|
||||
sqlite3WalkExpr(&sWalker, pTerm->pExpr);
|
||||
if( sWalker.eCode ) continue;
|
||||
}
|
||||
|
||||
/* If we survive all prior tests, that means this term is worth hinting */
|
||||
pExpr = sqlite3ExprAnd(db, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0));
|
||||
}
|
||||
if( pExpr!=0 ){
|
||||
sWalker.xExprCallback = codeCursorHintFixExpr;
|
||||
sqlite3WalkExpr(&sWalker, pExpr);
|
||||
sqlite3VdbeAddOp4(v, OP_CursorHint,
|
||||
(sHint.pIdx ? sHint.iIdxCur : sHint.iTabCur), 0, 0,
|
||||
(const char*)pExpr, P4_EXPR);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define codeCursorHint(A,B,C) /* No-op */
|
||||
#endif /* SQLITE_ENABLE_CURSOR_HINTS */
|
||||
|
||||
/*
|
||||
** Generate code for the start of the iLevel-th loop in the WHERE clause
|
||||
@@ -754,6 +902,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
pStart = pEnd;
|
||||
pEnd = pTerm;
|
||||
}
|
||||
codeCursorHint(pWInfo, pLevel, pEnd);
|
||||
if( pStart ){
|
||||
Expr *pX; /* The expression that defines the start bound */
|
||||
int r1, rTemp; /* Registers for holding the start boundary */
|
||||
@@ -947,15 +1096,6 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
}
|
||||
assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 );
|
||||
|
||||
/* Generate code to evaluate all constraint terms using == or IN
|
||||
** and store the values of those terms in an array of registers
|
||||
** starting at regBase.
|
||||
*/
|
||||
regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
|
||||
assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq );
|
||||
if( zStartAff ) cEndAff = zStartAff[nEq];
|
||||
addrNxt = pLevel->addrNxt;
|
||||
|
||||
/* If we are doing a reverse order scan on an ascending index, or
|
||||
** a forward order scan on a descending index, interchange the
|
||||
** start and end terms (pRangeStart and pRangeEnd).
|
||||
@@ -967,6 +1107,16 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
SWAP(u8, bSeekPastNull, bStopAtNull);
|
||||
}
|
||||
|
||||
/* Generate code to evaluate all constraint terms using == or IN
|
||||
** and store the values of those terms in an array of registers
|
||||
** starting at regBase.
|
||||
*/
|
||||
codeCursorHint(pWInfo, pLevel, pRangeEnd);
|
||||
regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
|
||||
assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq );
|
||||
if( zStartAff ) cEndAff = zStartAff[nEq];
|
||||
addrNxt = pLevel->addrNxt;
|
||||
|
||||
testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 );
|
||||
testcase( pRangeStart && (pRangeStart->eOperator & WO_GE)!=0 );
|
||||
testcase( pRangeEnd && (pRangeEnd->eOperator & WO_LE)!=0 );
|
||||
@@ -1249,7 +1399,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
|
||||
}
|
||||
if( pAndExpr ){
|
||||
pAndExpr = sqlite3PExpr(pParse, TK_AND, 0, pAndExpr, 0);
|
||||
pAndExpr = sqlite3PExpr(pParse, TK_AND|TKFLG_DONTFOLD, 0, pAndExpr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1305,11 +1455,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
r = sqlite3GetTempRange(pParse, nPk);
|
||||
for(iPk=0; iPk<nPk; iPk++){
|
||||
int iCol = pPk->aiColumn[iPk];
|
||||
int rx;
|
||||
rx = sqlite3ExprCodeGetColumn(pParse, pTab, iCol, iCur,r+iPk,0);
|
||||
if( rx!=r+iPk ){
|
||||
sqlite3VdbeAddOp2(v, OP_SCopy, rx, r+iPk);
|
||||
}
|
||||
sqlite3ExprCodeGetColumnToReg(pParse, pTab, iCol, iCur, r+iPk);
|
||||
}
|
||||
|
||||
/* Check if the temp table already contains this key. If so,
|
||||
@@ -1409,6 +1555,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
** a pseudo-cursor. No need to Rewind or Next such cursors. */
|
||||
pLevel->op = OP_Noop;
|
||||
}else{
|
||||
codeCursorHint(pWInfo, pLevel, 0);
|
||||
pLevel->op = aStep[bRev];
|
||||
pLevel->p1 = iCur;
|
||||
pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix autoindex5
|
||||
|
||||
# Schema is from the Debian security database
|
||||
#
|
||||
@@ -103,6 +104,26 @@ do_execsql_test autoindex5-1.1 {
|
||||
OR sp.release = 'wheezy' OR sp.release = 'squeeze' )
|
||||
ORDER BY sp.name, st.bug_name, sp.release, sp.subrelease;
|
||||
} {/SEARCH SUBQUERY 2 USING AUTOMATIC COVERING INDEX .bug_name=/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that ticket [8a2adec1] has been fixed.
|
||||
#
|
||||
do_execsql_test 2.1 {
|
||||
CREATE TABLE one(o);
|
||||
INSERT INTO one DEFAULT VALUES;
|
||||
|
||||
CREATE TABLE t1(x, z);
|
||||
INSERT INTO t1 VALUES('aaa', 4.0);
|
||||
INSERT INTO t1 VALUES('aaa', 4.0);
|
||||
CREATE VIEW vvv AS
|
||||
SELECT * FROM t1
|
||||
UNION ALL
|
||||
SELECT 0, 0 WHERE 0;
|
||||
|
||||
SELECT (
|
||||
SELECT sum(z) FROM vvv WHERE x='aaa'
|
||||
) FROM one;
|
||||
} {8.0}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+3
-1
@@ -7,11 +7,13 @@ proc bc_find_binaries {zCaption} {
|
||||
# against.
|
||||
#
|
||||
set binaries [list]
|
||||
set pattern "[file tail [info nameofexec]]?*"
|
||||
set self [file tail [info nameofexec]]
|
||||
set pattern "$self?*"
|
||||
if {$::tcl_platform(platform)=="windows"} {
|
||||
set pattern [string map {\.exe {}} $pattern]
|
||||
}
|
||||
foreach file [glob -nocomplain $pattern] {
|
||||
if {$file==$self} continue
|
||||
if {[file executable $file] && [file isfile $file]} {lappend binaries $file}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,324 @@
|
||||
# 2011 November 16
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# This file contains test cases for sqlite3_db_cacheflush API.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix cacheflush
|
||||
test_set_config_pagecache 0 0
|
||||
|
||||
# Run the supplied SQL on a copy of the database currently stored on
|
||||
# disk in file $dbfile.
|
||||
proc diskquery {dbfile sql} {
|
||||
forcecopy $dbfile dq.db
|
||||
sqlite3 dq dq.db
|
||||
set res [execsql $sql dq]
|
||||
dq close
|
||||
set res
|
||||
}
|
||||
|
||||
# Simplest possible test.
|
||||
#
|
||||
do_execsql_test 1.1.0 {
|
||||
CREATE TABLE t1(a, b);
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES(3, 4);
|
||||
}
|
||||
do_test 1.1.1 {
|
||||
diskquery test.db { SELECT * FROM t1 }
|
||||
} {1 2}
|
||||
do_test 1.1.2 {
|
||||
sqlite3_db_cacheflush db
|
||||
diskquery test.db { SELECT * FROM t1 }
|
||||
} {1 2 3 4}
|
||||
|
||||
# Test that multiple pages may be flushed to disk.
|
||||
#
|
||||
do_execsql_test 1.2.0 {
|
||||
COMMIT;
|
||||
CREATE TABLE t2(a, b);
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES(5, 6);
|
||||
INSERT INTO t2 VALUES('a', 'b');
|
||||
}
|
||||
do_test 1.2.1 {
|
||||
diskquery test.db {
|
||||
SELECT * FROM t1;
|
||||
SELECT * FROM t2;
|
||||
}
|
||||
} {1 2 3 4}
|
||||
do_test 1.2.2 {
|
||||
sqlite3_db_cacheflush db
|
||||
diskquery test.db {
|
||||
SELECT * FROM t1;
|
||||
SELECT * FROM t2;
|
||||
}
|
||||
} {1 2 3 4 5 6 a b}
|
||||
|
||||
# Test that pages with nRef!=0 are not flushed to disk.
|
||||
#
|
||||
do_execsql_test 1.3.0 {
|
||||
COMMIT;
|
||||
CREATE TABLE t3(a, b);
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES(7, 8);
|
||||
INSERT INTO t2 VALUES('c', 'd');
|
||||
INSERT INTO t3 VALUES('i', 'ii');
|
||||
}
|
||||
do_test 1.3.1 {
|
||||
diskquery test.db {
|
||||
SELECT * FROM t1;
|
||||
SELECT * FROM t2;
|
||||
SELECT * FROM t3;
|
||||
}
|
||||
} {1 2 3 4 5 6 a b}
|
||||
do_test 1.3.2 {
|
||||
db eval { SELECT a FROM t1 } {
|
||||
if {$a==3} {
|
||||
sqlite3_db_cacheflush db
|
||||
}
|
||||
}
|
||||
diskquery test.db {
|
||||
SELECT * FROM t1;
|
||||
SELECT * FROM t2;
|
||||
SELECT * FROM t3;
|
||||
}
|
||||
} {1 2 3 4 5 6 a b c d i ii}
|
||||
do_test 1.3.2 {
|
||||
sqlite3_db_cacheflush db
|
||||
diskquery test.db {
|
||||
SELECT * FROM t1;
|
||||
SELECT * FROM t2;
|
||||
SELECT * FROM t3;
|
||||
}
|
||||
} {1 2 3 4 5 6 7 8 a b c d i ii}
|
||||
|
||||
# Check that SQLITE_BUSY is returned if pages cannot be flushed due to
|
||||
# conflicting read locks.
|
||||
#
|
||||
do_execsql_test 1.4.0 {
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES(9, 10);
|
||||
}
|
||||
do_test 1.4.1 {
|
||||
sqlite3 db2 test.db
|
||||
db2 eval {
|
||||
BEGIN;
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
diskquery test.db {
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {1 2 3 4 5 6 7 8}
|
||||
do_test 1.4.2 {
|
||||
list [catch { sqlite3_db_cacheflush db } msg] $msg
|
||||
} {1 {database is locked}}
|
||||
do_test 1.4.3 {
|
||||
diskquery test.db {
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {1 2 3 4 5 6 7 8}
|
||||
do_test 1.4.4 {
|
||||
db2 close
|
||||
sqlite3_db_cacheflush db
|
||||
diskquery test.db {
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {1 2 3 4 5 6 7 8 9 10}
|
||||
do_execsql_test 1.4.5 { COMMIT }
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that ATTACHed database caches are also flushed.
|
||||
#
|
||||
forcedelete test.db2
|
||||
do_execsql_test 2.1.0 {
|
||||
ATTACH 'test.db2' AS aux;
|
||||
CREATE TABLE aux.t4(x, y);
|
||||
INSERT INTO t4 VALUES('A', 'B');
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES(11, 12);
|
||||
INSERT INTO t4 VALUES('C', 'D');
|
||||
}
|
||||
do_test 2.1.1 {
|
||||
diskquery test.db { SELECT * FROM t1; }
|
||||
} {1 2 3 4 5 6 7 8 9 10}
|
||||
do_test 2.1.2 {
|
||||
diskquery test.db2 { SELECT * FROM t4; }
|
||||
} {A B}
|
||||
do_test 2.1.3 {
|
||||
sqlite3_db_cacheflush db
|
||||
diskquery test.db { SELECT * FROM t1; }
|
||||
} {1 2 3 4 5 6 7 8 9 10 11 12}
|
||||
do_test 2.1.4 {
|
||||
sqlite3_db_cacheflush db
|
||||
diskquery test.db2 { SELECT * FROM t4; }
|
||||
} {A B C D}
|
||||
do_execsql_test 2.1.5 { COMMIT }
|
||||
|
||||
# And that hitting an SQLITE_BUSY when flushing "main" does not stop
|
||||
# SQLite from going on to flush "aux".
|
||||
#
|
||||
do_execsql_test 2.2.0 {
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES(13, 14);
|
||||
INSERT INTO t4 VALUES('E', 'F');
|
||||
}
|
||||
do_test 2.2.1 {
|
||||
diskquery test.db { SELECT * FROM t1; }
|
||||
} {1 2 3 4 5 6 7 8 9 10 11 12}
|
||||
do_test 2.2.2 {
|
||||
diskquery test.db2 { SELECT * FROM t4; }
|
||||
} {A B C D}
|
||||
do_test 2.2.3 {
|
||||
sqlite3 db2 test.db
|
||||
execsql {
|
||||
BEGIN;
|
||||
SELECT * FROM t1;
|
||||
} db2
|
||||
list [catch { sqlite3_db_cacheflush db } msg] $msg
|
||||
} {1 {database is locked}}
|
||||
do_test 2.2.4 {
|
||||
diskquery test.db { SELECT * FROM t1; }
|
||||
} {1 2 3 4 5 6 7 8 9 10 11 12}
|
||||
do_test 2.2.5 {
|
||||
diskquery test.db2 { SELECT * FROM t4; }
|
||||
} {A B C D E F}
|
||||
do_test 2.2.6 {
|
||||
db2 close
|
||||
sqlite3_db_cacheflush db
|
||||
diskquery test.db { SELECT * FROM t1; }
|
||||
} {1 2 3 4 5 6 7 8 9 10 11 12 13 14}
|
||||
do_execsql_test 2.2.7 { COMMIT }
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that nothing terrible happens if sqlite3_db_cacheflush() is
|
||||
# called on an in-memory database.
|
||||
#
|
||||
do_test 3.0 {
|
||||
db close
|
||||
sqlite3 db :memory:
|
||||
db eval {
|
||||
CREATE TABLE t1(x PRIMARY KEY);
|
||||
CREATE TABLE t2(y PRIMARY KEY);
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES(randomblob(100));
|
||||
INSERT INTO t2 VALUES(randomblob(100));
|
||||
INSERT INTO t1 VALUES(randomblob(100));
|
||||
INSERT INTO t2 VALUES(randomblob(100));
|
||||
}
|
||||
sqlite3_db_cacheflush db
|
||||
} {}
|
||||
|
||||
do_execsql_test 3.1 { PRAGMA integrity_check } ok
|
||||
do_execsql_test 3.2 { COMMIT }
|
||||
do_execsql_test 3.3 { PRAGMA integrity_check } ok
|
||||
do_execsql_test 3.4 {
|
||||
SELECT count(*) FROM t1;
|
||||
SELECT count(*) FROM t2;
|
||||
} {2 2}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that calling sqlite3_db_cacheflush() does not interfere with
|
||||
# savepoint transactions.
|
||||
#
|
||||
do_test 4.0 {
|
||||
reset_db
|
||||
execsql {
|
||||
CREATE TABLE ta(a, aa);
|
||||
CREATE TABLE tb(b, bb);
|
||||
INSERT INTO ta VALUES('a', randomblob(500));
|
||||
INSERT INTO tb VALUES('b', randomblob(500));
|
||||
BEGIN;
|
||||
UPDATE ta SET a = 'A';
|
||||
SAVEPOINT one;
|
||||
UPDATE tb SET b = 'B';
|
||||
}
|
||||
|
||||
sqlite3_db_cacheflush db
|
||||
diskquery test.db {
|
||||
SELECT a FROM ta;
|
||||
SELECT b FROM tb;
|
||||
}
|
||||
} {A B}
|
||||
|
||||
do_test 4.1 {
|
||||
execsql {
|
||||
ROLLBACK TO one;
|
||||
}
|
||||
sqlite3_db_cacheflush db
|
||||
diskquery test.db {
|
||||
SELECT a FROM ta;
|
||||
SELECT b FROM tb;
|
||||
}
|
||||
} {A b}
|
||||
|
||||
do_test 4.2 {
|
||||
execsql {
|
||||
INSERT INTO tb VALUES('c', randomblob(10));
|
||||
INSERT INTO tb VALUES('d', randomblob(10));
|
||||
INSERT INTO tb VALUES('e', randomblob(10));
|
||||
}
|
||||
sqlite3_db_cacheflush db
|
||||
diskquery test.db {
|
||||
SELECT a FROM ta;
|
||||
SELECT b FROM tb;
|
||||
}
|
||||
} {A b c d e}
|
||||
|
||||
do_test 4.3 {
|
||||
execsql {
|
||||
SAVEPOINT two;
|
||||
UPDATE tb SET b = upper(b);
|
||||
}
|
||||
sqlite3_db_cacheflush db
|
||||
diskquery test.db {
|
||||
SELECT a FROM ta;
|
||||
SELECT b FROM tb;
|
||||
}
|
||||
} {A B C D E}
|
||||
|
||||
do_test 4.4 {
|
||||
execsql {
|
||||
ROLLBACK TO two;
|
||||
}
|
||||
sqlite3_db_cacheflush db
|
||||
diskquery test.db {
|
||||
SELECT a FROM ta;
|
||||
SELECT b FROM tb;
|
||||
}
|
||||
} {A b c d e}
|
||||
|
||||
do_test 4.4 {
|
||||
execsql {
|
||||
ROLLBACK TO one;
|
||||
}
|
||||
sqlite3_db_cacheflush db
|
||||
diskquery test.db {
|
||||
SELECT a FROM ta;
|
||||
SELECT b FROM tb;
|
||||
}
|
||||
} {A b}
|
||||
|
||||
do_test 4.5 {
|
||||
execsql {
|
||||
ROLLBACK;
|
||||
SELECT a FROM ta;
|
||||
SELECT b FROM tb;
|
||||
}
|
||||
} {a b}
|
||||
|
||||
test_restore_config_pagecache
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
# 2011 November 16
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# This file contains fault-injection test cases for the
|
||||
# sqlite3_db_cacheflush API.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix cacheflush
|
||||
source $testdir/malloc_common.tcl
|
||||
|
||||
# Run the supplied SQL on a copy of the database currently stored on
|
||||
# disk in file $dbfile.
|
||||
proc diskquery {dbfile sql} {
|
||||
forcecopy $dbfile dq.db
|
||||
sqlite3 dq dq.db
|
||||
set res [execsql $sql dq]
|
||||
dq close
|
||||
set res
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a PRIMARY KEY, b);
|
||||
CREATE INDEX i1 ON t1(b);
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
INSERT INTO t1 VALUES(3, 4);
|
||||
INSERT INTO t1 VALUES(5, 6);
|
||||
INSERT INTO t1 VALUES(7, 8);
|
||||
}
|
||||
faultsim_save_and_close
|
||||
|
||||
do_faultsim_test 1.1 -prep {
|
||||
faultsim_restore_and_reopen
|
||||
db eval {
|
||||
BEGIN;
|
||||
UPDATE t1 SET b=b+1;
|
||||
}
|
||||
} -body {
|
||||
sqlite3_db_cacheflush db
|
||||
} -test {
|
||||
if {[sqlite3_get_autocommit db]} { error "Transaction rolled back!" }
|
||||
faultsim_test_result {0 {}} {1 {disk I/O error}}
|
||||
catch { db eval COMMIT }
|
||||
faultsim_integrity_check
|
||||
}
|
||||
|
||||
do_faultsim_test 1.2 -prep {
|
||||
faultsim_restore_and_reopen
|
||||
db eval {
|
||||
BEGIN;
|
||||
UPDATE t1 SET b=b+1;
|
||||
}
|
||||
} -body {
|
||||
set result [list]
|
||||
db eval { SELECT * FROM t1 } {
|
||||
if {$a==5} { catch { sqlite3_db_cacheflush db } }
|
||||
lappend result $a $b
|
||||
}
|
||||
set result
|
||||
} -test {
|
||||
faultsim_test_result {0 {1 3 3 5 5 7 7 9}} {1 {disk I/O error}}
|
||||
catch { db eval COMMIT }
|
||||
faultsim_integrity_check
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 2.0 {
|
||||
CREATE TABLE t1(a PRIMARY KEY, b, c);
|
||||
CREATE INDEX i1 ON t1(b);
|
||||
CREATE INDEX i2 ON t1(c, b);
|
||||
INSERT INTO t1 VALUES(1, 2, randomblob(600));
|
||||
INSERT INTO t1 VALUES(3, 4, randomblob(600));
|
||||
INSERT INTO t1 VALUES(5, 6, randomblob(600));
|
||||
INSERT INTO t1 VALUES(7, 8, randomblob(600));
|
||||
INSERT INTO t1 VALUES(9, 10, randomblob(600));
|
||||
}
|
||||
faultsim_save_and_close
|
||||
|
||||
do_faultsim_test 2.1 -prep {
|
||||
faultsim_restore_and_reopen
|
||||
db eval {
|
||||
BEGIN;
|
||||
UPDATE t1 SET b=b+1;
|
||||
}
|
||||
} -body {
|
||||
set result [list]
|
||||
db eval { SELECT * FROM t1 } {
|
||||
if {$a==5} { catch { sqlite3_db_cacheflush db } }
|
||||
lappend result $a $b
|
||||
}
|
||||
set result
|
||||
} -test {
|
||||
faultsim_test_result {0 {1 3 3 5 5 7 7 9 9 11}} {1 {disk I/O error}}
|
||||
catch { db eval { INSERT INTO t1 VALUES(11, 12, randomblob(600)) } }
|
||||
catch { db eval COMMIT }
|
||||
faultsim_integrity_check
|
||||
}
|
||||
|
||||
do_faultsim_test 2.2 -prep {
|
||||
faultsim_restore_and_reopen
|
||||
db eval {
|
||||
BEGIN;
|
||||
UPDATE t1 SET b=b+1;
|
||||
}
|
||||
} -body {
|
||||
sqlite3_db_cacheflush db
|
||||
} -test {
|
||||
if {[sqlite3_get_autocommit db]} { error "Transaction rolled back!" }
|
||||
faultsim_test_result {0 {}} {1 {disk I/O error}}
|
||||
catch { db eval { SELECT * FROM t1 } }
|
||||
catch { db eval COMMIT }
|
||||
faultsim_integrity_check
|
||||
}
|
||||
|
||||
do_faultsim_test 2.3 -prep {
|
||||
faultsim_restore_and_reopen
|
||||
db eval {
|
||||
BEGIN;
|
||||
UPDATE t1 SET b=b-1;
|
||||
}
|
||||
} -body {
|
||||
sqlite3_db_cacheflush db
|
||||
} -test {
|
||||
if {[sqlite3_get_autocommit db]} { error "Transaction rolled back!" }
|
||||
faultsim_test_result {0 {}} {1 {disk I/O error}}
|
||||
catch { db eval { INSERT INTO t1 VALUES(11, 12, randomblob(600)) } }
|
||||
catch { db eval COMMIT }
|
||||
faultsim_integrity_check
|
||||
}
|
||||
|
||||
do_faultsim_test 2.4 -prep {
|
||||
faultsim_restore_and_reopen
|
||||
db eval {
|
||||
BEGIN;
|
||||
UPDATE t1 SET b=b-1;
|
||||
}
|
||||
} -body {
|
||||
catch { sqlite3_db_cacheflush db }
|
||||
catch { sqlite3_db_release_memory db }
|
||||
catch { sqlite3_db_cacheflush db }
|
||||
execsql { SELECT a, b FROM t1 }
|
||||
} -test {
|
||||
faultsim_test_result {0 {1 1 3 3 5 5 7 7 9 9}} {1 {disk I/O error}}
|
||||
catchsql ROLLBACK
|
||||
faultsim_integrity_check
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
# 2014 July 15
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix cursorhint
|
||||
|
||||
ifcapable !cursorhints {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a,b,c,d);
|
||||
CREATE TABLE t2(x,y,z);
|
||||
INSERT INTO t1(a,b) VALUES(10, 15);
|
||||
INSERT INTO t1(a,b) VALUES(20, 25);
|
||||
INSERT INTO t2(x,y) VALUES('ten', 'fifteen');
|
||||
INSERT INTO t2(x,y) VALUES('twenty', 'twentyfive');
|
||||
CREATE TABLE t3(id TEXT PRIMARY KEY, a, b, c, d) WITHOUT ROWID;
|
||||
INSERT INTO t3(id,a,b,c,d) SELECT rowid, a, b, c, d FROM t1;
|
||||
PRAGMA automatic_index = 0;
|
||||
}
|
||||
|
||||
# Run EXPLAIN on $sql. Return a list of P4 values for all $opcode
|
||||
# opcodes.
|
||||
#
|
||||
proc p4_of_opcode {db opcode sql} {
|
||||
set res {}
|
||||
$db eval "EXPLAIN $sql" x {
|
||||
if {$x(opcode)==$opcode} {lappend res $x(p4)}
|
||||
}
|
||||
return $res
|
||||
}
|
||||
|
||||
# Run EXPLAIN on $sql. Return a list of P5 values for all $opcode
|
||||
# opcodes that contain regexp $comment in their comment
|
||||
#
|
||||
proc p5_of_opcode {db opcode comment sql} {
|
||||
set res {}
|
||||
$db eval "EXPLAIN $sql" x {
|
||||
if {$x(opcode)==$opcode && [regexp $comment $x(comment)]} {
|
||||
lappend res $x(p5)
|
||||
}
|
||||
}
|
||||
return $res
|
||||
}
|
||||
|
||||
# Verify that when t1 is in the outer loop and t2 is in the inner loop,
|
||||
# no cursor hints occur for t1 (since it is a full table scan) but that
|
||||
# each t2 access has a cursor hint based on the current t1.a value.
|
||||
#
|
||||
do_test 1.1 {
|
||||
p4_of_opcode db CursorHint {
|
||||
SELECT * FROM t1 CROSS JOIN t2 WHERE a=x
|
||||
}
|
||||
} {{EQ(r[1],c0)}}
|
||||
do_test 1.2 {
|
||||
p5_of_opcode db OpenRead . {
|
||||
SELECT * FROM t1 CROSS JOIN t2 WHERE a=x
|
||||
}
|
||||
} {00 00}
|
||||
|
||||
# Do the same test the other way around.
|
||||
#
|
||||
do_test 2.1 {
|
||||
p4_of_opcode db CursorHint {
|
||||
SELECT * FROM t2 CROSS JOIN t1 WHERE a=x
|
||||
}
|
||||
} {{EQ(c0,r[1])}}
|
||||
do_test 2.2 {
|
||||
p5_of_opcode db OpenRead . {
|
||||
SELECT * FROM t2 CROSS JOIN t1 WHERE a=x
|
||||
}
|
||||
} {00 00}
|
||||
|
||||
# Various expressions captured by CursorHint
|
||||
#
|
||||
do_test 3.1 {
|
||||
p4_of_opcode db CursorHint {
|
||||
SELECT * FROM t1 WHERE a=15 AND c=22 AND rowid!=98
|
||||
}
|
||||
} {AND(AND(EQ(c0,15),EQ(c2,22)),NE(rowid,98))}
|
||||
do_test 3.2 {
|
||||
p4_of_opcode db CursorHint {
|
||||
SELECT * FROM t3 WHERE a<15 AND b>22 AND id!=98
|
||||
}
|
||||
} {AND(AND(LT(c1,15),GT(c2,22)),NE(c0,98))}
|
||||
|
||||
# Indexed queries
|
||||
#
|
||||
do_test 4.1asc {
|
||||
db eval {
|
||||
CREATE INDEX t1bc ON t1(b,c);
|
||||
CREATE INDEX t2yz ON t2(y,z);
|
||||
}
|
||||
p4_of_opcode db CursorHint {
|
||||
SELECT * FROM t1 WHERE b>11 ORDER BY b ASC;
|
||||
}
|
||||
} {}
|
||||
do_test 4.1desc {
|
||||
p4_of_opcode db CursorHint {
|
||||
SELECT * FROM t1 WHERE b>11 ORDER BY b DESC;
|
||||
}
|
||||
} {GT(c0,11)}
|
||||
do_test 4.2 {
|
||||
p5_of_opcode db OpenRead . {
|
||||
SELECT * FROM t1 WHERE b>11;
|
||||
}
|
||||
} {02 00}
|
||||
do_test 4.3asc {
|
||||
p4_of_opcode db CursorHint {
|
||||
SELECT c FROM t1 WHERE b<11 ORDER BY b ASC;
|
||||
}
|
||||
} {LT(c0,11)}
|
||||
do_test 4.3desc {
|
||||
p4_of_opcode db CursorHint {
|
||||
SELECT c FROM t1 WHERE b<11 ORDER BY b DESC;
|
||||
}
|
||||
} {}
|
||||
do_test 4.4 {
|
||||
p5_of_opcode db OpenRead . {
|
||||
SELECT c FROM t1 WHERE b<11;
|
||||
}
|
||||
} {00}
|
||||
|
||||
do_test 4.5asc {
|
||||
p4_of_opcode db CursorHint {
|
||||
SELECT c FROM t1 WHERE b>=10 AND b<=20 ORDER BY b ASC;
|
||||
}
|
||||
} {LE(c0,20)}
|
||||
do_test 4.5desc {
|
||||
p4_of_opcode db CursorHint {
|
||||
SELECT c FROM t1 WHERE b>=10 AND b<=20 ORDER BY b DESC;
|
||||
}
|
||||
} {GE(c0,10)}
|
||||
|
||||
# If there are any equality terms used in the constraint, then all terms
|
||||
# should be hinted.
|
||||
#
|
||||
do_test 4.6asc {
|
||||
p4_of_opcode db CursorHint {
|
||||
SELECT rowid FROM t1 WHERE b=22 AND c>=10 AND c<=20 ORDER BY b,c ASC;
|
||||
}
|
||||
} {AND(AND(EQ(c0,22),GE(c1,10)),LE(c1,20))}
|
||||
do_test 4.6desc {
|
||||
p4_of_opcode db CursorHint {
|
||||
SELECT rowid FROM t1 WHERE b=22 AND c>=10 AND c<=20 ORDER BY b,c DESC;
|
||||
}
|
||||
} {AND(AND(EQ(c0,22),GE(c1,10)),LE(c1,20))}
|
||||
|
||||
finish_test
|
||||
@@ -26,7 +26,9 @@ proc parse_uri {uri} {
|
||||
set DB [sqlite3_open_v2 $uri {
|
||||
SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_WAL
|
||||
} tvfs]
|
||||
set fileName [sqlite3_db_filename $DB main]
|
||||
sqlite3_close $DB
|
||||
forcedelete $fileName
|
||||
tvfs delete
|
||||
tvfs2 delete
|
||||
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
# 2001 September 15
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the SELECT statement.
|
||||
#
|
||||
# $Id: select1.test,v 1.70 2009/05/28 01:00:56 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set ::testprefix fordelete
|
||||
|
||||
# This function returns a list of the tables or indexes opened with
|
||||
# OP_OpenWrite instructions when the SQL statement passed as the only
|
||||
# argument is executed. If the OPFLAG_FORDELETE flag is specified on
|
||||
# the OP_OpenWrite, an asterix is appended to the object name. The list
|
||||
# is sorted in [lsort] order before it is returned.
|
||||
#
|
||||
proc analyze_delete_program {sql} {
|
||||
# Build a map from root page to table/index name.
|
||||
db eval {
|
||||
SELECT name, rootpage FROM sqlite_master
|
||||
} {
|
||||
set T($rootpage) $name
|
||||
}
|
||||
|
||||
# Calculate the results.
|
||||
set res [list]
|
||||
db eval "EXPLAIN $sql" R {
|
||||
if {$R(opcode) == "OpenWrite"} {
|
||||
set obj $T($R(p2))
|
||||
if {"0x$R(p5)" & 0x08} { append obj *}
|
||||
lappend res $obj
|
||||
}
|
||||
}
|
||||
|
||||
lsort $res
|
||||
}
|
||||
|
||||
proc do_adp_test {tn sql res} {
|
||||
uplevel [list do_test $tn [list analyze_delete_program $sql] [list {*}$res]]
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a PRIMARY KEY, b);
|
||||
}
|
||||
|
||||
foreach {tn sql res} {
|
||||
1 { DELETE FROM t1 WHERE a=?} { sqlite_autoindex_t1_1 t1* }
|
||||
2 { DELETE FROM t1 WHERE a=? AND b=? } { sqlite_autoindex_t1_1 t1 }
|
||||
3 { DELETE FROM t1 WHERE a>? } { sqlite_autoindex_t1_1 t1* }
|
||||
4 { DELETE FROM t1 WHERE rowid=? } { sqlite_autoindex_t1_1* t1 }
|
||||
} {
|
||||
do_adp_test 1.$tn $sql $res
|
||||
}
|
||||
|
||||
do_execsql_test 2.0 {
|
||||
CREATE TABLE t2(a, b, c);
|
||||
CREATE INDEX t2a ON t2(a);
|
||||
CREATE INDEX t2b ON t2(b);
|
||||
CREATE INDEX t2c ON t2(c);
|
||||
}
|
||||
foreach {tn sql res} {
|
||||
1 { DELETE FROM t2 WHERE a=?} { t2* t2a t2b* t2c* }
|
||||
2 { DELETE FROM t2 WHERE a=? AND +b=?} { t2 t2a t2b* t2c* }
|
||||
3 { DELETE FROM t2 WHERE a=? OR b=?} { t2 t2a* t2b* t2c* }
|
||||
4 { DELETE FROM t2 WHERE +a=? } { t2 t2a* t2b* t2c* }
|
||||
5 { DELETE FROM t2 WHERE rowid=? } { t2 t2a* t2b* t2c* }
|
||||
} {
|
||||
do_adp_test 2.$tn $sql $res
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that a record that consists of the bytes:
|
||||
#
|
||||
# 0x01 0x00
|
||||
#
|
||||
# is interpreted by OP_Column as a vector of NULL values (assuming the
|
||||
# default column values are NULL). Also test that:
|
||||
#
|
||||
# 0x00
|
||||
#
|
||||
# is handled in the same way.
|
||||
#
|
||||
do_execsql_test 3.0 {
|
||||
CREATE TABLE x1(a INTEGER PRIMARY KEY, b, c, d);
|
||||
CREATE TABLE x2(a INTEGER PRIMARY KEY, b, c, d);
|
||||
}
|
||||
|
||||
do_test 3.1 {
|
||||
set root [db one { SELECT rootpage FROM sqlite_master WHERE name = 'x1' }]
|
||||
db eval {
|
||||
BEGIN IMMEDIATE;
|
||||
}
|
||||
set bt [btree_from_db db]
|
||||
set csr [btree_cursor $bt $root 1]
|
||||
btree_insert $csr 5 "\000"
|
||||
btree_close_cursor $csr
|
||||
db eval { COMMIT }
|
||||
|
||||
db eval {
|
||||
SELECT * FROM x1;
|
||||
}
|
||||
} {5 {} {} {}}
|
||||
|
||||
do_test 3.2 {
|
||||
set root [db one { SELECT rootpage FROM sqlite_master WHERE name = 'x2' }]
|
||||
db eval {
|
||||
BEGIN IMMEDIATE;
|
||||
}
|
||||
set bt [btree_from_db db]
|
||||
set csr [btree_cursor $bt $root 1]
|
||||
btree_insert $csr 6 "\000"
|
||||
btree_close_cursor $csr
|
||||
db eval { COMMIT }
|
||||
|
||||
db eval {
|
||||
SELECT * FROM x2;
|
||||
}
|
||||
} {6 {} {} {}}
|
||||
|
||||
finish_test
|
||||
|
||||
+6
-3
@@ -70,6 +70,9 @@
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include "sqlite3.h"
|
||||
#define ISSPACE(X) isspace((unsigned char)(X))
|
||||
#define ISDIGIT(X) isdigit((unsigned char)(X))
|
||||
|
||||
|
||||
#ifdef __unix__
|
||||
# include <signal.h>
|
||||
@@ -633,9 +636,9 @@ static void runSql(sqlite3 *db, const char *zSql, unsigned runFlags){
|
||||
if( runFlags & SQL_TRACE ){
|
||||
const char *z = zSql;
|
||||
int n;
|
||||
while( z<zMore && isspace(z[0]) ) z++;
|
||||
while( z<zMore && ISSPACE(z[0]) ) z++;
|
||||
n = (int)(zMore - z);
|
||||
while( n>0 && isspace(z[n-1]) ) n--;
|
||||
while( n>0 && ISSPACE(z[n-1]) ) n--;
|
||||
if( n==0 ) break;
|
||||
if( pStmt==0 ){
|
||||
printf("TRACE: %.*s (error: %s)\n", n, z, sqlite3_errmsg(db));
|
||||
@@ -757,7 +760,7 @@ static int integerValue(const char *zArg){
|
||||
zArg++;
|
||||
}
|
||||
}else{
|
||||
while( isdigit(zArg[0]) ){
|
||||
while( ISDIGIT(zArg[0]) ){
|
||||
v = v*10 + zArg[0] - '0';
|
||||
zArg++;
|
||||
}
|
||||
|
||||
@@ -62,6 +62,21 @@ do_execsql_test index3-2.2eqp {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT a FROM t1 WHERE b='ab005xy' COLLATE nocase;
|
||||
} {/USING INDEX/}
|
||||
do_execsql_test index3-2.3 {
|
||||
SELECT name FROM sqlite_master WHERE tbl_name='t1' ORDER BY name
|
||||
} {sqlite_autoindex_t1_1 sqlite_autoindex_t1_2 t1 t1c t1d}
|
||||
do_execsql_test index3-2.4 {
|
||||
CREATE TABLE t2a(a integer, b, PRIMARY KEY(a));
|
||||
CREATE TABLE t2b("a" integer, b, PRIMARY KEY("a"));
|
||||
CREATE TABLE t2c([a] integer, b, PRIMARY KEY([a]));
|
||||
CREATE TABLE t2d('a' integer, b, PRIMARY KEY('a'));
|
||||
}
|
||||
do_execsql_test index3-2.5 {
|
||||
SELECT name FROM sqlite_master WHERE tbl_name LIKE 't2_' ORDER BY name
|
||||
} {t2a t2b t2c t2d}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# This test corrupts the database file so it must be the last test
|
||||
|
||||
@@ -324,5 +324,22 @@ do_execsql_test json-6.4 {
|
||||
SELECT json_valid('["a",55,"b",72]');
|
||||
} {1}
|
||||
|
||||
# White-space tests. Note that form-feed is not white-space in JSON.
|
||||
# ticket [57eec374ae1d0a1d4a23077a95f4e173fe269113]
|
||||
#
|
||||
foreach {tn isvalid ws} {
|
||||
7.1 1 char(0x20)
|
||||
7.2 1 char(0x09)
|
||||
7.3 1 char(0x0A)
|
||||
7.4 1 char(0x0D)
|
||||
7.5 0 char(0x0C)
|
||||
7.6 1 char(0x20,0x09,0x0a,0x0d,0x20)
|
||||
7.7 0 char(0x20,0x09,0x0a,0x0c,0x0d,0x20)
|
||||
} {
|
||||
do_execsql_test json-$tn.1 \
|
||||
"SELECT json_valid(printf('%s{%s\"x\"%s:%s9%s}%s',
|
||||
$::ws,$::ws,$::ws,$::ws,$::ws,$::ws));" \
|
||||
$isvalid
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
+3
-1
@@ -93,7 +93,9 @@ do_test 1.4.1 {
|
||||
list [catch { sqlite3 dbh /root/test.db } msg] $msg
|
||||
} {1 {unable to open database file}}
|
||||
|
||||
do_re_test 1.4.2 { lindex $::log 0 } {^os_unix.c:\d*: \(\d+\) open\(.*test.db\) - }
|
||||
do_re_test 1.4.2 {
|
||||
lindex $::log 0
|
||||
} {^os_unix.c:\d*: \(\d+\) (open|readlink)\(.*test.db\) - }
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Tests oserror-1.* test failures in the unlink() system call.
|
||||
|
||||
@@ -707,7 +707,7 @@ test_suite "inmemory_journal" -description {
|
||||
pragma journal_mode = 'memory'
|
||||
} -files [test_set $::allquicktests -exclude {
|
||||
# Exclude all tests that simulate IO errors.
|
||||
autovacuum_ioerr2.test incrvacuum_ioerr.test ioerr.test
|
||||
autovacuum_ioerr2.test cffault.test incrvacuum_ioerr.test ioerr.test
|
||||
ioerr.test ioerr2.test ioerr3.test ioerr4.test ioerr5.test
|
||||
vacuum3.test incrblob_err.test diskfull.test backup_ioerr.test
|
||||
e_fts3.test fts3cov.test fts3malloc.test fts3rnd.test
|
||||
@@ -723,7 +723,7 @@ test_suite "inmemory_journal" -description {
|
||||
corrupt5.test corruptA.test pageropt.test
|
||||
|
||||
# Exclude stmt.test, which expects sub-journals to use temporary files.
|
||||
stmt.test
|
||||
stmt.test symlink.test
|
||||
|
||||
zerodamage.test
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user