Compare commits

..

3 Commits

418 changed files with 22470 additions and 64145 deletions
+16 -10
View File
@@ -30,12 +30,14 @@ The public domain source files usually contain a header comment
similar to the following to make it clear that the software is
public domain.
> The author disclaims copyright to this source code. In place of
> a legal notice, here is a blessing:
>
> * May you do good and not evil.
> * May you find forgiveness for yourself and forgive others.
> * May you share freely, never taking more than you give.
> ~~~
The 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.
~~~
Almost every file you find in this source repository will be
public domain. But there are a small number of exceptions:
@@ -47,7 +49,9 @@ This repository contains a (relatively) small amount of non-public-domain
code used to help implement the configuration and build logic. In other
words, there are some non-public-domain files used to implement:
> ./configure && make
> ~~~
./configure && make
~~~
In all cases, the non-public-domain files included with this
repository have generous BSD-style licenses. So anyone is free to
@@ -65,7 +69,7 @@ third-party build scripts in order to compile SQLite.
Non-public-domain code included in this respository includes:
* The ["autosetup"](http://msteveb.github.io/autosetup/) configuration
system that is contained (mostly) in the autosetup/ directory, but also
system that is contained (mostly) the autosetup/ directory, but also
includes the "./configure" script at the top-level of this archive.
Autosetup has a separate BSD-style license. See the
[autosetup/LICENSE](http://msteveb.github.io/autosetup/license/)
@@ -75,11 +79,13 @@ Non-public-domain code included in this respository includes:
software found in the legacy autoconf/ directory and its
subdirectories.
The following unix shell command can be run from the top-level
The following unix shell command is can be run from the top-level
of this source repository in order to remove all non-public-domain
code:
> rm -rf configure autosetup autoconf
> ~~~
rm -rf configure autosetup autoconf
~~~
If you unpack this source repository and then run the command above, what
is left will be 100% public domain.
+3 -11
View File
@@ -131,15 +131,9 @@ libsqlite3.DLL.install-rules = @SQLITE_DLL_INSTALL_RULES@
CFLAGS.fuzzcheck-asan.fsanitize = @CFLAGS_ASAN_FSANITIZE@
#
# TARGET_DEBUG is intended to either be empty or be set to -g
# -DSQLITE_DEBUG=1, plus any other flags relevant for debug-only
# builds. These get added near the front of $(T.cc) so that they can
# be overridden by CFLAGS passed directly to make. Historically (prior
# to 2026-03-30) these were at/near the end of the flags but that made
# it impossible to pass custom -O* flags to specific binaries without
# reconfiguring.
# Intended to either be empty or be set to -g -DSQLITE_DEBUG=1.
#
T.cc += @TARGET_DEBUG@
T.cc.TARGET_DEBUG = @TARGET_DEBUG@
#
# $(JIMSH) and $(CFLAGS.jimsh) are documented in main.mk. $(JIMSH)
@@ -170,9 +164,7 @@ OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@ $(OPTIONS)
PACKAGE_VERSION = @PACKAGE_VERSION@
#
# Filename extensions for binaries and libraries. B.* are for the
# being-built-on platform and T.* are for the build's target platform.
# i.e. B.* is for build-time tooling and T.* is for deliverables.
# Filename extensions for binaries and libraries
#
B.exe = @BUILD_EXEEXT@
T.exe = @TARGET_EXEEXT@
+165 -256
View File
@@ -11,8 +11,6 @@
TOP = .
# <<mark>>
# ^^^^^^^^-- content between mark and /mark omitted from autoconf/Makefile.msc
#
# Set this non-0 to create and use the SQLite amalgamation file.
#
!IFNDEF USE_AMALGAMATION
@@ -103,6 +101,13 @@ NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4244 -wd4305 -wd4306 -wd4702 -wd4706
!ENDIF
!ENDIF
# Set this non-0 to use the library paths and other options necessary for
# Windows Phone 8.1.
#
!IFNDEF USE_WP81_OPTS
USE_WP81_OPTS = 0
!ENDIF
# Set this non-0 to split the SQLite amalgamation file into chunks to
# be used for debugging with Visual Studio.
#
@@ -111,8 +116,14 @@ SPLIT_AMALGAMATION = 0
!ENDIF
# <<mark>>
# ^^^^^^^^-- content between mark and /mark omitted from autoconf/Makefile.msc
# Set this non-0 to have this makefile assume the Tcl shell executable
# (tclsh*.exe) is available in the PATH. By default, this is disabled
# for compatibility with older build environments. This setting only
# applies if TCLSH_CMD is not set manually.
#
!IFNDEF USE_TCLSH_IN_PATH
USE_TCLSH_IN_PATH = 0
!ENDIF
# Set this non-0 to use zlib, possibly compiling it from source code.
#
@@ -175,6 +186,14 @@ USE_NATIVE_LIBPATHS = 0
USE_RC = 1
!ENDIF
# Set this non-0 to compile binaries suitable for the WinRT environment.
# This setting does not apply to any binaries that require Tcl to operate
# properly (i.e. the text fixture, etc).
#
!IFNDEF FOR_WINRT
FOR_WINRT = 0
!ENDIF
# Set this non-0 to compile binaries suitable for the UWP environment.
# This setting does not apply to any binaries that require Tcl to operate
# properly (i.e. the text fixture, etc).
@@ -190,8 +209,6 @@ FOR_WIN10 = 0
!ENDIF
# <<mark>>
# ^^^^^^^^-- content between mark and /mark omitted from autoconf/Makefile.msc
#
# Set this non-0 to skip attempting to look for and/or link with the Tcl
# runtime library.
#
@@ -248,8 +265,6 @@ DEBUG = 0
!ENDIF
# <<mark>>
# ^^^^^^^^-- content between mark and /mark omitted from autoconf/Makefile.msc
#
# By default, use --linemacros=1 argument to the mksqlite3c.tcl tool, which
# is used to build the amalgamation. This can be turned off to ease debug
# of the amalgamation away from the source tree.
@@ -345,8 +360,6 @@ SQLITE3EXEPDB = /pdb:sqlite3sh.pdb
!ENDIF
# <<mark>>
# ^^^^^^^^-- content between mark and /mark omitted from autoconf/Makefile.msc
#
# These are the names of the customized Tcl header files used by various parts
# of this makefile when the stdcall calling convention is in use. It is not
# used for any other purpose.
@@ -392,7 +405,6 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_CARRAY=1
!ENDIF
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
!ENDIF
@@ -415,7 +427,6 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK=1
# Always enable math functions on Windows
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_MATH_FUNCTIONS
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PERCENTILE
# Should the rbu extension be enabled? If so, add compilation options
# to enable it.
@@ -628,24 +639,16 @@ RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -I$(TOP)\src $(RCOPTS) $(RCCOPTS)
!IF "$(PLATFORM)"=="x86"
CORE_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
SHELL_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
# <<mark>>
# ^^^^^^^^-- content between mark and /mark omitted from autoconf/Makefile.msc
#
TEST_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall -DINCLUDE_SQLITE_TCL_H=1 -DSQLITE_TCLAPI=__cdecl
# <</mark>>
!ELSE
!IFNDEF PLATFORM
CORE_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
SHELL_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
# <<mark>>
# ^^^^^^^^-- content between mark and /mark omitted from autoconf/Makefile.msc
#
TEST_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall -DINCLUDE_SQLITE_TCL_H=1 -DSQLITE_TCLAPI=__cdecl
# <</mark>>
!ELSE
CORE_CCONV_OPTS =
SHELL_CCONV_OPTS =
@@ -772,6 +775,18 @@ SHELL_LINK_OPTS = $(SHELL_CORE_LIB)
TCC = $(TCC) -FAcs
!ENDIF
# When compiling the library for use in the WinRT environment,
# the following compile-time options must be used as well to
# disable use of Win32 APIs that are not available and to enable
# use of Win32 APIs that are specific to Windows 8 and/or WinRT.
#
!IF $(FOR_WINRT)!=0
TCC = $(TCC) -DSQLITE_OS_WINRT=1
RCC = $(RCC) -DSQLITE_OS_WINRT=1
TCC = $(TCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
RCC = $(RCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
!ENDIF
# C compiler options for the Windows 10 platform (needs MSVC 2015).
#
!IF $(FOR_WIN10)!=0
@@ -784,31 +799,25 @@ BCC = $(BCC) /d2guard4 -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
# USE_CRT_DLL option is set to force dynamically linking to the
# MSVC runtime library.
#
!IF $(USE_CRT_DLL)!=0
!IF $(FOR_WINRT)!=0 || $(USE_CRT_DLL)!=0
!IF $(DEBUG)>1
TCC = $(TCC) -MDd
BCC = $(BCC) -MDd
ZLIBCFLAGS = -nologo -MDd -W3 -O2 -Oy- -Zi
!ELSE
TCC = $(TCC) -MD
BCC = $(BCC) -MD
ZLIBCFLAGS = -nologo -MD -W3 -O2 -Oy- -Zi
!ENDIF
!ELSE
!IF $(DEBUG)>1
TCC = $(TCC) -MTd
BCC = $(BCC) -MTd
ZLIBCFLAGS = -nologo -MTd -W3 -O2 -Oy- -Zi
!ELSE
TCC = $(TCC) -MT
BCC = $(BCC) -MT
ZLIBCFLAGS = -nologo -MT -W3 -O2 -Oy- -Zi
!ENDIF
!ENDIF
# <<mark>>
# ^^^^^^^^-- content between mark and /mark omitted from autoconf/Makefile.msc
#
# The mksqlite3c.tcl and mksqlite3h.tcl scripts will pull in
# any extension header files by default. For non-amalgamation
# builds, we need to make sure the compiler can find these.
@@ -859,6 +868,16 @@ MKSQLITE3H_ARGS =
!ENDIF
# <</mark>>
# Define -DNDEBUG to compile without debugging (i.e., for production usage)
# Omitting the define will cause extra debugging code to be inserted and
# includes extra comments when "EXPLAIN stmt" is used.
#
!IF $(DEBUG)==0
TCC = $(TCC) -DNDEBUG
BCC = $(BCC) -DNDEBUG
RCC = $(RCC) -DNDEBUG
!ENDIF
!IF $(DEBUG)>0 || $(API_ARMOR)!=0 || $(FOR_WIN10)!=0
TCC = $(TCC) -DSQLITE_ENABLE_API_ARMOR=1
RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR=1
@@ -924,8 +943,6 @@ TCC = $(TCC) /fsanitize=address
!ENDIF
# <<mark>>
# ^^^^^^^^-- content between mark and /mark omitted from autoconf/Makefile.msc
#
# The locations of the Tcl header and library files. Also, the library that
# non-stubs enabled programs using Tcl must link against. These variables
# (TCLINCDIR, TCLLIBDIR, and LIBTCL) may be overridden via the environment
@@ -1165,8 +1182,6 @@ BCC = $(BCC) -Zi
!ENDIF
# <<mark>>
# ^^^^^^^^-- content between mark and /mark omitted from autoconf/Makefile.msc
#
# If zlib support is enabled, add the compiler options for it.
#
!IF $(USE_ZLIB)!=0
@@ -1219,6 +1234,56 @@ LTLINKOPTS = /NOLOGO
LTLIBOPTS = /NOLOGO
!ENDIF
# When compiling for use in the WinRT environment, the following
# linker option must be used to mark the executable as runnable
# only in the context of an application container.
#
!IF $(FOR_WINRT)!=0
LTLINKOPTS = $(LTLINKOPTS) /APPCONTAINER
!IF "$(VISUALSTUDIOVERSION)"=="12.0" || "$(VISUALSTUDIOVERSION)"=="14.0"
!IFNDEF STORELIBPATH
!IF "$(PLATFORM)"=="x86"
STORELIBPATH = $(CRTLIBPATH)\store
!ELSEIF "$(PLATFORM)"=="x64"
STORELIBPATH = $(CRTLIBPATH)\store\amd64
!ELSEIF "$(PLATFORM)"=="ARM"
STORELIBPATH = $(CRTLIBPATH)\store\arm
!ELSE
STORELIBPATH = $(CRTLIBPATH)\store
!ENDIF
!ENDIF
STORELIBPATH = $(STORELIBPATH:\\=\)
LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(STORELIBPATH)"
!ENDIF
!ENDIF
# When compiling for Windows Phone 8.1, an extra library path is
# required.
#
!IF $(USE_WP81_OPTS)!=0
!IFNDEF WP81LIBPATH
!IF "$(PLATFORM)"=="x86"
WP81LIBPATH = $(PROGRAMFILES_X86)\Windows Phone Kits\8.1\lib\x86
!ELSEIF "$(PLATFORM)"=="ARM"
WP81LIBPATH = $(PROGRAMFILES_X86)\Windows Phone Kits\8.1\lib\ARM
!ELSE
WP81LIBPATH = $(PROGRAMFILES_X86)\Windows Phone Kits\8.1\lib\x86
!ENDIF
!ENDIF
!ENDIF
# When compiling for Windows Phone 8.1, some extra linker options
# are also required.
#
!IF $(USE_WP81_OPTS)!=0
!IFDEF WP81LIBPATH
LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(WP81LIBPATH)"
!ENDIF
LTLINKOPTS = $(LTLINKOPTS) /DYNAMICBASE
LTLINKOPTS = $(LTLINKOPTS) WindowsPhoneCore.lib RuntimeObject.lib PhoneAppModelHost.lib
LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:kernel32.lib /NODEFAULTLIB:ole32.lib
!ENDIF
# When compiling for UWP or the Windows 10 platform, some extra linker
# options are also required.
#
@@ -1242,14 +1307,12 @@ LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib
# If either debugging or symbols are enabled, enable PDBs.
#
!IF $(DEBUG)>1 || $(SYMBOLS)!=0
LDFLAGS = /NODEFAULTLIB:msvcrt /DEBUG $(LDOPTS)
LDFLAGS = /DEBUG $(LDOPTS)
!ELSE
LDFLAGS = /NODEFAULTLIB:msvcrt $(LDOPTS)
LDFLAGS = $(LDOPTS)
!ENDIF
# <<mark>>
# ^^^^^^^^-- content between mark and /mark omitted from autoconf/Makefile.msc
#
# Start with the Tcl related linker options.
#
!IF $(NO_TCL)==0
@@ -1276,13 +1339,11 @@ LTLIBS = $(LTLIBS) $(LIBICU)
###############################################################################
# <<mark>>
# ^^^^^^^^-- content between mark and /mark omitted from autoconf/Makefile.msc
#
# Object files for the SQLite library (non-amalgamation).
#
LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \
backup.lo bitvec.lo btmutex.lo btree.lo build.lo \
callback.lo carray.lo complete.lo ctime.lo \
callback.lo complete.lo ctime.lo \
date.lo dbpage.lo dbstat.lo delete.lo \
expr.lo fault.lo fkey.lo \
fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \
@@ -1344,7 +1405,6 @@ SRC00 = \
$(TOP)\src\btree.c \
$(TOP)\src\build.c \
$(TOP)\src\callback.c \
$(TOP)\src\carray.c \
$(TOP)\src\complete.c \
ctime.c \
$(TOP)\src\date.c \
@@ -1396,7 +1456,7 @@ SRC01 = \
$(TOP)\src\status.c \
$(TOP)\src\table.c \
$(TOP)\src\threads.c \
tclsqlite-ex.c \
$(TOP)\src\tclsqlite.c \
$(TOP)\src\tokenize.c \
$(TOP)\src\treeview.c \
$(TOP)\src\trigger.c \
@@ -1578,6 +1638,7 @@ TESTEXT = \
$(TOP)\ext\misc\amatch.c \
$(TOP)\ext\misc\appendvfs.c \
$(TOP)\ext\misc\basexx.c \
$(TOP)\ext\misc\carray.c \
$(TOP)\ext\misc\cksumvfs.c \
$(TOP)\ext\misc\closure.c \
$(TOP)\ext\misc\csv.c \
@@ -1593,6 +1654,7 @@ TESTEXT = \
$(TOP)\ext\misc\mmapwarm.c \
$(TOP)\ext\misc\nextchar.c \
$(TOP)\ext\misc\normalize.c \
$(TOP)\ext\misc\percentile.c \
$(TOP)\ext\misc\prefixes.c \
$(TOP)\ext\misc\qpvtab.c \
$(TOP)\ext\misc\randomjson.c \
@@ -1704,10 +1766,8 @@ SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_DQS=0
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS4=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_PERCENTILE=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_STMT_SCANSTATUS=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_STRICT_SUBTYPE=1
!ENDIF
@@ -1719,9 +1779,7 @@ FUZZERSHELL_COMPILE_OPTS =
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -I$(TOP)\test -I$(TOP)\ext\recover
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_MEMSYS5
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_OSS_FUZZ
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_DECIMAL_MAX_DIGIT=1000
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_BYTECODE_VTAB
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_CARRAY
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_DBPAGE_VTAB
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_DBSTAT_VTAB
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_BYTECODE_VTAB
@@ -1735,7 +1793,6 @@ FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_MATH_FUNCTIONS
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_MEMSYS5
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_NORMALIZE
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_PERCENTILE
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_PREUPDATE_HOOK
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_RTREE
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_SESSION
@@ -1766,17 +1823,8 @@ FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\test\fuzzinvariants.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\test\vt02.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\recover\dbdata.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\recover\sqlite3recover.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\base64.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\base85.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\completion.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\decimal.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\ieee754.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\percentile.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\randomjson.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\regexp.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\series.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\shathree.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\sha1.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\stmtrand.c
OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c
DBFUZZ_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION
@@ -1877,8 +1925,8 @@ $(SQLITE3EXE): shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLIT
/link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
# <<mark>>
sqldiff.exe: $(TOP)\tool\sqldiff.c $(TOP)\ext\misc\sqlite3_stdio.h $(TOP)\ext\misc\sqlite3_stdio.c $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS) $(TOP)\tool\winmain.c
$(LTLINK) $(NO_WARN) -I$(TOP)\ext\misc $(TOP)\tool\sqldiff.c $(TOP)\ext\misc\sqlite3_stdio.c $(TOP)\tool\winmain.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(LIBRESOBJS)
sqldiff.exe: $(TOP)\tool\sqldiff.c $(TOP)\ext\misc\sqlite3_stdio.h $(TOP)\ext\misc\sqlite3_stdio.c $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS)
$(LTLINK) $(NO_WARN) -I$(TOP)\ext\misc $(TOP)\tool\sqldiff.c $(TOP)\ext\misc\sqlite3_stdio.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(LIBRESOBJS)
dbhash.exe: $(TOP)\tool\dbhash.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(TOP)\tool\dbhash.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
@@ -1968,18 +2016,8 @@ sqlite3.c: .target_source sqlite3ext.h sqlite3session.h $(MKSQLITE3C_TOOL) src-v
sqlite3-all.c: sqlite3.c $(TOP)\tool\split-sqlite3c.tcl $(JIM_TCLSH)
$(JIM_TCLSH) $(TOP)\tool\split-sqlite3c.tcl
TCLSQLITEEX = \
$(TOP)\ext\qrf\qrf.h \
$(TOP)\ext\qrf\qrf.c \
$(TOP)\src\tclsqlite.c
tclsqlite-ex.c: $(TCLSQLITEEX) $(TOP)\tool\mkcombo.tcl $(JIM_TCLSH)
$(JIM_TCLSH) $(TOP)\tool\mkcombo.tcl $(TCLSQLITEEX) -o $@
# <</mark>>
tclsqlite-ex.c:
# Rule to build the amalgamation
#
sqlite3.lo: $(SQLITE3C)
@@ -2063,9 +2101,6 @@ build.lo: $(TOP)\src\build.c $(HDR)
callback.lo: $(TOP)\src\callback.c $(HDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\callback.c
carray.lo: $(TOP)\src\carray.c $(HDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\carray.c
complete.lo: $(TOP)\src\complete.c $(HDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\complete.c
@@ -2279,11 +2314,11 @@ whereexpr.lo: $(TOP)\src\whereexpr.c $(HDR)
window.lo: $(TOP)\src\window.c $(HDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\window.c
tclsqlite.lo: tclsqlite-ex.c $(HDR) $(SQLITE_TCL_DEP)
$(LTCOMPILE) $(NO_WARN) -DUSE_TCL_STUBS=1 -DBUILD_sqlite -I$(TCLINCDIR) -c tclsqlite-ex.c /OUT:tclsqlite.lo
tclsqlite.lo: $(TOP)\src\tclsqlite.c $(HDR) $(SQLITE_TCL_DEP)
$(LTCOMPILE) $(NO_WARN) -DUSE_TCL_STUBS=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
tclsqlite-shell.lo: tclsqlite-ex.c $(HDR) $(SQLITE_TCL_DEP)
$(LTCOMPILE) $(NO_WARN) -DTCLSH -DBUILD_sqlite -I$(TCLINCDIR) -c tclsqlite-ex.c
tclsqlite-shell.lo: $(TOP)\src\tclsqlite.c $(HDR) $(SQLITE_TCL_DEP)
$(LTCOMPILE) $(NO_WARN) -DTCLSH -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
tclsqlite3.exe: tclsqlite-shell.lo $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS)
$(LTLINK) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) /OUT:$@ tclsqlite-shell.lo $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS)
@@ -2336,8 +2371,6 @@ keywordhash.h: $(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe
# Source and header files that shell.c depends on
SHELL_DEP = \
$(TOP)\src\shell.c.in \
$(TOP)\ext\qrf\qrf.c \
$(TOP)\ext\qrf\qrf.h \
$(TOP)\ext\expert\sqlite3expert.c \
$(TOP)\ext\expert\sqlite3expert.h \
$(TOP)\ext\intck\sqlite3intck.c \
@@ -2351,6 +2384,7 @@ SHELL_DEP = \
$(TOP)\ext\misc\ieee754.c \
$(TOP)\ext\misc\memtrace.c \
$(TOP)\ext\misc\pcachetrace.c \
$(TOP)\ext\misc\percentile.c \
$(TOP)\ext\misc\regexp.c \
$(TOP)\ext\misc\series.c \
$(TOP)\ext\misc\sha1.c \
@@ -2377,7 +2411,7 @@ shell.c: $(SHELL_DEP) $(TOP)\tool\mkshellc.tcl $(JIM_TCLSH)
$(JIM_TCLSH) $(TOP)\tool\mkshellc.tcl shell.c
zlib:
pushd $(ZLIBDIR) && $(MAKE) /f win32\Makefile.msc clean $(ZLIBLIB) CFLAGS="$(ZLIBCFLAGS)" && popd
pushd $(ZLIBDIR) && $(MAKE) /f win32\Makefile.msc clean $(ZLIBLIB) && popd
# Rules to build the extension objects.
#
@@ -2491,8 +2525,6 @@ TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_DEFAULT_PAGE_SIZE=1024
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_CARRAY=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_PERCENTILE=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_CKSUMVFS_STATIC=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) $(TEST_CCONV_OPTS)
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_STATIC_RANDOMJSON
@@ -2501,9 +2533,9 @@ TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_STRICT_SUBTYPE=1
TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2)
TESTFIXTURE_SRC1 = $(TESTEXT) $(SQLITE3C)
!IF $(USE_AMALGAMATION)==0
TESTFIXTURE_SRC = $(TESTSRC) tclsqlite-ex.c $(TESTFIXTURE_SRC0)
TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0)
!ELSE
TESTFIXTURE_SRC = $(TESTSRC) tclsqlite-ex.c $(TESTFIXTURE_SRC1)
TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC1)
!ENDIF
!IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0
@@ -2551,19 +2583,43 @@ coretestprogs: testfixture.exe sqlite3.exe
testprogs: $(TESTPROGS) srcck1.exe fuzzcheck.exe sessionfuzz.exe
fulltest: alltest fuzztest
alltest: $(TESTPROGS)
@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 shell
@set PATH=$(LIBTCLPATH);$(PATH)
.\testfixture.exe $(TOP)\test\permutations.test queryplanner $(TESTOPTS)
fuzztest: fuzzcheck.exe
.\fuzzcheck.exe $(FUZZDATA)
# Legacy testing target for third-party integrators. The SQLite
# developers seldom use this target themselves. Instead
# they use "nmake /f Makefile.msc devtest" which runs tests on
# a standard set of options
#
# Legacy testing targets, no longer used by the developers and
# now aliased to one of the commonly used testing targets.
test: $(TESTPROGS) sourcetest fuzztest tcltest
# Minimal testing that runs in less than 3 minutes (on a fast machine)
#
quicktest: testfixture.exe sourcetest
@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.
#
quicktest: devtest
test: devtest
fulltest: releasetest
alltest: releasetest
soaktest: releasetest
fulltestonly: releasetest
# The veryquick.test TCL tests.
#
@@ -2588,22 +2644,6 @@ devtest: srctree-check sourcetest
mdevtest:
$(TCLSH_CMD) $(TOP)\test\testrunner.tcl mdevtest
# Rerun test cases that failed on the previous testrunner invocation
#
retest:
$(TCLSH_CMD) $(TOP)\test\testrunner.tcl retest
# Show all errors from the most reason testrunner invocation
#
errors:
$(TCLSH_CMD) $(TOP)\test\testrunner.tcl errors
# Show the status of the current testrunner invocation,
# updated every couple of seconds
#
status:
$(TCLSH_CMD) $(TOP)\test\testrunner.tcl status -d 2
# Validate that various generated files in the source tree
# are up-to-date.
#
@@ -2627,23 +2667,17 @@ smoketest: $(TESTPROGS)
@set PATH=$(LIBTCLPATH);$(PATH)
.\testfixture.exe $(TOP)\test\main.test $(TESTOPTS)
# Measure the performance of floating-point conversions.
#
fp-speed-test: fp-speed-1.exe fp-speed-2.exe
fp-speed-1 1000000
fp-speed-2 1000000
shelltest: $(TESTPROGS)
.\testfixture.exe $(TOP)\test\permutations.test shell
shelltest:
$(TCLSH_CMD) $(TOP)\test\testrunner.tcl release shell
sqlite3_analyzer.c: $(SQLITE3C) $(SQLITE3H) tclsqlite-ex.c $(TOP)\tool\spaceanal.tcl $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in $(TOP)\ext\misc\sqlite3_stdio.h $(TOP)\ext\misc\sqlite3_stdio.c $(SQLITE_TCL_DEP)
sqlite3_analyzer.c: $(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in $(TOP)\ext\misc\sqlite3_stdio.h $(TOP)\ext\misc\sqlite3_stdio.c $(SQLITE_TCL_DEP)
$(TCLSH_CMD) $(TOP)\tool\mkccode.tcl -DINCLUDE_SQLITE3_C $(TOP)\tool\sqlite3_analyzer.c.in > $@
sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS)
$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_analyzer.c \
/link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS)
sqltclsh.c: sqlite3.c tclsqlite-ex.c $(TOP)\tool\sqltclsh.tcl $(TOP)\ext\misc\appendvfs.c $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqltclsh.c.in
sqltclsh.c: sqlite3.c $(TOP)\src\tclsqlite.c $(TOP)\tool\sqltclsh.tcl $(TOP)\ext\misc\appendvfs.c $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqltclsh.c.in
$(TCLSH_CMD) $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqltclsh.c.in >sqltclsh.c
sqltclsh.exe: sqltclsh.c $(SHELL_CORE_DEP) $(LIBRESOBJS)
@@ -2653,6 +2687,23 @@ sqltclsh.exe: sqltclsh.c $(SHELL_CORE_DEP) $(LIBRESOBJS)
sqlite3_expert.exe: $(SQLITE3C) $(TOP)\ext\expert\sqlite3expert.h $(TOP)\ext\expert\sqlite3expert.c $(TOP)\ext\expert\expert.c
$(LTLINK) $(NO_WARN) $(TOP)\ext\expert\sqlite3expert.c $(TOP)\ext\expert\expert.c $(SQLITE3C) $(TLIBS)
CHECKER_DEPS =\
$(TOP)\tool\mkccode.tcl \
sqlite3.c \
$(TOP)\src\tclsqlite.c \
$(TOP)\ext\repair\sqlite3_checker.tcl \
$(TOP)\ext\repair\checkindex.c \
$(TOP)\ext\repair\checkfreelist.c \
$(TOP)\ext\misc\btreeinfo.c \
$(TOP)\ext\repair\sqlite3_checker.c.in
sqlite3_checker.c: $(CHECKER_DEPS)
$(TCLSH_CMD) $(TOP)\tool\mkccode.tcl $(TOP)\ext\repair\sqlite3_checker.c.in > $@
sqlite3_checker.exe: sqlite3_checker.c $(LIBRESOBJS)
$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_checker.c \
/link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS)
dbdump.exe: $(TOP)\ext\misc\dbdump.c $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS)
$(LTLINK) $(NO_WARN) -DDBDUMP_STANDALONE $(TOP)\ext\misc\dbdump.c $(SQLITE3C) \
/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS)
@@ -2685,9 +2736,6 @@ showwal.exe: $(TOP)\tool\showwal.c $(SQLITE3C) $(SQLITE3H)
showshm.exe: $(TOP)\tool\showshm.c
$(LTLINK) $(NO_WARN) $(TOP)\tool\showshm.c /link $(LDFLAGS) $(LTLINKOPTS)
showtmlog.exe: $(TOP)\tool\showtmlog.c
$(LTLINK) $(NO_WARN) $(TOP)\tool\showtmlog.c /link $(LDFLAGS) $(LTLINKOPTS)
index_usage.exe: $(TOP)\tool\index_usage.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
$(TOP)\tool\index_usage.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
@@ -2725,14 +2773,6 @@ speedtest1.exe: $(TOP)\test\speedtest1.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(ST_COMPILE_OPTS) -DSQLITE_OMIT_LOAD_EXTENSION \
$(TOP)\test\speedtest1.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
fp-speed-1.exe: $(TOP)\test\fp-speed-1.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(ST_COMPILE_OPTS) -DSQLITE_OMIT_LOAD_EXTENSION \
$(TOP)\test\fp-speed-1.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
fp-speed-2.exe: $(TOP)\test\fp-speed-2.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(ST_COMPILE_OPTS) -DSQLITE_OMIT_LOAD_EXTENSION \
$(TOP)\test\fp-speed-2.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
kvtest.exe: $(TOP)\test\kvtest.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(KV_COMPILE_OPTS) \
$(TOP)\test\kvtest.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
@@ -2764,135 +2804,6 @@ tcl-env:
@echo JIM_TCLSH = $(JIM_TCLSH)
@echo VISUALSTUDIOVERSION = $(VISUALSTUDIOVERSION)
env:
@echo ALL_TCL_TARGETS = $(ALL_TCL_TARGETS)
@echo API_ARMOR = $(API_ARMOR)
@echo ASAN = $(ASAN)
@echo BCC = $(BCC)
@echo BUILD_ZLIB = $(BUILD_ZLIB)
@echo CC = $(CC)
@echo CCOPTS = $(CCOPTS)
@echo CHECKER_DEPS = $(CHECKER_DEPS)
@echo CORE_CCONV_OPTS = $(CORE_CCONV_OPTS)
@echo CORE_COMPILE_OPTS = $(CORE_COMPILE_OPTS)
@echo CORE_LINK_DEP = $(CORE_LINK_DEP)
@echo CORE_LINK_OPTS = $(CORE_LINK_OPTS)
@echo CRTLIBPATH = $(CRTLIBPATH)
@echo CSC = $(CSC)
@echo DBFUZZ_COMPILE_OPTS = $(DBFUZZ_COMPILE_OPTS)
@echo DEBUG = $(DEBUG)
@echo DYNAMIC_SHELL = $(DYNAMIC_SHELL)
@echo EXT_FEATURE_FLAGS = $(EXT_FEATURE_FLAGS)
@echo EXTHDR = $(EXTHDR)
@echo EXTRA_SRC = $(EXTRA_SRC)
@echo FOR_UWP = $(FOR_UWP)
@echo FUZZCHECK_OPTS = $(FUZZCHECK_OPTS)
@echo FUZZCHECK_SRC = $(FUZZCHECK_SRC)
@echo FUZZDATA = $(FUZZDATA)
@echo FUZZERSHELL_COMPILE_OPTS = $(FUZZERSHELL_COMPILE_OPTS)
@echo HDR = $(HDR)
@echo ICUDIR = $(ICUDIR)
@echo ICUINCDIR = $(ICUINCDIR)
@echo ICULIBDIR = $(ICULIBDIR)
@echo JIM_TCLSH = $(JIM_TCLSH)
@echo KV_COMPILE_OPTS = $(KV_COMPILE_OPTS)
@echo LDFLAGS = $(LDFLAGS)
@echo LD = $(LD)
@echo LIBICU = $(LIBICU)
@echo LIBOBJ = $(LIBOBJ)
@echo LIBREADLINE = $(LIBREADLINE)
@echo LIBRESOBJS = $(LIBRESOBJS)
@echo LIBTCLPATH = $(LIBTCLPATH)
@echo LIBTCLSTUB = $(LIBTCLSTUB)
@echo LIBTCL = $(LIBTCL)
@echo LTCOMPILE = $(LTCOMPILE)
@echo LTLIB = $(LTLIB)
@echo LTLIBOPTS = $(LTLIBOPTS)
@echo LTLIBPATHS = $(LTLIBPATHS)
@echo LTLIBS = $(LTLIBS)
@echo LTLINK = $(LTLINK)
@echo LTLINKOPTS = $(LTLINKOPTS)
@echo LTRCOMPILE = $(LTRCOMPILE)
@echo MEMDEBUG = $(MEMDEBUG)
@echo MINIMAL_AMALGAMATION = $(MINIMAL_AMALGAMATION)
@echo MPTESTER_COMPILE_OPTS = $(MPTESTER_COMPILE_OPTS)
@echo NCC = $(NCC)
@echo NCRTLIBPATH = $(NCRTLIBPATH)
@echo NLTLIBPATHS = $(NLTLIBPATHS)
@echo NO_LINEMACROS = $(NO_LINEMACROS)
@echo NO_TCL = $(NO_TCL)
@echo NO_WARN = $(NO_WARN)
@echo NSDKLIBPATH = $(NSDKLIBPATH)
@echo NUCRTLIBPATH = $(NUCRTLIBPATH)
@echo OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS)
@echo OPTIMIZATIONS = $(OPTIMIZATIONS)
@echo OSSSHELL_SRC = $(OSSSHELL_SRC)
@echo OSTRACE = $(OSTRACE)
@echo RBU = $(RBU)
@echo RCC = $(RCC)
@echo RC = $(RC)
@echo READLINE_FLAGS = $(READLINE_FLAGS)
@echo REQ_FEATURE_FLAGS = $(REQ_FEATURE_FLAGS)
@echo RSYNC_OPT = $(RSYNC_OPT)
@echo RSYNC_SRC = $(RSYNC_SRC)
@echo SESSION = $(SESSION)
@echo SETLK_TIMEOUT = $(SETLK_TIMEOUT)
@echo SHELL_CCONV_OPTS = $(SHELL_CCONV_OPTS)
@echo SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS)
@echo SHELL_CORE_DEP = $(SHELL_CORE_DEP)
@echo SHELL_CORE_LIB = $(SHELL_CORE_LIB)
@echo SHELL_CORE_SRC = $(SHELL_CORE_SRC)
@echo SHELL_DEP = $(SHELL_DEP)
@echo SHELL_LINK_OPTS = $(SHELL_LINK_OPTS)
@echo SPLIT_AMALGAMATION = $(SPLIT_AMALGAMATION)
@echo SQLITETCLDECLSH = $(SQLITETCLDECLSH)
@echo SQLITE_TCL_DEP = $(SQLITE_TCL_DEP)
@echo SQLITETCLH = $(SQLITETCLH)
@echo SRC = $(SRC)
@echo STATICALLY_LINK_TCL = $(STATICALLY_LINK_TCL)
@echo ST_COMPILE_OPTS = $(ST_COMPILE_OPTS)
@echo STORELIBPATH = $(STORELIBPATH)
@echo SYMBOLS = $(SYMBOLS)
@echo TCC = $(TCC)
@echo TCLDIR = $(TCLDIR)
@echo TCLINCDIR = $(TCLINCDIR)
@echo TCLLIBDIR = $(TCLLIBDIR)
@echo TCLLIBPATHS = $(TCLLIBPATHS)
@echo TCLLIBS = $(TCLLIBS)
@echo TCLSH_CMD = $(TCLSH_CMD)
@echo TCLSQLITEEX = $(TCLSQLITEEX)
@echo TCLSUFFIX = $(TCLSUFFIX)
@echo TCLVERSION = $(TCLVERSION)
@echo TEST_CCONV_OPTS = $(TEST_CCONV_OPTS)
@echo TESTEXT = $(TESTEXT)
@echo TESTFIXTURE_DEP = $(TESTFIXTURE_DEP)
@echo TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS)
@echo TESTFIXTURE_SRC = $(TESTFIXTURE_SRC)
@echo TESTOPTS = $(TESTOPTS)
@echo TESTPROGS = $(TESTPROGS)
@echo TESTSRC = $(TESTSRC)
@echo TLIBS = $(TLIBS)
@echo TOP = $(TOP)
@echo UCRTLIBPATH = $(UCRTLIBPATH)
@echo USE_AMALGAMATION = $(USE_AMALGAMATION)
@echo USE_CRT_DLL = $(USE_CRT_DLL)
@echo USE_FATAL_WARN = $(USE_FATAL_WARN)
@echo USE_FULLWARN = $(USE_FULLWARN)
@echo USE_ICU = $(USE_ICU)
@echo USE_LISTINGS = $(USE_LISTINGS)
@echo USE_NATIVE_LIBPATHS = $(USE_NATIVE_LIBPATHS)
@echo USE_RC = $(USE_RC)
@echo USE_RUNTIME_CHECKS = $(USE_RUNTIME_CHECKS)
@echo USE_SEH = $(USE_SEH)
@echo USE_STDCALL = $(USE_STDCALL)
@echo USE_ZLIB = $(USE_ZLIB)
@echo XCOMPILE = $(XCOMPILE)
@echo ZLIBCFLAGS = $(ZLIBCFLAGS)
@echo ZLIBDIR = $(ZLIBDIR)
@echo ZLIBINCDIR = $(ZLIBINCDIR)
@echo ZLIBLIBDIR = $(ZLIBLIBDIR)
@echo ZLIBLIB = $(ZLIBLIB)
moreclean: clean
del /Q $(SQLITE3C) $(SQLITE3H) 2>NUL
# <</mark>>
@@ -2922,7 +2833,6 @@ clean:
del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe dbdump.exe 2>NUL
del /Q changeset.exe 2>NUL
del /Q showjournal.exe showstat4.exe showwal.exe speedtest1.exe 2>NUL
del /Q fp-speed-1.exe fp-speed-2.exe 2>NUL
del /Q mptester.exe wordcount.exe rbu.exe srcck1.exe 2>NUL
del /Q sqlite3.c sqlite3-*.c sqlite3.h 2>NUL
del /Q sqlite3rc.h 2>NUL
@@ -2937,5 +2847,4 @@ clean:
del /Q fts5.* fts5parse.* 2>NUL
del /q src-verify.exe 2>NUL
del /q jimsh.exe jimsh0.exe 2>NUL
-$(TCLSH_CMD) test/testrunner.tcl clean
# <</mark>>
+69 -64
View File
@@ -1,10 +1,9 @@
<h1 align="center">SQLite Source Repository</h1>
This repository contains the complete source code for the
[SQLite database engine](https://sqlite.org/) going back
to 2000-05-29. The tree includes many tests and some
documentation, though additional tests and most documentation
are managed separately.
[SQLite database engine](https://sqlite.org/), including
many test scripts. However, other test scripts
and most of the documentation are managed separately.
See the [on-line documentation](https://sqlite.org/) for more information
about what SQLite is and how it works from a user's perspective. This
@@ -54,34 +53,41 @@ then no longer be fully in the public domain.
## Obtaining The SQLite Source Code
Source code tarballs or ZIP archives are available at:
If you do not want to use Fossil, you can download tarballs or ZIP
archives or [SQLite archives](https://sqlite.org/cli.html#sqlar) as follows:
* [Latest trunk check-in](https://sqlite.org/src/rchvdwnld/trunk).
* Latest trunk check-in as
[Tarball](https://sqlite.org/src/tarball/sqlite.tar.gz),
[ZIP-archive](https://sqlite.org/src/zip/sqlite.zip), or
[SQLite-archive](https://sqlite.org/src/sqlar/sqlite.sqlar).
* [Latest release](https://sqlite.org/src/rchvdwnld/release)
* Latest release as
[Tarball](https://sqlite.org/src/tarball/sqlite.tar.gz?r=release),
[ZIP-archive](https://sqlite.org/src/zip/sqlite.zip?r=release), or
[SQLite-archive](https://sqlite.org/src/sqlar/sqlite.sqlar?r=release).
* For other check-ins, browse the
[project timeline](https://sqlite.org/src/timeline?y=ci) and
click on the check-in hash of the check-in you want to download.
On the resulting "info" page, click one of the options to the
right of the "**Downloads:**" label in the "**Overview**" section
near the top.
* For other check-ins, substitute an appropriate branch name or
tag or hash prefix in place of "release" in the URLs of the previous
bullet. Or browse the [timeline](https://sqlite.org/src/timeline)
to locate the check-in desired, click on its information page link,
then click on the "Tarball" or "ZIP Archive" links on the information
page.
To access sources directly using [Fossil](https://fossil-scm.org/home),
first install Fossil version 2.0 or later.
Source tarballs and precompiled binaries for Fossil are available at
Source tarballs and precompiled binaries available at
<https://fossil-scm.org/home/uv/download.html>. Fossil is
a stand-alone program. To install, simply download or build the single
executable file and put that file someplace on your $PATH or %PATH%.
executable file and put that file someplace on your $PATH.
Then run commands like this:
mkdir -p ~/sqlite
cd ~/sqlite
fossil open https://sqlite.org/src
The initial "fossil open" command will take two or three minutes. Afterwards,
you can do fast, bandwidth-efficient updates to whatever versions of SQLite you
like. Some examples:
The "fossil open" command will take two or three minutes. Afterwards,
you can do fast, bandwidth-efficient updates to the whatever versions
of SQLite you like. Some examples:
fossil update trunk ;# latest trunk check-in
fossil update release ;# latest official release
@@ -97,21 +103,19 @@ the build products. It is recommended, but not required, that the
build directory be separate from the source directory. Cd into the
build directory and then from the build directory run the configure
script found at the root of the source tree. Then run "make".
See the [compile-for-unix.md](doc/compile-for-unix.md) document for
more detail.
For example:
apt install gcc make tcl-dev ;# Install the necessary build tools
apt install gcc make tcl-dev ;# Make sure you have all the necessary build tools
tar xzf sqlite.tar.gz ;# Unpack the source tree into "sqlite"
mkdir bld ;# Build happens in a sibling directory
mkdir bld ;# Build will occur in a sibling directory
cd bld ;# Change to the build directory
../sqlite/configure ;# Run the configure script
make sqlite3 ;# The "sqlite3" command-line tool
make sqlite3.c ;# The "amalgamation" source file
make sqldiff ;# The "sqldiff" command-line tool
#### Targets below require tcl-dev ####
make tclextension-install ;# Install the SQLite TCL extension
make sqlite3 ;# Builds the "sqlite3" command-line tool
make sqlite3.c ;# Build the "amalgamation" source file
make sqldiff ;# Builds the "sqldiff" command-line tool
# Makefile targets below this point require tcl-dev
make tclextension-install ;# Build and install the SQLite TCL extension
make devtest ;# Run development tests
make releasetest ;# Run full release tests
make sqlite3_analyzer ;# Builds the "sqlite3_analyzer" tool
@@ -119,15 +123,14 @@ For example:
See the makefile for additional targets. For debugging builds, the
core developers typically run "configure" with options like this:
../sqlite/configure --all --debug CFLAGS='-O0 -g'
../sqlite/configure --enable-all --enable-debug CFLAGS='-O0 -g'
For release builds, the core developers usually do:
../sqlite/configure --all
../sqlite/configure --enable-all
Core deliverables (sqlite3.c, sqlite3) can be built without a TCL, but
many makefile targets require a "tclsh" TCL interpreter version 8.6
or later. The "tclextension-install" target and the test targets that follow
Almost all makefile targets require a "tclsh" TCL interpreter version 8.6 or
later. The "tclextension-install" target and the test targets that follow
all require TCL development libraries too. ("apt install tcl-dev"). It is
helpful, but is not required, to install the SQLite TCL extension (the
"tclextension-install" target) prior to running tests. The "releasetest"
@@ -137,20 +140,19 @@ On "make" command-lines, one can add "OPTIONS=..." to specify additional
compile-time options over and above those set by ./configure. For example,
to compile with the SQLITE_OMIT_DEPRECATED compile-time option, one could say:
./configure --all
./configure --enable-all
make OPTIONS=-DSQLITE_OMIT_DEPRECATED sqlite3
The configure script uses [autosetup](https://msteveb.github.io/autosetup/).
If the configure script does not work out for you, there is a generic
makefile named "Makefile.linux-gcc" in the top directory of the source tree
that you can copy and edit to suit your needs. Comments on the generic
makefile show what changes are needed.
The configure script uses autoconf 2.61 and libtool. If the configure
script does not work out for you, there is a generic makefile named
"Makefile.linux-gcc" in the top directory of the source tree that you
can copy and edit to suit your needs. Comments on the generic makefile
show what changes are needed.
## Compiling for Windows Using MSVC
On Windows, everything can be compiled with MSVC.
You will also need a working installation of TCL if you want to run tests,
though TCL is not required if you just want to build SQLite itself.
You will also need a working installation of TCL.
See the [compile-for-windows.md](doc/compile-for-windows.md) document for
additional information about how to install MSVC and TCL and configure your
build environment.
@@ -160,25 +162,24 @@ TCL library, using a command like this:
set TCLDIR=c:\Tcl
SQLite itself does not contain any TCL code, but it does use TCL to run
tests. You may need to install TCL development libraries in order to
successfully complete some makefile targets. It is helpful, but is not
required, to install the SQLite TCL extension (the "tclextension-install"
target) prior to running tests.
SQLite uses "tclsh.exe" as part of the build process, and so that
program will need to be somewhere on your %PATH%. SQLite itself
does not contain any TCL code, but it does use TCL to help with the
build process and to run tests. You may need to install TCL development
libraries in order to successfully complete some makefile targets.
It is helpful, but is not required, to install the SQLite TCL extension
(the "tclextension-install" target) prior to running tests.
The source tree contains a "make.bat" file that allows the same "make"
commands of Unix to work on Windows. In the following, you can substitute
"nmake /f Makefile.msc" in place of "make", if you prefer to avoid this BAT
file:
Build using Makefile.msc. Example:
make sqlite3.exe
make sqlite3.c
make sqldiff.exe
#### Targets below require TCL development libraries ####
make tclextension-install
make devtest
make releasetest
make sqlite3_analyzer.exe
nmake /f Makefile.msc sqlite3.exe
nmake /f Makefile.msc sqlite3.c
nmake /f Makefile.msc sqldiff.exe
# Makefile targets below this point require TCL development libraries
nmake /f Makefile.msc tclextension-install
nmake /f Makefile.msc devtest
nmake /f Makefile.msc releasetest
nmake /f Makefile.msc sqlite3_analyzer.exe
There are many other makefile targets. See comments in Makefile.msc for
details.
@@ -186,7 +187,7 @@ details.
As with the unix Makefile, the OPTIONS=... argument can be passed on the nmake
command-line to enable new compile-time options. For example:
make OPTIONS=-DSQLITE_OMIT_DEPRECATED sqlite3.exe
nmake /f Makefile.msc OPTIONS=-DSQLITE_OMIT_DEPRECATED sqlite3.exe
## Source Tree Map
@@ -199,7 +200,8 @@ command-line to enable new compile-time options. For example:
* **test/** - This directory and its subdirectories contains code used
for testing. Files that end in "`.test`" are TCL scripts that run
tests using an augmented TCL interpreter named "testfixture". Use
a command like "`make testfixture`" to build that
a command like "`make testfixture`" (unix) or
"`nmake /f Makefile.msc testfixture.exe`" (windows) to build that
augmented TCL interpreter, then run individual tests using commands like
"`testfixture test/main.test`". This test/ subdirectory also contains
additional C code modules and scripts for other kinds of testing.
@@ -381,11 +383,10 @@ implementation. It will not be the easiest library in the world to hack.
(and some other test programs too) is built and run when you type
"make test".
* **VERSION**, **manifest**, **manifest.tags**, and **manifest.uuid** -
These files define the current SQLite version number. The "VERSION" file
is human generated, but the "manifest", "manifest.tags", and
"manifest.uuid" files are automatically generated by the
[Fossil version control system](https://fossil-scm.org/).
* **VERSION**, **manifest**, and **manifest.uuid** - These files define
the current SQLite version number. The "VERSION" file is human generated,
but the "manifest" and "manifest.uuid" files are automatically generated
by the [Fossil version control system](https://fossil-scm.org/).
There are many other source files. Each has a succinct header comment that
describes its purpose and role within the larger system.
@@ -411,6 +412,10 @@ makefile:
> make verify-source
Or on windows:
> nmake /f Makefile.msc verify-source
Using the makefile to verify source integrity is good for detecting
accidental changes to the source tree, but malicious changes could be
hidden by also modifying the makefiles.
+1 -1
View File
@@ -1 +1 @@
3.54.0
3.51.0
+4 -7
View File
@@ -222,12 +222,9 @@ install: install-lib
# Flags to link the shell app either directly against sqlite3.c
# (ENABLE_STATIC_SHELL==1) or libsqlite3.so (ENABLE_STATIC_SHELL==0).
#
# Maintenance reminder: placement of $(LDFLAGS) is more relevant for
# some platforms than others:
# https://sqlite.org/forum/forumpost/d80ecdaddd
ENABLE_STATIC_SHELL = @ENABLE_STATIC_SHELL@
sqlite3-shell-link-flags.1 = $(TOP)/sqlite3.c $(LDFLAGS) $(LDFLAGS.libsqlite3)
sqlite3-shell-link-flags.0 = $(LDFLAGS) -L. -lsqlite3 $(LDFLAGS.zlib) $(LDFLAGS.math)
sqlite3-shell-link-flags.1 = $(TOP)/sqlite3.c $(LDFLAGS.libsqlite3)
sqlite3-shell-link-flags.0 = -L. -lsqlite3 $(LDFLAGS.zlib) $(LDFLAGS.math)
sqlite3-shell-deps.1 = $(TOP)/sqlite3.c
sqlite3-shell-deps.0 = $(libsqlite3.DLL)
#
@@ -248,7 +245,7 @@ sqlite3$(T.exe): $(TOP)/shell.c $(sqlite3-shell-deps.$(ENABLE_STATIC_SHELL))
$(sqlite3-shell-static.flags.$(STATIC_CLI_SHELL)) \
-I. $(OPT_FEATURE_FLAGS) $(SHELL_OPT) \
$(CFLAGS) $(CFLAGS.readline) $(CFLAGS.icu) \
$(LDFLAGS.readline)
$(LDFLAGS) $(LDFLAGS.readline)
sqlite3$(T.exe)-1:
sqlite3$(T.exe)-0: sqlite3$(T.exe)
@@ -282,7 +279,7 @@ DIST_FILES := \
README.txt VERSION \
auto.def autosetup configure tea \
sqlite3.h sqlite3.c shell.c sqlite3ext.h \
Makefile.in Makefile.msc Makefile.fallback make.bat \
Makefile.in Makefile.msc Makefile.fallback \
sqlite3.rc sqlite3rc.h Replace.cs \
sqlite3.pc.in sqlite3.1
+90 -17
View File
@@ -101,6 +101,13 @@ NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4244 -wd4305 -wd4306 -wd4702 -wd4706
!ENDIF
!ENDIF
# Set this non-0 to use the library paths and other options necessary for
# Windows Phone 8.1.
#
!IFNDEF USE_WP81_OPTS
USE_WP81_OPTS = 0
!ENDIF
# Set this non-0 to split the SQLite amalgamation file into chunks to
# be used for debugging with Visual Studio.
#
@@ -149,6 +156,14 @@ USE_NATIVE_LIBPATHS = 0
USE_RC = 1
!ENDIF
# Set this non-0 to compile binaries suitable for the WinRT environment.
# This setting does not apply to any binaries that require Tcl to operate
# properly (i.e. the text fixture, etc).
#
!IFNDEF FOR_WINRT
FOR_WINRT = 0
!ENDIF
# Set this non-0 to compile binaries suitable for the UWP environment.
# This setting does not apply to any binaries that require Tcl to operate
# properly (i.e. the text fixture, etc).
@@ -312,7 +327,6 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_CARRAY=1
!ENDIF
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
!ENDIF
@@ -335,7 +349,6 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK=1
# Always enable math functions on Windows
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_MATH_FUNCTIONS
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PERCENTILE
# Should the rbu extension be enabled? If so, add compilation options
# to enable it.
@@ -548,14 +561,10 @@ RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) $(RCOPTS) $(RCCOPTS)
!IF "$(PLATFORM)"=="x86"
CORE_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
SHELL_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
!ELSE
!IFNDEF PLATFORM
CORE_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
SHELL_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
!ELSE
CORE_CCONV_OPTS =
SHELL_CCONV_OPTS =
@@ -656,6 +665,18 @@ SHELL_LINK_OPTS = $(SHELL_CORE_LIB)
TCC = $(TCC) -FAcs
!ENDIF
# When compiling the library for use in the WinRT environment,
# the following compile-time options must be used as well to
# disable use of Win32 APIs that are not available and to enable
# use of Win32 APIs that are specific to Windows 8 and/or WinRT.
#
!IF $(FOR_WINRT)!=0
TCC = $(TCC) -DSQLITE_OS_WINRT=1
RCC = $(RCC) -DSQLITE_OS_WINRT=1
TCC = $(TCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
RCC = $(RCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
!ENDIF
# C compiler options for the Windows 10 platform (needs MSVC 2015).
#
!IF $(FOR_WIN10)!=0
@@ -668,29 +689,35 @@ BCC = $(BCC) /d2guard4 -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
# USE_CRT_DLL option is set to force dynamically linking to the
# MSVC runtime library.
#
!IF $(USE_CRT_DLL)!=0
!IF $(FOR_WINRT)!=0 || $(USE_CRT_DLL)!=0
!IF $(DEBUG)>1
TCC = $(TCC) -MDd
BCC = $(BCC) -MDd
ZLIBCFLAGS = -nologo -MDd -W3 -O2 -Oy- -Zi
!ELSE
TCC = $(TCC) -MD
BCC = $(BCC) -MD
ZLIBCFLAGS = -nologo -MD -W3 -O2 -Oy- -Zi
!ENDIF
!ELSE
!IF $(DEBUG)>1
TCC = $(TCC) -MTd
BCC = $(BCC) -MTd
ZLIBCFLAGS = -nologo -MTd -W3 -O2 -Oy- -Zi
!ELSE
TCC = $(TCC) -MT
BCC = $(BCC) -MT
ZLIBCFLAGS = -nologo -MT -W3 -O2 -Oy- -Zi
!ENDIF
!ENDIF
# Define -DNDEBUG to compile without debugging (i.e., for production usage)
# Omitting the define will cause extra debugging code to be inserted and
# includes extra comments when "EXPLAIN stmt" is used.
#
!IF $(DEBUG)==0
TCC = $(TCC) -DNDEBUG
BCC = $(BCC) -DNDEBUG
RCC = $(RCC) -DNDEBUG
!ENDIF
!IF $(DEBUG)>0 || $(API_ARMOR)!=0 || $(FOR_WIN10)!=0
TCC = $(TCC) -DSQLITE_ENABLE_API_ARMOR=1
RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR=1
@@ -880,6 +907,56 @@ LTLINKOPTS = /NOLOGO
LTLIBOPTS = /NOLOGO
!ENDIF
# When compiling for use in the WinRT environment, the following
# linker option must be used to mark the executable as runnable
# only in the context of an application container.
#
!IF $(FOR_WINRT)!=0
LTLINKOPTS = $(LTLINKOPTS) /APPCONTAINER
!IF "$(VISUALSTUDIOVERSION)"=="12.0" || "$(VISUALSTUDIOVERSION)"=="14.0"
!IFNDEF STORELIBPATH
!IF "$(PLATFORM)"=="x86"
STORELIBPATH = $(CRTLIBPATH)\store
!ELSEIF "$(PLATFORM)"=="x64"
STORELIBPATH = $(CRTLIBPATH)\store\amd64
!ELSEIF "$(PLATFORM)"=="ARM"
STORELIBPATH = $(CRTLIBPATH)\store\arm
!ELSE
STORELIBPATH = $(CRTLIBPATH)\store
!ENDIF
!ENDIF
STORELIBPATH = $(STORELIBPATH:\\=\)
LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(STORELIBPATH)"
!ENDIF
!ENDIF
# When compiling for Windows Phone 8.1, an extra library path is
# required.
#
!IF $(USE_WP81_OPTS)!=0
!IFNDEF WP81LIBPATH
!IF "$(PLATFORM)"=="x86"
WP81LIBPATH = $(PROGRAMFILES_X86)\Windows Phone Kits\8.1\lib\x86
!ELSEIF "$(PLATFORM)"=="ARM"
WP81LIBPATH = $(PROGRAMFILES_X86)\Windows Phone Kits\8.1\lib\ARM
!ELSE
WP81LIBPATH = $(PROGRAMFILES_X86)\Windows Phone Kits\8.1\lib\x86
!ENDIF
!ENDIF
!ENDIF
# When compiling for Windows Phone 8.1, some extra linker options
# are also required.
#
!IF $(USE_WP81_OPTS)!=0
!IFDEF WP81LIBPATH
LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(WP81LIBPATH)"
!ENDIF
LTLINKOPTS = $(LTLINKOPTS) /DYNAMICBASE
LTLINKOPTS = $(LTLINKOPTS) WindowsPhoneCore.lib RuntimeObject.lib PhoneAppModelHost.lib
LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:kernel32.lib /NODEFAULTLIB:ole32.lib
!ENDIF
# When compiling for UWP or the Windows 10 platform, some extra linker
# options are also required.
#
@@ -903,9 +980,9 @@ LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib
# If either debugging or symbols are enabled, enable PDBs.
#
!IF $(DEBUG)>1 || $(SYMBOLS)!=0
LDFLAGS = /NODEFAULTLIB:msvcrt /DEBUG $(LDOPTS)
LDFLAGS = /DEBUG $(LDOPTS)
!ELSE
LDFLAGS = /NODEFAULTLIB:msvcrt $(LDOPTS)
LDFLAGS = $(LDOPTS)
!ENDIF
@@ -938,10 +1015,8 @@ SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_DQS=0
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS4=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_PERCENTILE=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_STMT_SCANSTATUS=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_STRICT_SUBTYPE=1
!ENDIF
@@ -990,8 +1065,6 @@ $(SQLITE3EXE): shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLIT
/link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
tclsqlite-ex.c:
# Rule to build the amalgamation
#
sqlite3.lo: $(SQLITE3C)
+2 -3
View File
@@ -119,7 +119,7 @@ TCLLIBDIR = @TCLLIBDIR@
# typically come from the ./configure command-line invocation).
#
CFLAGS.configure = @SH_CFLAGS@ @TEAISH_CFLAGS@ @CFLAGS@ @CPPFLAGS@ $(TCL_INCLUDE_SPEC)
CFLAGS.configure += -DUSE_TCL_STUBS=@TEAISH_USE_STUBS@
#CFLAGS.configure += -DUSE_TCL_STUBS=1
#
# LDFLAGS.configure = LDFLAGS as known at configure-time.
@@ -153,7 +153,6 @@ tx.src = @TEAISH_EXT_SRC@
# gets set up via the configure script.
#
tx.CFLAGS =
tx.CPPFLAGS =
#
# tx.LDFLAGS is typically set by teaish.make, whereas TEAISH_LDFLAGS
@@ -219,7 +218,7 @@ config.log: @TEAISH_TEST_TCL_IN@
# CC variant for compiling Tcl-using sources.
#
CC.tcl = \
$(CC) -o $@ $(CFLAGS.configure) $(CFLAGS) $(tx.CFLAGS) $(tx.CPPFLAGS)
$(CC) -o $@ $(CFLAGS.configure) $(CFLAGS) $(tx.CFLAGS)
#
# CC variant for linking $(tx.src) into an extension DLL. Note that
+1 -11
View File
@@ -375,11 +375,6 @@ configure process, and check it in.
Patching Autosetup for Project-local Changes
------------------------------------------------------------------------
The autosetup files require the following patches after updating
from their upstream sources:
### `--debug` flag
Autosetup reserves the flag name **`--debug`** for its own purposes,
and its own special handling of `--enable-...` flags makes `--debug`
an alias for `--enable-debug`. As this project has a long history of
@@ -393,11 +388,6 @@ If autosetup is upgraded and this patch is _not_ applied the invoking
`./configure` will fail loudly because of the declaration of the
`debug` flag in `auto.def` - duplicated flags are not permitted.
### Fail on `malloc()` error
See [check-in 72c8a5b94cdf5d](/info/72c8a5b94cdf5d).
<a name="branch-customization"></a>
Branch-specific Customization
========================================================================
@@ -461,4 +451,4 @@ all other significant processing.
[sqlite-config.tcl]: /file/autosetup/sqlite-config.tcl
[Makefile.in]: /file/Makefile.in
[main.mk]: /file/main.mk
[JimTCL]: https://msteveb.github.io/jimtcl/
[JimTCL]: https://jim.tcl.tk
+7 -11
View File
@@ -406,8 +406,8 @@ proc options-add {opts} {
# Find the corresponding value in the user options
# and set the default if necessary
if {[string match "-*" $opt]} {
# We no longer support documentation-only options, like "-C <dir>"
autosetup-error "Option $opt is not supported"
# This is a documentation-only option, like "-C <dir>"
set opthelp $opt
} elseif {$colon eq ""} {
# Boolean option
lappend autosetup(options) $name
@@ -1611,7 +1611,7 @@ proc autosetup_output_block {type lines} {
# Generate a command reference from inline documentation
proc automf_command_reference {} {
lappend files $::autosetup(prog)
lappend files {*}[lsort [glob -nocomplain $::autosetup(libdir)/{*/*.tcl,*.tcl}]]
lappend files {*}[lsort [glob -nocomplain $::autosetup(libdir)/*.tcl]]
# We want to process all non-module files before module files
# and then modules in alphabetical order.
@@ -2124,7 +2124,7 @@ if {$autosetup(istcl)} {
set frame [info frame -$i]
if {[dict exists $frame file]} {
# We don't need proc, so use ""
lappend stacktrace "" [dict get $frame file] [dict get $frame line] ""
lappend stacktrace "" [dict get $frame file] [dict get $frame line]
}
}
return $stacktrace
@@ -2181,12 +2181,8 @@ proc error-location {msg} {
if {$::autosetup(debug)} {
return -code error $msg
}
set vars {p f l cmd}
if {!$::autosetup(istcl) && ![dict exists $::tcl_platform stackFormat]} {
# Older versions of Jim had a 3 element stacktrace
set vars {p f l}
}
foreach $vars [stacktrace] {
# Search back through the stack trace for the first error in a .def file
foreach {p f l} [stacktrace] {
if {[string match *.def $f]} {
return "[relative-path $f]:$l: Error: $msg"
}
@@ -2538,7 +2534,7 @@ if {[catch {main $argv} msg opts] == 1} {
show-notices
autosetup-full-error [error-dump $msg $opts $autosetup(debug)]
if {!$autosetup(debug)} {
puts stderr "Try: '[file tail $autosetup(exe)] --debug' for a full stack trace"
puts stderr "Try: '[file tail $autosetup(exe)] --autosetup-debug' for a full stack trace"
}
exit 1
}
+4 -6
View File
@@ -89,15 +89,13 @@ switch -glob -- [get-define host] {
define SH_SOPREFIX -Wl,-h,
}
}
*-*-hpux* {
define SHOBJ_CFLAGS +z
*-*-hpux {
# XXX: These haven't been tested
define SHOBJ_CFLAGS "+O3 +z"
define SHOBJ_LDFLAGS -b
define SH_CFLAGS +z
define SH_LDFLAGS -b
define SH_LINKFLAGS -Wl,+s
define SH_LINKRPATH "-Wl,+b -Wl,%s"
define SH_SOPREFIX -Wl,+h,
define STRIPLIBFLAGS -Wl,-s
define LD_LIBRARY_PATH SHLIB_PATH
}
*-*-haiku {
define SHOBJ_CFLAGS ""
+948 -1622
View File
File diff suppressed because it is too large Load Diff
+13 -56
View File
@@ -557,7 +557,7 @@ proc proj-opt-define-bool {args} {
if {$invert} {
set rc [expr {!$rc}]
}
msg-result [string map {0 no 1 yes} $rc]
msg-result $rc
define $defName $rc
return $rc
}
@@ -706,20 +706,11 @@ proc proj-file-write {args} {
}
#
# @proj-check-compile-commands ?-assume-for-clang? ?configFlag?
# @proj-check-compile-commands ?configFlag?
#
# Checks the compiler for compile_commands.json support. If
# $configFlag is not empty then it is assumed to be the name of an
# autosetup boolean config which controls whether to run/skip this
# check.
#
# If -assume-for-clang is provided and $configFlag is not empty and CC
# matches *clang* and no --$configFlag was explicitly provided to the
# configure script then behave as if --$configFlag had been provided.
# To disable that assumption, either don't pass -assume-for-clang or
# pass --$configFlag=0 to the configure script. (The reason for this
# behavior is that clang supports compile-commands but some other
# compilers report false positives with these tests.)
# Checks the compiler for compile_commands.json support. If passed an
# argument it is assumed to be the name of an autosetup boolean config
# which controls whether to run/skip this check.
#
# Returns 1 if supported, else 0, and defines HAVE_COMPILE_COMMANDS to
# that value. Defines MAKE_COMPILATION_DB to "yes" if supported, "no"
@@ -727,38 +718,12 @@ proc proj-file-write {args} {
# HAVE_COMPILE_COMMANDS is preferred.
#
# ACHTUNG: this test has a long history of false positive results
# because of compilers reacting differently to the -MJ flag. Because
# of this, it is recommended that this support be an opt-in feature,
# rather than an on-by-default default one. That is: in the
# configure script define the option as
# {--the-flag-name=0 => {Enable ....}}
# because of compilers reacting differently to the -MJ flag.
#
proc proj-check-compile-commands {args} {
set i 0
set configFlag {}
set fAssumeForClang 0
set doAssume 0
proc proj-check-compile-commands {{configFlag {}}} {
msg-checking "compile_commands.json support... "
if {"-assume-for-clang" eq [lindex $args 0]} {
lassign $args - configFlag
incr fAssumeForClang
} elseif {1 == [llength $args]} {
lassign $args configFlag
} else {
proj-error "Invalid arguments"
}
if {1 == $fAssumeForClang && "" ne $configFlag} {
if {[string match *clang* [get-define CC]]
&& ![proj-opt-was-provided $configFlag]
&& ![proj-opt-truthy $configFlag]} {
proj-indented-notice [subst -nocommands -nobackslashes {
CC appears to be clang, so assuming that --$configFlag is likely
to work. To disable this assumption use --$configFlag=0.}]
incr doAssume
}
}
if {!$doAssume && "" ne $configFlag && ![proj-opt-truthy $configFlag]} {
msg-result "check disabled. Use --${configFlag} to enable it."
if {"" ne $configFlag && ![proj-opt-truthy $configFlag]} {
msg-result "explicitly disabled"
define HAVE_COMPILE_COMMANDS 0
define MAKE_COMPILATION_DB no
return 0
@@ -767,7 +732,7 @@ proc proj-check-compile-commands {args} {
# This test reportedly incorrectly succeeds on one of
# Martin G.'s older systems. drh also reports a false
# positive on an unspecified older Mac system.
msg-result "compiler supports -MJ. Assuming it's useful for compile_commands.json"
msg-result "compiler supports compile_commands.json"
define MAKE_COMPILATION_DB yes; # deprecated
define HAVE_COMPILE_COMMANDS 1
return 1
@@ -1170,10 +1135,6 @@ proc proj-check-rpath {} {
if {"" eq $wl} {
set wl [proj-cc-check-Wl-flag -R$lp]
}
if {"" eq $wl} {
# HP-UX: https://sqlite.org/forum/forumpost/d80ecdaddd
set wl [proj-cc-check-Wl-flag +b $lp]
}
define LDFLAGS_RPATH $wl
}
}
@@ -1183,7 +1144,7 @@ proc proj-check-rpath {} {
#
# @proj-check-soname ?libname?
#
# Checks whether CC supports the -Wl,-soname,lib... flag. If so, it
# Checks whether CC supports the -Wl,soname,lib... flag. If so, it
# returns 1 and defines LDFLAGS_SONAME_PREFIX to the flag's prefix, to
# which the client would need to append "libwhatever.N". If not, it
# returns 0 and defines LDFLAGS_SONAME_PREFIX to an empty string.
@@ -1199,10 +1160,6 @@ proc proj-check-soname {{libname "libfoo.so.0"}} {
if {[cc-check-flags "-Wl,-soname,${libname}"]} {
define LDFLAGS_SONAME_PREFIX "-Wl,-soname,"
return 1
} elseif {[cc-check-flags "-Wl,+h,${libname}"]} {
# HP-UX: https://sqlite.org/forum/forumpost/d80ecdaddd
define LDFLAGS_SONAME_PREFIX "-Wl,+h,"
return 1
} else {
define LDFLAGS_SONAME_PREFIX ""
return 0
@@ -1842,7 +1799,7 @@ proc proj-setup-autoreconfig {defName} {
}
#
# @prop-define-append defineName args...
# @prop-append-to defineName args...
#
# A proxy for Autosetup's [define-append]. Appends all non-empty $args
# to [define-append $defineName].
@@ -1873,7 +1830,7 @@ proc proj-define-append {defineName args} {
# but it is technically correct and still relevant on some
# environments.
#
# See: proj-define-append
# See: proj-append-to
#
proc proj-define-amend {args} {
set defName ""
+9 -71
View File
@@ -65,7 +65,7 @@ array set sqliteConfig [subst [proj-strip-hash-comments {
# The list of feature --flags which the --all flag implies. This
# requires special handling in a few places.
#
all-flag-enables {fts4 fts5 rtree geopoly session dbpage dbstat carray}
all-flag-enables {fts4 fts5 rtree geopoly session}
#
# Default value for the --all flag. Can hypothetically be modified
@@ -220,9 +220,6 @@ proc sqlite-configure {buildMode configScript} {
geopoly => {Enable the GEOPOLY extension}
rtree => {Enable the RTREE extension}
session => {Enable the SESSION extension}
dbpage => {Enable the sqlite3_dbpage extension}
dbstat => {Enable the sqlite3_dbstat extension}
carray=1 => {Disable the CARRAY extension}
all=$::sqliteConfig(all-flag-default) => {$allFlagHelp}
largefile=1
=> {This legacy flag has no effect on the library but may influence
@@ -504,7 +501,6 @@ proc sqlite-configure-phase1 {buildMode} {
if {[file exists $srcdir/sqlite3.pc.in]} {
proj-dot-ins-append $srcdir/sqlite3.pc.in
}
sqlite-handle-hpux; # must be relatively early so that other config tests can work
}; # sqlite-configure-phase1
########################################################################
@@ -557,25 +553,7 @@ proc proc-debug {msg} {
}
define OPT_FEATURE_FLAGS {} ; # -DSQLITE_OMIT/ENABLE flags.
#
# OPT_SHELL = feature-related CFLAGS for the sqlite3 CLI app. The
# list's initial values are defaults which are always applied and not
# affected by --feature-flags. The list is appended to by various
# --feature-flags.
define OPT_SHELL {
-DSQLITE_DQS=0
-DSQLITE_ENABLE_FTS4
-DSQLITE_ENABLE_RTREE
-DSQLITE_ENABLE_EXPLAIN_COMMENTS
-DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
-DSQLITE_ENABLE_STMTVTAB
-DSQLITE_ENABLE_DBPAGE_VTAB
-DSQLITE_ENABLE_DBSTAT_VTAB
-DSQLITE_ENABLE_BYTECODE_VTAB
-DSQLITE_ENABLE_OFFSET_SQL_FUNC
-DSQLITE_ENABLE_PERCENTILE
-DSQLITE_STRICT_SUBTYPE=1
}
define OPT_SHELL {} ; # Feature-related CFLAGS for the sqlite3 CLI app
########################################################################
# Adds $args, if not empty, to OPT_FEATURE_FLAGS. If the first arg is
# -shell then it strips that arg and passes the remaining args the
@@ -649,7 +627,7 @@ proc sqlite-check-common-system-deps {} {
# Check for needed/wanted functions
cc-check-functions gmtime_r isnan localtime_r localtime_s \
usleep utime pread pread64 pwrite pwrite64
strchrnul usleep utime pread pread64 pwrite pwrite64
apply {{} {
set ldrt ""
@@ -679,7 +657,6 @@ proc sqlite-check-common-system-deps {} {
define HAVE_ZLIB 1
define LDFLAGS_ZLIB -lz
sqlite-add-shell-opt -DSQLITE_HAVE_ZLIB=1
sqlite-add-feature-flag -DSQLITE_HAVE_ZLIB=1
} else {
define HAVE_ZLIB 0
define LDFLAGS_ZLIB ""
@@ -743,11 +720,12 @@ proc sqlite-setup-default-cflags {} {
# compiling binaries for the target system (CC a.k.a. $(T.cc)).
# Normally they're the same, but they will differ when
# cross-compiling.
#
# When cross-compiling we default to not using the -g flag, based on a
# /chat discussion prompted by
# https://sqlite.org/forum/forumpost/9a67df63eda9925c
set defaultCFlags {-O2}
if {!$::sqliteConfig(is-cross-compiling)} {
# When cross-compiling we default to not using the -g flag, based
# on a /chat discussion prompted by
# https://sqlite.org/forum/forumpost/9a67df63eda9925c
lappend defaultCFlags -g
}
define CFLAGS [proj-get-env CFLAGS $defaultCFlags]
@@ -805,12 +783,8 @@ proc sqlite-handle-common-feature-flags {} {
sqlite-add-feature-flag -DSQLITE_ENABLE_MEMSYS3
}
}
bytecode-vtab -DSQLITE_ENABLE_BYTECODE_VTAB {}
scanstatus {-DSQLITE_ENABLE_STMT_SCANSTATUS -DSQLITE_ENABLE_BYTECODE_VTAB} {}
scanstatus -DSQLITE_ENABLE_STMT_SCANSTATUS {}
column-metadata -DSQLITE_ENABLE_COLUMN_METADATA {}
dbpage -DSQLITE_ENABLE_DBPAGE_VTAB {}
dbstat -DSQLITE_ENABLE_DBSTAT_VTAB {}
carray -DSQLITE_ENABLE_CARRAY {}
}] {
if {$boolFlag ni $::autosetup(options)} {
# Skip flags which are in the canonical build but not
@@ -1137,27 +1111,6 @@ proc sqlite-check-line-editing {} {
set editLibName "readline" ; # "readline" or "editline"
set editLibDef "HAVE_READLINE" ; # "HAVE_READLINE" or "HAVE_EDITLINE"
set dirLn [opt-val with-linenoise]
# If none of --with-linenoise, --enable-readline, or --enable-editline
# are provided, but there exists a directory "linenoise" at $HOME or
# a sibling of the build or source directory, then try to use that linenoise
# direcctory.
#
if {"" eq $dirLn
&& ![proj-opt-was-provided readline]
&& ![proj-opt-was-provided editline]
} {
set dirlist ../linenoise
catch {lappend dirlist [file-normalize $::autosetup(srcdir)/../linenoise]}
catch {lappend dirlist $::env(HOME)/linenoise}
foreach d $dirlist {
if {[file exists $d/linenoise.c] && [file exists $d/linenoise.h]} {
set dirLn $d
break
}
}
}
if {"" ne $dirLn} {
# Use linenoise from a copy of its sources (not a library)...
if {![file isdir $dirLn]} {
@@ -1193,8 +1146,6 @@ proc sqlite-check-line-editing {} {
if {$::sqliteConfig(use-jim-for-codegen) && 2 == $lnVal} {
define-append CFLAGS_JIMSH -DUSE_LINENOISE [get-define CFLAGS_READLINE]
user-notice "Adding linenoise support to jimsh."
} else {
msg-result "Using linenoise at [file-normalize $dirLn]"
}
return "linenoise ($flavor)"
} elseif {[opt-bool editline]} {
@@ -1532,7 +1483,7 @@ proc sqlite-handle-math {} {
}
define LDFLAGS_MATH [get-define lib_ceil]
undefine lib_ceil
sqlite-add-feature-flag -DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_ENABLE_PERCENTILE
sqlite-add-feature-flag -DSQLITE_ENABLE_MATH_FUNCTIONS
msg-result "Enabling math SQL functions"
} {
define LDFLAGS_MATH ""
@@ -1594,19 +1545,6 @@ proc sqlite-handle-mac-install-name {} {
return $rc
}
#
# Checks specific to HP-UX.
#
proc sqlite-handle-hpux {} {
switch -glob -- [get-define host] {
*hpux* {
if {[cc-check-flags "-Ae"]} {
define-append CFLAGS -Ae
}
}
}
}
########################################################################
# Handles the --dll-basename configure flag. [define]'s
# SQLITE_DLL_BASENAME to the DLL's preferred base name (minus
+1 -5
View File
@@ -220,9 +220,7 @@ proc teaish-configure-core {} {
=> {Full pathname of tclsh to use. It is used for trying to find
tclConfig.sh. Warning: if its containing dir has multiple tclsh
versions, it may select the wrong tclConfig.sh!
Defaults to the $TCLSH environment variable.}
tcl-stubs=0 => {Enable use of Tcl stubs library.}
Defaults to the $TCLSH environment variable.}
# TEA has --with-tclinclude but it appears to only be useful for
# building an extension against an uninstalled copy of TCL's own
@@ -500,8 +498,6 @@ proc teaish__configure_phase1 {} {
}
teaish-checks-run -post
define TEAISH_USE_STUBS [opt-bool tcl-stubs]
apply {{} {
# Set up "vsatisfies" code for pkgIndex.tcl.in,
# _teaish.tester.tcl.in, and for a configure-time check. We would
+7 -33
View File
@@ -22,10 +22,9 @@ guidance on building for Windows.
or <https://sqlite.org/tmp/tcl9.0.0.tar.gz>.
<li>Untar the source archive. CD into the "unix/" subfolder
of the source tree.
<li>Run: &ensp; `mkdir $HOME/local`
<li>Run: &ensp; `./configure --prefix=$HOME/local`<br>
SQLite deliverable builds add: &emsp; `--static CFLAGS=-Os`
<li>Run: &ensp; `make install`
<li>Run: `mkdir $HOME/local`
<li>Run: `./configure --prefix=$HOME/local`
<li>Run: `make install`
</ol>
<p>
As of 2024-10-25, TCL is not longer required for many
@@ -37,35 +36,12 @@ guidance on building for Windows.
4. Download the SQLite source tree and unpack it. CD into the
toplevel directory of the source tree.
5. *(Optional):* Download Antirez's "linenoise" command-line editing
library to provide command-line editing in the CLI. You can find
a suitable copy of the linenoise sources at
<https://sqlite.org/linenoise.tar.gz> or at various other locations
on the internet. If you put the linenoise source tree in
a directory named $HOME/linenoise or a directory "linenoise" which
is a sibling of the SQLite source tree, then the SQLite ./configure
script will automatically find and use that source code to provide
command-line editing in the CLI. If you would rather use the readline
or editline libraries or a precompiled linenoise library, there are
./configure options to accommodate that choice. The SQLite developers
typically use $HOME/linenoise since linenoise is small, has no
external dependencies, "just works", and the ./configure script
will pick it up and use it automatically. But you do what works
best for you.
<p>
You are not required to have any command-line editing support in
order to use SQLite. But command-line editing does make the
interactive experience more enjoyable.
6. Run: `./configure --enable-all --with-tclsh=$HOME/local/bin/tclsh9.0`
5. Run: `./configure --enable-all --with-tclsh=$HOME/local/bin/tclsh9.0`
You do not need to use --with-tclsh if the tclsh you want to use is the
first one on your PATH or if you are building without TCL.
Lots of other options to ./configure are available.
Run `./configure --help` for further guidance.
7. Run the "`Makefile`" makefile with an appropriate target.
6. Run the "`Makefile`" makefile with an appropriate target.
Examples:
<ul>
<li> `make sqlite3.c`
@@ -90,7 +66,5 @@ guidance on building for Windows.
of SQLite.
8. For a debugging build of the CLI, use `./configure --dev`. A debugging
build contains lots of extra debugging code, so it is slow and a lot
bigger. You probably do not want to deploy a debugging build. But if
you are working on the code, a debugging build works much better.
7. For a debugging build of the CLI, where the ".treetrace" and ".wheretrace"
commands work, add the the --with-debug argument to configure.
+17 -44
View File
@@ -1,7 +1,7 @@
# Notes On Compiling SQLite On Windows 11
Below are step-by-step instructions on how to build SQLite from
canonical source on a new Windows 11 PC, as of 2025-10-31.
canonical source on a new Windows 11 PC, as of 2024-10-09.
See [](./compile-for-unix.md) for a similar guide for unix-like
systems, including MacOS.
@@ -24,8 +24,7 @@ systems, including MacOS.
application to your task bar, as you will use it a lot. Bring up
an instance of this command prompt and do all of the subsequent steps
in that "x64 Native Tools" command prompt. (Or use "x86" if you want
a 32-bit build. Or use "ARM64" if you want to do a build for Windows
on ARM.) The subsequent steps will not work in a vanilla
a 32-bit build.) The subsequent steps will not work in a vanilla
DOS prompt. Nor will they work in PowerShell.
3. *(Optional):* Install TCL development libraries.
@@ -134,7 +133,9 @@ following minor changes:
The command the developers use for building the deliverable DLL on the
[download page](https://sqlite.org/download.html) is as follows:
> nmake /f Makefile.msc sqlite3.dll USE_NATIVE_LIBPATHS=1 "OPTS=-DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS4=1 -DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_JSON1=1 -DSQLITE_ENABLE_GEOPOLY=1 -DSQLITE_ENABLE_SESSION=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 -DSQLITE_ENABLE_SERIALIZE=1 -DSQLITE_ENABLE_MATH_FUNCTIONS=1"
> ~~~~
nmake /f Makefile.msc sqlite3.dll USE_NATIVE_LIBPATHS=1 "OPTS=-DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS4=1 -DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_JSON1=1 -DSQLITE_ENABLE_GEOPOLY=1 -DSQLITE_ENABLE_SESSION=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 -DSQLITE_ENABLE_SERIALIZE=1 -DSQLITE_ENABLE_MATH_FUNCTIONS=1"
~~~~
That command generates both the sqlite3.dll and sqlite3.def files. The same
command works for both 32-bit and 64-bit builds.
@@ -146,7 +147,9 @@ with TCL in order to function. The [sqlite3_analyzer.exe program](https://sqlit
is an example. You can build as described above, and then
enter:
> nmake /f Makefile.msc sqlite3_analyzer.exe
> ~~~~
nmake /f Makefile.msc sqlite3_analyzer.exe
~~~~
And you will end up with a working executable. However, that executable
will depend on having the "tcl98.dll" library somewhere on your %PATH%.
@@ -172,47 +175,17 @@ statically linked so that it does not depend on separate DLL:
5. CD into your SQLite source code directory and build the desired
utility program, but add the following extra argument to the
nmake command line:
<blockquote><pre>STATICALLY_LINK_TCL=1</pre></blockquote>
<blockquote><pre>
STATICALLY_LINK_TCL=1
</pre></blockquote>
<p>So, for example, to build a statically linked version of
sqlite3_analyzer.exe, you might type:
<blockquote><pre>nmake /f Makefile.msc STATICALLY_LINK_TCL=1 sqlite3_analyzer.exe</pre></blockquote>
<blockquote><pre>
nmake /f Makefile.msc STATICALLY_LINK_TCL=1 sqlite3_analyzer.exe
</pre></blockquote>
6. After your executable is built, you can verify that it does not
depend on the TCL DLL by running:
<blockquote><pre>dumpbin /dependents sqlite3_analyzer.exe</pre></blockquote>
## Linking Against ZLIB
Some feature (such as zip-file support in the CLI) require the ZLIB
compression library. That library is more or less universally available
on unix platforms, but is seldom provided on Windows. You will probably
need to provide it yourself. Here the the steps needed:
1. Download the zlib-1.3.1.tar.gz tarball (or a similar version).
Unpack the tarball sources. You can put them wherever you like.
For the purposes of this document, let's assume you put the source
tree in c:\\zlib-64. Note: If you are building for both x64 and
x86, you will need separate builds of ZLIB for each, thus separate
build directories.
2. Before building SQLite (as described above) first make these
environment changes. The lead-programmer for SQLite (who writes
these words) has BAT files named "env-x64.bat" and "env-x32.bat"
and "env-arm64.bat" that make these changes, and he runs those
BAT file whenever he starts a new shell. These are the settings
needed:
<blockquote>
set USE_ZLIB=1<br>
set BUILD_ZLIB=0<br>
set ZLIBDIR=c:\\zlib-64
</blockquote>
3. Because the settings in step 2 specify "BUILD_ZLIB=0", you will need
to build the library at least once. I recommand:
<blockquote>
make clean sqlite3.exe BUILD_ZLIB=1
</blockquote>
4. After making the environment changes specified in steps 1 through 3
above, you then build and test SQLite as you normally would. The
environment variable changes will cause ZLIB to be linked automatically.
<blockquote><pre>
dumpbin /dependents sqlite3_analyzer.exe
</pre></blockquote>
+9 -8
View File
@@ -149,10 +149,11 @@ RFC 8259 format, without extensions. The payload is the ASCII
text representation of that numeric value.
<li value="4"><p><b>INT5</b> &rarr;
The element is a JSON integer literal in hexadecimal notation.
The payload is the ASCII text representation of the literal.
Because the payload is in a non-standard format, it will need
to be translated when the JSONB is converted into RFC 8259 text JSON.
The element is a JSON integer value that is not in the
canonical format. The payload is the ASCII
text representation of that numeric value. Because the payload is in a
non-standard format, it will need to be translated when the JSONB is
converted into RFC 8259 text JSON.
<li value="5"><p><b>FLOAT</b> &rarr;
The element is a JSON floating-point value in the canonical
@@ -161,10 +162,10 @@ text representation of that numeric value.
<li value="6"><p><b>FLOAT5</b> &rarr;
The element is a JSON floating-point value that is not in the
canonical JSON format but rather the extended JSON5 format.
The payload is the ASCII text representation of that numeric value.
Because the payload is in a non-standard format, it will need to
be translated when the JSONB is converted into RFC 8259 text JSON.
canonical format. The payload is the ASCII
text representation of that numeric value. Because the payload is in a
non-standard format, it will need to be translated when the JSONB is
converted into RFC 8259 text JSON.
<li value="7"><p><b>TEXT</b> &rarr;
The element is a JSON string value that does not contain
+8 -22
View File
@@ -696,7 +696,6 @@ other than that, the order of directives in Lemon is arbitrary.</p>
<li><tt><a href='#pright'>%right</a></tt>
<li><tt><a href='#reallc'>%realloc</a></tt>
<li><tt><a href='#stack_overflow'>%stack_overflow</a></tt>
<li><tt><a href='#reallc'>%stack_size_limit</a></tt>
<li><tt><a href='#stack_size'>%stack_size</a></tt>
<li><tt><a href='#start_symbol'>%start_symbol</a></tt>
<li><tt><a href='#syntax_error'>%syntax_error</a></tt>
@@ -1204,33 +1203,20 @@ the wildcard token and some other token, the other token is always used.
The wildcard token is only matched if there are no alternatives.</p>
<a id='reallc'></a>
<h4>4.4.26 The <tt>%realloc</tt>, <tt>%free</tt>, and
<tt>%stack_size_limit</tt> directives</h4>
<h4>4.4.26 The <tt>%realloc</tt> and <tt>%free</tt> directives</h4>
<p>The <tt>%realloc</tt> and <tt>%free</tt> directives defines function
that allocate and free heap memory. The signatures and semantics of
these functions are similar to the realloc() and free() functions from
the standard C library, except that these functions take an extra
parameter at the end that is determined by %extra_context. If
%extra_context is not defined, then the extra argument is 0. The
extra parameter provides the capability to do better error reporting
in the event of a memory allocation error, and/or to use an alternative
private application heap.
that allocate and free heap memory. The signatures of these functions
should be the same as the realloc() and free() functions from the standard
C library.
<p>If both of these functions are defined then they are used to
allocate and free memory for supplemental parser stack space, if
the initial parse stack space is exceeded. The initial parser stack size
<p>If both of these functions are defined
then these functions are used to allocate and free
memory for supplemental parser stack space, if the initial
parse stack space is exceeded. The initial parser stack size
is specified by either <tt>%stack_size</tt> or the
-DYYSTACKDEPTH compile-time flag.
<p>The <tt>%stack_size_limit</tt> directive defines a function that returns
the maximum allowed parser stack size. If this diretive does not exist,
no size limit is enforced. This function takes a single argument which
is the %extra_context value or "0" if %extra_context is not defined.
The function should return an integer that is the maximum
number of parser stack entries. If more stack space
than this is needed, the %stack_overflow code is invoked.
<a id='errors'></a>
<h2>5.0 Error Processing</h2>
+57 -102
View File
@@ -4,12 +4,6 @@
<ul type=none>
<li> 1. <a href=#overview>Overview</a>
<ul type=none>
<li> 1.1. <a href=#runtr>Running testrunner.tcl</a>
<li> 1.2. <a href=#runviamake>Run using "make"</a>
<li> 1.3. <a href=#outputs>Outputs from testrunner.tcl</a>
<li> 1.4. <a href=#help>Built-in help</a>
</ul>
<li> 2. <a href=#binary_tests>Binary Tests</a>
<ul type=none>
<li> 2.1. <a href=#organization_tests>Organization of Tcl Tests</a>
@@ -32,40 +26,17 @@
The testrunner.tcl program is a Tcl script used to run multiple SQLite
tests in parallel, thus reducing testing time on multi-core machines.
The testrunner.tcl supports running tests that based on `testfixture`,
`sqlite3`, and `fuzzcheck`.
It supports the following types of tests:
<a name="runtr"></a>
## 1.1 Running testrunner.tcl
* Tcl test scripts.
The testrunner.tcl script is located in the "test" subdirectory of the
SQLite source tree. So if your shell is current positioned at the top
of the source tree, you would normally run the script using the command:
"<tt>test/testrunner.tcl</tt>". On Windows, you have to specify the
`tclsh` interpreter command first, like this:
"<tt>tclsh&nbsp;test/testrunner.tcl</tt>".
* Fuzzcheck tests, including using an external fuzzcheck database.
In this document, we will assume that you are on a unix-like OS
(not on Windows) and that your current directory is the root
of the SQLite source tree, and so all invocations of the testrunner.tcl
script will be of the form "<tt>test/testrunner.tcl</tt>". If you
are in a different directory, then make appropriate adjustments to
the path. On Windows, add the "<tt>tclsh</tt>" interpreter command
up front.
<a name="runviamake"></a>
## 1.2 Run using make
The standard Makefiles for SQLite include targets that invoke
testrunner.tcl. So the following commands also run testrunner.tcl:
* `make devtest`
* `make releasetest`
* `make sdevtest`
* `make testrunner`
<a name="outputs"></a>
## 1.3 Outputs from testrunner.tcl
* Tests run with `make` commands. Examples:
- `make devtest`
- `make releasetest`
- `make sdevtest`
- `make testrunner`
The testrunner.tcl program stores output of all tests and builds run in
log file **testrunner.log**, created in the current working directory.
@@ -83,19 +54,17 @@ A useful query might be:
```
You can get a summary of errors in a prior run by invoking commands like
those shown below. Note that the testrunner.tcl script can be run directly
on unix systems (including Macs) but you will need to add <tt>tclsh</tt>
to the front on Windows.
these:
```
test/testrunner.tcl errors
test/testrunner.tcl errors -v
tclsh $(TESTDIR)/testrunner.tcl errors
tclsh $(TESTDIR)/testrunner.tcl errors -v
```
Running the command:
```
test/testrunner.tcl status
tclsh $(TESTDIR)/testrunner.tcl status
```
in the directory containing the testrunner.db database runs various queries
@@ -104,43 +73,32 @@ A good way to keep and eye on test progress is to run either of the two
following commands:
```
watch test/testrunner.tcl status
test/testrunner.tcl status -d 2
watch tclsh $(TESTDIR)/testrunner.tcl status
tclsh $(TESTDIR)/testrunner.tcl status -d 2
```
Both of the commands above accomplish about the same thing, but the second
one has the advantage of not requiring "watch" to be installed on your
system.
Sometimes testrunner.tcl uses the `testfixture` and `sqlite3` binaries that
are in the directory from which testrunner.tcl is run.
(see "Binary Tests" below). Sometimes it builds testfixture and
Sometimes testrunner.tcl uses the `testfixture` binary that it is run with
to run tests (see "Binary Tests" below). Sometimes it builds testfixture and
other binaries in specific configurations to test (see "Source Tests").
<a name=help></a>
## 1.4 Built-in help
Run this command:
```
test/testrunner.tcl help
```
To get a summary of all of the various command-line options available
with testrunner.tcl
<a name=binary_tests></a>
# 2. Binary Tests
The commands described in this section all run various combinations of the Tcl
test scripts using whatever `testfixture` binary (and maybe also the `sqlite3`
binary, depending on the test) that is found in the directory from which
testrunner.tcl is launched. So typically, one must first run something
like "`make testfixture sqlite3`" before launching binary tests. In other
words, testrunner.tcl does not automatically build the binaries under test
for binary tests. The testrunner.tcl expects the binaries to be available
already.
test scripts using the `testfixture` binary used to run the testrunner.tcl
script (i.e. they do not invoke the compiler to build new binaries, or the
`make` command to run tests that are not Tcl scripts). The procedure to run
these tests is therefore:
1. Build the "testfixture" (or "testfixture.exe" for windows) binary using
whatever method seems convenient.
2. Test the binary built in step 1 by running testrunner.tcl with it,
perhaps with various options.
The following sub-sections describe the various options that can be
passed to testrunner.tcl to test binary testfixture builds.
@@ -182,22 +140,22 @@ are defined in file *testrunner_data.tcl*.
To run the "veryquick" test set, use either of the following:
```
test/testrunner.tcl
test/testrunner.tcl veryquick
./testfixture $TESTDIR/testrunner.tcl
./testfixture $TESTDIR/testrunner.tcl veryquick
```
To run the "full" test suite:
```
test/testrunner.tcl full
./testfixture $TESTDIR/testrunner.tcl full
```
To run the subset of the "full" test suite for which the test file name matches
a specified pattern (e.g. all tests that start with "fts5"), either of:
```
test/testrunner.tcl fts5%
test/testrunner.tcl 'fts5*'
./testfixture $TESTDIR/testrunner.tcl fts5%
./testfixture $TESTDIR/testrunner.tcl 'fts5*'
```
Strictly speaking, for a test to be run the pattern must match the script
@@ -209,7 +167,7 @@ characters specified as part of the pattern are transformed to "\*".
To run "all" tests (full + permutations):
```
test/testrunner.tcl all
./testfixture $TESTDIR/testrunner.tcl all
```
<a name=binary_test_failures></a>
@@ -228,15 +186,10 @@ If there is no permutation, the individual test script may be run with:
Or, if the failure occured as part of a permutation:
```
test/testrunner.tcl $PERMUTATION $PATH_TO_SCRIPT
./testfixture $TESTDIR/testrunner.tcl $PERMUTATION $PATH_TO_SCRIPT
```
One can also rerun all tests that failed or did not complete
in the previous invocation by typing:
```
test/testrunner.tcl retest
```
TODO: An example instead of "$PERMUTATION" and $PATH\_TO\_SCRIPT?
<a name=source_code_tests></a>
# 3. Source Code Tests
@@ -251,9 +204,11 @@ other tests. The advantages of this are that:
* it ensures that tests are always run using binaries created with the
same set of compiler options.
The testrunner.tcl commands described in this section do not require that
the testfixture and/or sqlite3 binaries be built ahead of time. Those
binaries will be constructed automatically.
The testrunner.tcl commands described in this section may be run using
either a *testfixture* (or testfixture.exe) build, or with any other Tcl
shell that supports SQLite 3.31.1 or newer via "package require sqlite3".
TODO: ./configure + Makefile.msc build systems.
<a name=commands_to_run_tests></a>
## 3.1. Commands to Run SQLite Tests
@@ -263,7 +218,7 @@ the `make fuzztest` target once for each of two --enable-all builds - one
with debugging enabled and one without:
```
test/testrunner.tcl mdevtest
tclsh $TESTDIR/testrunner.tcl mdevtest
```
In other words, it is equivalent to running:
@@ -272,13 +227,13 @@ In other words, it is equivalent to running:
$TOP/configure --enable-all --enable-debug
make fuzztest
make testfixture
$TOP/test/testrunner.tcl veryquick
./testfixture $TOP/test/testrunner.tcl veryquick
# Then, after removing files created by the tests above:
$TOP/configure --enable-all OPTS="-O0"
make fuzztest
make testfixture
$TOP/test/testrunner.tcl veryquick
./testfixture $TOP/test/testrunner.tcl veryquick
```
The **sdevtest** command is identical to the mdevtest command, except that the
@@ -286,7 +241,7 @@ second of the two builds is a sanitizer build. Specifically, this means that
OPTS="-fsanitize=address,undefined" is specified instead of OPTS="-O0":
```
test/testrunner.tcl sdevtest
tclsh $TESTDIR/testrunner.tcl sdevtest
```
The **release** command runs lots of tests under lots of builds. It runs
@@ -295,7 +250,7 @@ on Linux, Windows or OSX. Refer to *testrunner\_data.tcl* for the details
of the specific tests run.
```
test/testrunner.tcl release
tclsh $TESTDIR/testrunner.tcl release
```
As with <a href=#source code tests>source code tests</a>, one or more patterns
@@ -303,7 +258,7 @@ may be appended to any of the above commands (mdevtest, sdevtest or release).
Pattern matching is used for both Tcl tests and fuzz tests.
```
test/testrunner.tcl release rtree%
tclsh $TESTDIR/testrunner.tcl release rtree%
```
<a name=zipvfs_tests></a>
@@ -313,14 +268,14 @@ testrunner.tcl can build a zipvfs-enabled testfixture and use it to run
tests from the Zipvfs project with the following command:
```
test/testrunner.tcl --zipvfs $PATH_TO_ZIPVFS
tclsh $TESTDIR/testrunner.tcl --zipvfs $PATH_TO_ZIPVFS
```
This can be combined with any of "mdevtest", "sdevtest" or "release" to
test both SQLite and Zipvfs with a single command:
```
test/testrunner.tcl --zipvfs $PATH_TO_ZIPVFS mdevtest
tclsh $TESTDIR/testrunner.tcl --zipvfs $PATH_TO_ZIPVFS mdevtest
```
<a name=source_code_test_failures></a>
@@ -340,10 +295,10 @@ a dos \*.bat file on windows. For example:
```
# Create a script that recreates build configuration "Device-One" on
# Linux or OSX:
test/testrunner.tcl script Device-One > make.sh
tclsh $TESTDIR/testrunner.tcl script Device-One > make.sh
# Create a script that recreates build configuration "Have-Not" on Windows:
test/testrunner.tcl script Have-Not > make.bat
tclsh $TESTDIR/testrunner.tcl script Have-Not > make.bat
```
The generated bash or \*.bat file script accepts a single argument - a makefile
@@ -366,7 +321,7 @@ Thus, for example, to run a full releasetest including an external
dbsqlfuzz database, run a command like one of these:
```
test/testrunner.tcl releasetest --fuzzdb ../fuzz/20250415.db
tclsh test/testrunner.tcl releasetest --fuzzdb ../fuzz/20250415.db
FUZZDB=../fuzz/20250415.db make releasetest
nmake /f Makefile.msc FUZZDB=../fuzz/20250415.db releasetest
```
@@ -376,7 +331,7 @@ databases. So if you want to run *only* tests involving the external
database, you can use a command something like this:
```
test/testrunner.tcl releasetest 20250415 --fuzzdb ../fuzz/20250415.db
tclsh test/testrunner.tcl releasetest 20250415 --fuzzdb ../fuzz/20250415.db
```
<a name=testrunner_options></a>
@@ -390,7 +345,7 @@ required by a test, not to run any actual tests. For example:
```
# Build binaries required by release test.
test/testrunner.tcl --buildonly release"
tclsh $TESTDIR/testrunner.tcl --buildonly release"
```
The **--dryrun** option prevents testrunner.tcl from building any binaries
@@ -399,7 +354,7 @@ would normally execute into the testrunner.log file. Example:
```
# Log the shell commmands that make up the mdevtest test.
test/testrunner.tcl --dryrun mdevtest"
tclsh $TESTDIR/testrunner.tcl --dryrun mdevtest"
```
The **--explain** option is similar to --dryrun in that it prevents
@@ -409,7 +364,7 @@ summary of all the builds and tests that would have been run.
```
# Show what builds and tests would have been run
test/testrunner.tcl --explain mdevtest
tclsh $TESTDIR/testrunner.tcl --explain mdevtest
```
The **--status** option uses VT100 escape sequences to display the test
@@ -425,7 +380,7 @@ When running either binary or source code tests, testrunner.tcl reports the
number of jobs it intends to use to stdout. e.g.
```
$ test/testrunner.tcl
$ ./testfixture $TESTDIR/testrunner.tcl
splitting work across 16 jobs
... more output ...
```
@@ -435,7 +390,7 @@ of real cores on the machine. This can be overridden using the "--jobs" (or -j)
switch:
```
$ test/testrunner.tcl --jobs 8
$ ./testfixture $TESTDIR/testrunner.tcl --jobs 8
splitting work across 8 jobs
... more output ...
```
@@ -445,5 +400,5 @@ running by exucuting the following command from the directory containing the
testrunner.log and testrunner.db files:
```
$ test/testrunner.tcl njob $NEW_NUMBER_OF_JOBS
$ ./testfixture $TESTDIR/testrunner.tcl njob $NEW_NUMBER_OF_JOBS
```
+1 -1
View File
@@ -90,7 +90,7 @@ foreach {tn setup} {
proc do_rec_test {tn sql res} {
set res [squish [string trim $res]]
set tst [subst -nocommands {
squish [string trim [exec $::CLI -noinit test.db ".expert" {$sql;}]]
squish [string trim [exec $::CLI test.db ".expert" {$sql;}]]
}]
uplevel [list do_test $tn $tst $res]
}
+25 -27
View File
@@ -172,11 +172,11 @@ struct sqlite3expert {
** Allocate and return nByte bytes of zeroed memory using sqlite3_malloc().
** If the allocation fails, set *pRc to SQLITE_NOMEM and return NULL.
*/
static void *idxMalloc(int *pRc, i64 nByte){
static void *idxMalloc(int *pRc, int nByte){
void *pRet;
assert( *pRc==SQLITE_OK );
assert( nByte>0 );
pRet = sqlite3_malloc64(nByte);
pRet = sqlite3_malloc(nByte);
if( pRet ){
memset(pRet, 0, nByte);
}else{
@@ -243,7 +243,7 @@ static int idxHashAdd(
return 1;
}
}
pEntry = idxMalloc(pRc, sizeof(IdxHashEntry) + (i64)nKey+1 + (i64)nVal+1);
pEntry = idxMalloc(pRc, sizeof(IdxHashEntry) + nKey+1 + nVal+1);
if( pEntry ){
pEntry->zKey = (char*)&pEntry[1];
memcpy(pEntry->zKey, zKey, nKey);
@@ -378,15 +378,15 @@ struct ExpertCsr {
};
static char *expertDequote(const char *zIn){
i64 n = STRLEN(zIn);
char *zRet = sqlite3_malloc64(n);
int n = STRLEN(zIn);
char *zRet = sqlite3_malloc(n);
assert( zIn[0]=='\'' );
assert( zIn[n-1]=='\'' );
if( zRet ){
i64 iOut = 0;
i64 iIn = 0;
int iOut = 0;
int iIn = 0;
for(iIn=1; iIn<(n-1); iIn++){
if( zIn[iIn]=='\'' ){
assert( zIn[iIn+1]=='\'' );
@@ -699,7 +699,7 @@ static int idxGetTableInfo(
sqlite3_stmt *p1 = 0;
int nCol = 0;
int nTab;
i64 nByte;
int nByte;
IdxTable *pNew = 0;
int rc, rc2;
char *pCsr = 0;
@@ -791,14 +791,14 @@ static char *idxAppendText(int *pRc, char *zIn, const char *zFmt, ...){
va_list ap;
char *zAppend = 0;
char *zRet = 0;
i64 nIn = zIn ? STRLEN(zIn) : 0;
i64 nAppend = 0;
int nIn = zIn ? STRLEN(zIn) : 0;
int nAppend = 0;
va_start(ap, zFmt);
if( *pRc==SQLITE_OK ){
zAppend = sqlite3_vmprintf(zFmt, ap);
if( zAppend ){
nAppend = STRLEN(zAppend);
zRet = (char*)sqlite3_malloc64(nIn + nAppend + 1);
zRet = (char*)sqlite3_malloc(nIn + nAppend + 1);
}
if( zAppend && zRet ){
if( nIn ) memcpy(zRet, zIn, nIn);
@@ -1562,8 +1562,8 @@ struct IdxRemCtx {
int eType; /* SQLITE_NULL, INTEGER, REAL, TEXT, BLOB */
i64 iVal; /* SQLITE_INTEGER value */
double rVal; /* SQLITE_FLOAT value */
i64 nByte; /* Bytes of space allocated at z */
i64 n; /* Size of buffer z */
int nByte; /* Bytes of space allocated at z */
int n; /* Size of buffer z */
char *z; /* SQLITE_TEXT/BLOB value */
} aSlot[1];
};
@@ -1599,13 +1599,11 @@ static void idxRemFunc(
break;
case SQLITE_BLOB:
assert( pSlot->n <= 0x7fffffff );
sqlite3_result_blob(pCtx, pSlot->z, (int)pSlot->n, SQLITE_TRANSIENT);
sqlite3_result_blob(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT);
break;
case SQLITE_TEXT:
assert( pSlot->n <= 0x7fffffff );
sqlite3_result_text(pCtx, pSlot->z, (int)pSlot->n, SQLITE_TRANSIENT);
sqlite3_result_text(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT);
break;
}
@@ -1625,10 +1623,10 @@ static void idxRemFunc(
case SQLITE_BLOB:
case SQLITE_TEXT: {
i64 nByte = sqlite3_value_bytes(argv[1]);
int nByte = sqlite3_value_bytes(argv[1]);
const void *pData = 0;
if( nByte>pSlot->nByte ){
char *zNew = (char*)sqlite3_realloc64(pSlot->z, nByte*2);
char *zNew = (char*)sqlite3_realloc(pSlot->z, nByte*2);
if( zNew==0 ){
sqlite3_result_error_nomem(pCtx);
return;
@@ -1683,7 +1681,7 @@ static int idxPopulateOneStat1(
int nCol = 0;
int i;
sqlite3_stmt *pQuery = 0;
i64 *aStat = 0;
int *aStat = 0;
int rc = SQLITE_OK;
assert( p->iSample>0 );
@@ -1729,7 +1727,7 @@ static int idxPopulateOneStat1(
sqlite3_free(zQuery);
if( rc==SQLITE_OK ){
aStat = (i64*)idxMalloc(&rc, sizeof(i64)*(nCol+1));
aStat = (int*)idxMalloc(&rc, sizeof(int)*(nCol+1));
}
if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){
IdxHashEntry *pEntry;
@@ -1746,11 +1744,11 @@ static int idxPopulateOneStat1(
}
if( rc==SQLITE_OK ){
i64 s0 = aStat[0];
zStat = sqlite3_mprintf("%lld", s0);
int s0 = aStat[0];
zStat = sqlite3_mprintf("%d", s0);
if( zStat==0 ) rc = SQLITE_NOMEM;
for(i=1; rc==SQLITE_OK && i<=nCol; i++){
zStat = idxAppendText(&rc, zStat, " %lld", (s0+aStat[i]/2) / aStat[i]);
zStat = idxAppendText(&rc, zStat, " %d", (s0+aStat[i]/2) / aStat[i]);
}
}
@@ -1829,7 +1827,7 @@ static int idxPopulateStat1(sqlite3expert *p, char **pzErr){
rc = sqlite3_exec(p->dbm, "ANALYZE; PRAGMA writable_schema=1", 0, 0, 0);
if( rc==SQLITE_OK ){
i64 nByte = sizeof(struct IdxRemCtx) + (sizeof(struct IdxRemSlot) * nMax);
int nByte = sizeof(struct IdxRemCtx) + (sizeof(struct IdxRemSlot) * nMax);
pCtx = (struct IdxRemCtx*)idxMalloc(&rc, nByte);
}
@@ -1846,7 +1844,7 @@ static int idxPopulateStat1(sqlite3expert *p, char **pzErr){
}
if( rc==SQLITE_OK ){
pCtx->nSlot = (i64)nMax+1;
pCtx->nSlot = nMax+1;
rc = idxPrepareStmt(p->dbm, &pAllIndex, pzErr, zAllIndex);
}
if( rc==SQLITE_OK ){
@@ -2113,7 +2111,7 @@ int sqlite3_expert_sql(
if( pStmt ){
IdxStatement *pNew;
const char *z = sqlite3_sql(pStmt);
i64 n = STRLEN(z);
int n = STRLEN(z);
pNew = (IdxStatement*)idxMalloc(&rc, sizeof(IdxStatement) + n+1);
if( rc==SQLITE_OK ){
pNew->zSql = (char*)&pNew[1];
+6 -3
View File
@@ -1816,7 +1816,9 @@ static int fts3CursorSeekStmt(Fts3Cursor *pCsr){
zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist);
if( !zSql ) return SQLITE_NOMEM;
p->bLock++;
rc = sqlite3Fts3PrepareStmt(p, zSql, 1, 1, &pCsr->pStmt);
rc = sqlite3_prepare_v3(
p->db, zSql,-1,SQLITE_PREPARE_PERSISTENT,&pCsr->pStmt,0
);
p->bLock--;
sqlite3_free(zSql);
}
@@ -3391,7 +3393,9 @@ static int fts3FilterMethod(
}
if( zSql ){
p->bLock++;
rc = sqlite3Fts3PrepareStmt(p, zSql, 1, 1, &pCsr->pStmt);
rc = sqlite3_prepare_v3(
p->db,zSql,-1,SQLITE_PREPARE_PERSISTENT,&pCsr->pStmt,0
);
p->bLock--;
sqlite3_free(zSql);
}else{
@@ -4014,7 +4018,6 @@ static int fts3IntegrityMethod(
UNUSED_PARAMETER(isQuick);
rc = sqlite3Fts3IntegrityCheck(p, &bOk);
assert( pVtab->zErrMsg==0 || rc!=SQLITE_OK );
assert( rc!=SQLITE_CORRUPT_VTAB );
if( rc==SQLITE_ERROR || (rc&0xFF)==SQLITE_CORRUPT ){
*pzErr = sqlite3_mprintf("unable to validate the inverted index for"
+1 -19
View File
@@ -203,16 +203,7 @@ typedef sqlite3_int64 i64; /* 8-byte signed integer */
#define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32))
#define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)
#if !defined(deliberate_fall_through)
# if defined(__has_attribute)
# if __has_attribute(fallthrough)
# define deliberate_fall_through __attribute__((fallthrough));
# endif
# endif
#endif
#if !defined(deliberate_fall_through)
# define deliberate_fall_through
#endif
#define deliberate_fall_through
/*
** Macros needed to provide flexible arrays in a portable way
@@ -610,15 +601,6 @@ int sqlite3Fts3Incrmerge(Fts3Table*,int,int);
(*(u8*)(p)&0x80) ? sqlite3Fts3GetVarint32(p, piVal) : (*piVal=*(u8*)(p), 1) \
)
int sqlite3Fts3PrepareStmt(
Fts3Table *p, /* Prepare for this connection */
const char *zSql, /* SQL to prepare */
int bPersist, /* True to set SQLITE_PREPARE_PERSISTENT */
int bAllowVtab, /* True to omit SQLITE_PREPARE_NO_VTAB */
sqlite3_stmt **pp /* OUT: Prepared statement */
);
/* fts3.c */
void sqlite3Fts3ErrMsg(char**,const char*,...);
int sqlite3Fts3PutVarint(char *, sqlite3_int64);
+1 -1
View File
@@ -325,7 +325,7 @@ static int fts3auxNextMethod(sqlite3_vtab_cursor *pCursor){
pCsr->aStat[1].nDoc++;
}
eState = 2;
/* no break */ deliberate_fall_through
/* fall through */
case 2:
if( v==0 ){ /* 0x00. Next integer will be a docid. */
+4
View File
@@ -17,6 +17,10 @@
#include <string.h>
#include <assert.h>
#ifndef SQLITE_AMALGAMATION
typedef sqlite3_int64 i64;
#endif
/*
** Characters that may appear in the second argument to matchinfo().
*/
+10 -32
View File
@@ -98,9 +98,9 @@ typedef struct SegmentWriter SegmentWriter;
** incrementally. See function fts3PendingListAppend() for details.
*/
struct PendingList {
sqlite3_int64 nData;
int nData;
char *aData;
sqlite3_int64 nSpace;
int nSpace;
sqlite3_int64 iLastDocid;
sqlite3_int64 iLastCol;
sqlite3_int64 iLastPos;
@@ -273,24 +273,6 @@ struct SegmentNode {
#define SQL_UPDATE_LEVEL_IDX 38
#define SQL_UPDATE_LEVEL 39
/*
** Wrapper around sqlite3_prepare_v3() to ensure that SQLITE_PREPARE_FROM_DDL
** is always set.
*/
int sqlite3Fts3PrepareStmt(
Fts3Table *p, /* Prepare for this connection */
const char *zSql, /* SQL to prepare */
int bPersist, /* True to set SQLITE_PREPARE_PERSISTENT */
int bAllowVtab, /* True to omit SQLITE_PREPARE_NO_VTAB */
sqlite3_stmt **pp /* OUT: Prepared statement */
){
int f = SQLITE_PREPARE_FROM_DDL
|((bAllowVtab==0) ? SQLITE_PREPARE_NO_VTAB : 0)
|(bPersist ? SQLITE_PREPARE_PERSISTENT : 0);
return sqlite3_prepare_v3(p->db, zSql, -1, f, pp, NULL);
}
/*
** This function is used to obtain an SQLite prepared statement handle
** for the statement identified by the second argument. If successful,
@@ -416,12 +398,12 @@ static int fts3SqlStmt(
pStmt = p->aStmt[eStmt];
if( !pStmt ){
int bAllowVtab = 0;
int f = SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB;
char *zSql;
if( eStmt==SQL_CONTENT_INSERT ){
zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, p->zWriteExprlist);
}else if( eStmt==SQL_SELECT_CONTENT_BY_ROWID ){
bAllowVtab = 1;
f &= ~SQLITE_PREPARE_NO_VTAB;
zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist);
}else{
zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName);
@@ -429,7 +411,7 @@ static int fts3SqlStmt(
if( !zSql ){
rc = SQLITE_NOMEM;
}else{
rc = sqlite3Fts3PrepareStmt(p, zSql, 1, bAllowVtab, &pStmt);
rc = sqlite3_prepare_v3(p->db, zSql, -1, f, &pStmt, NULL);
sqlite3_free(zSql);
assert( rc==SQLITE_OK || pStmt==0 );
p->aStmt[eStmt] = pStmt;
@@ -778,9 +760,7 @@ static int fts3PendingTermsAddOne(
pList = (PendingList *)fts3HashFind(pHash, zToken, nToken);
if( pList ){
assert( (i64)pList->nData+(i64)nToken+(i64)sizeof(Fts3HashElem)
<= (i64)p->nPendingData );
p->nPendingData -= (int)(pList->nData + nToken + sizeof(Fts3HashElem));
p->nPendingData -= (pList->nData + nToken + sizeof(Fts3HashElem));
}
if( fts3PendingListAppend(&pList, p->iPrevDocid, iCol, iPos, &rc) ){
if( pList==fts3HashInsert(pHash, zToken, nToken, pList) ){
@@ -793,9 +773,7 @@ static int fts3PendingTermsAddOne(
}
}
if( rc==SQLITE_OK ){
assert( (i64)p->nPendingData + pList->nData + nToken
+ sizeof(Fts3HashElem) <= 0x3fffffff );
p->nPendingData += (int)(pList->nData + nToken + sizeof(Fts3HashElem));
p->nPendingData += (pList->nData + nToken + sizeof(Fts3HashElem));
}
return rc;
}
@@ -3596,7 +3574,7 @@ static int fts3DoRebuild(Fts3Table *p){
if( !zSql ){
rc = SQLITE_NOMEM;
}else{
rc = sqlite3Fts3PrepareStmt(p, zSql, 0, 1, &pStmt);
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
}
@@ -5349,7 +5327,7 @@ int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk){
if( !zSql ){
rc = SQLITE_NOMEM;
}else{
rc = sqlite3Fts3PrepareStmt(p, zSql, 0, 1, &pStmt);
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
}
@@ -5479,7 +5457,7 @@ static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){
v = atoi(&zVal[9]);
if( v>=24 && v<=p->nPgsz-35 ) p->nNodeSize = v;
rc = SQLITE_OK;
}else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 11) ){
}else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){
v = atoi(&zVal[11]);
if( v>=64 && v<=FTS3_MAX_PENDING_DATA ) p->nMaxPendingData = v;
rc = SQLITE_OK;
+2 -8
View File
@@ -81,13 +81,7 @@ typedef sqlite3_uint64 u64;
# define FLEXARRAY 1
#endif
#endif /* SQLITE_AMALGAMATION */
/*
** Constants for the largest and smallest possible 32-bit signed integers.
*/
# define LARGEST_INT32 ((int)(0x7fffffff))
# define SMALLEST_INT32 ((int)((-1) - LARGEST_INT32))
#endif
/* Truncate very long tokens to this many bytes. Hard limit is
** (65536-1-1-4-9)==65521 bytes. The limiting factor is the 16-bit offset
@@ -821,7 +815,7 @@ int sqlite3Fts5ExprPattern(
** i64 iRowid = sqlite3Fts5ExprRowid(pExpr);
** }
*/
int sqlite3Fts5ExprFirst(Fts5Expr*, Fts5Index *pIdx, i64 iMin, i64, int bDesc);
int sqlite3Fts5ExprFirst(Fts5Expr*, Fts5Index *pIdx, i64 iMin, int bDesc);
int sqlite3Fts5ExprNext(Fts5Expr*, i64 iMax);
int sqlite3Fts5ExprEof(Fts5Expr*);
i64 sqlite3Fts5ExprRowid(Fts5Expr*);
+1 -1
View File
@@ -455,7 +455,7 @@ static void fts5SnippetFunction(
iBestCol = (iCol>=0 ? iCol : 0);
nPhrase = pApi->xPhraseCount(pFts);
aSeen = sqlite3_malloc64(nPhrase);
aSeen = sqlite3_malloc(nPhrase);
if( aSeen==0 ){
rc = SQLITE_NOMEM;
}
+1 -1
View File
@@ -288,7 +288,7 @@ char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn){
if( nIn<0 ){
nIn = (int)strlen(pIn);
}
zRet = (char*)sqlite3_malloc64((i64)nIn+1);
zRet = (char*)sqlite3_malloc(nIn+1);
if( zRet ){
memcpy(zRet, pIn, nIn);
zRet[nIn] = '\0';
+3 -1
View File
@@ -576,7 +576,7 @@ int sqlite3Fts5ConfigParse(
sqlite3_int64 nByte;
int bUnindexed = 0; /* True if there are one or more UNINDEXED */
*ppOut = pRet = (Fts5Config*)sqlite3_malloc64(sizeof(Fts5Config));
*ppOut = pRet = (Fts5Config*)sqlite3_malloc(sizeof(Fts5Config));
if( pRet==0 ) return SQLITE_NOMEM;
memset(pRet, 0, sizeof(Fts5Config));
pRet->pGlobal = pGlobal;
@@ -1123,3 +1123,5 @@ void sqlite3Fts5ConfigErrmsg(Fts5Config *pConfig, const char *zFmt, ...){
va_end(ap);
}
+3 -12
View File
@@ -314,7 +314,7 @@ int sqlite3Fts5ExprNew(
assert( sParse.rc!=SQLITE_OK || sParse.zErr==0 );
if( sParse.rc==SQLITE_OK ){
*ppNew = pNew = sqlite3_malloc64(sizeof(Fts5Expr));
*ppNew = pNew = sqlite3_malloc(sizeof(Fts5Expr));
if( pNew==0 ){
sParse.rc = SQLITE_NOMEM;
sqlite3Fts5ParseNodeFree(sParse.pExpr);
@@ -466,7 +466,7 @@ int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2){
p2->pRoot = 0;
if( sParse.rc==SQLITE_OK ){
Fts5ExprPhrase **ap = (Fts5ExprPhrase**)sqlite3_realloc64(
Fts5ExprPhrase **ap = (Fts5ExprPhrase**)sqlite3_realloc(
p1->apExprPhrase, nPhrase * sizeof(Fts5ExprPhrase*)
);
if( ap==0 ){
@@ -1549,13 +1549,7 @@ static int fts5ExprNodeFirst(Fts5Expr *pExpr, Fts5ExprNode *pNode){
** Return SQLITE_OK if successful, or an SQLite error code otherwise. It
** is not considered an error if the query does not match any documents.
*/
int sqlite3Fts5ExprFirst(
Fts5Expr *p,
Fts5Index *pIdx,
i64 iFirst,
i64 iLast,
int bDesc
){
int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bDesc){
Fts5ExprNode *pRoot = p->pRoot;
int rc; /* Return code */
@@ -1577,9 +1571,6 @@ int sqlite3Fts5ExprFirst(
assert( pRoot->bEof==0 );
rc = fts5ExprNodeNext(p, pRoot, 0, 0);
}
if( fts5RowidCmp(p, pRoot->iRowid, iLast)>0 ){
pRoot->bEof = 1;
}
return rc;
}
+1 -1
View File
@@ -91,7 +91,7 @@ int sqlite3Fts5HashNew(Fts5Config *pConfig, Fts5Hash **ppNew, int *pnByte){
int rc = SQLITE_OK;
Fts5Hash *pNew;
*ppNew = pNew = (Fts5Hash*)sqlite3_malloc64(sizeof(Fts5Hash));
*ppNew = pNew = (Fts5Hash*)sqlite3_malloc(sizeof(Fts5Hash));
if( pNew==0 ){
rc = SQLITE_NOMEM;
}else{
+39 -46
View File
@@ -877,9 +877,9 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
if( rc==SQLITE_OK ){
u8 *aOut = 0; /* Read blob data into this buffer */
i64 nByte = sqlite3_blob_bytes(p->pReader);
i64 szData = (sizeof(Fts5Data) + 7) & ~7;
i64 nAlloc = szData + nByte + FTS5_DATA_PADDING;
int nByte = sqlite3_blob_bytes(p->pReader);
int szData = (sizeof(Fts5Data) + 7) & ~7;
sqlite3_int64 nAlloc = szData + nByte + FTS5_DATA_PADDING;
pRet = (Fts5Data*)sqlite3_malloc64(nAlloc);
if( pRet ){
pRet->nn = nByte;
@@ -2074,7 +2074,6 @@ static void fts5SegIterReverseInitPage(Fts5Index *p, Fts5SegIter *pIter){
while( 1 ){
u64 iDelta = 0;
if( i>=n ) break;
if( eDetail==FTS5_DETAIL_NONE ){
/* todo */
if( i<n && a[i]==0 ){
@@ -2093,7 +2092,7 @@ static void fts5SegIterReverseInitPage(Fts5Index *p, Fts5SegIter *pIter){
/* If necessary, grow the pIter->aRowidOffset[] array. */
if( iRowidOffset>=pIter->nRowidOffset ){
i64 nNew = pIter->nRowidOffset + 8;
int nNew = pIter->nRowidOffset + 8;
int *aNew = (int*)sqlite3_realloc64(pIter->aRowidOffset,nNew*sizeof(int));
if( aNew==0 ){
p->rc = SQLITE_NOMEM;
@@ -5240,7 +5239,7 @@ static void fts5DoSecureDelete(
int iSegid = pSeg->pSeg->iSegid;
u8 *aPg = pSeg->pLeaf->p;
int nPg = pSeg->pLeaf->nn;
int iPgIdx = pSeg->pLeaf->szLeaf; /* Offset of page footer */
int iPgIdx = pSeg->pLeaf->szLeaf;
u64 iDelta = 0;
int iNextOff = 0;
@@ -5319,7 +5318,7 @@ static void fts5DoSecureDelete(
iSOP += fts5GetVarint32(&aPg[iSOP], nPos);
}
assert_nc( iSOP==pSeg->iLeafOffset );
iNextOff = iSOP + pSeg->nPos;
iNextOff = pSeg->iLeafOffset + pSeg->nPos;
}
}
@@ -5399,31 +5398,31 @@ static void fts5DoSecureDelete(
** is another term following it on this page. So the subsequent term
** needs to be moved to replace the term associated with the entry
** being removed. */
u64 nPrefix = 0;
u64 nSuffix = 0;
u64 nPrefix2 = 0;
u64 nSuffix2 = 0;
int nPrefix = 0;
int nSuffix = 0;
int nPrefix2 = 0;
int nSuffix2 = 0;
iDelKeyOff = iNextOff;
iNextOff += fts5GetVarint(&aPg[iNextOff], &nPrefix2);
iNextOff += fts5GetVarint(&aPg[iNextOff], &nSuffix2);
iNextOff += fts5GetVarint32(&aPg[iNextOff], nPrefix2);
iNextOff += fts5GetVarint32(&aPg[iNextOff], nSuffix2);
if( iKey!=1 ){
iKeyOff += fts5GetVarint(&aPg[iKeyOff], &nPrefix);
iKeyOff += fts5GetVarint32(&aPg[iKeyOff], nPrefix);
}
iKeyOff += fts5GetVarint(&aPg[iKeyOff], &nSuffix);
iKeyOff += fts5GetVarint32(&aPg[iKeyOff], nSuffix);
nPrefix = MIN(nPrefix, nPrefix2);
nSuffix = (nPrefix2 + nSuffix2) - nPrefix;
if( (iKeyOff+nSuffix)>(u64)iPgIdx || (iNextOff+nSuffix2)>(u64)iPgIdx ){
if( (iKeyOff+nSuffix)>iPgIdx || (iNextOff+nSuffix2)>iPgIdx ){
FTS5_CORRUPT_IDX(p);
}else{
if( iKey!=1 ){
iOff += sqlite3Fts5PutVarint(&aPg[iOff], nPrefix);
}
iOff += sqlite3Fts5PutVarint(&aPg[iOff], nSuffix);
if( nPrefix2>(u64)pSeg->term.n ){
if( nPrefix2>pSeg->term.n ){
FTS5_CORRUPT_IDX(p);
}else if( nPrefix2>nPrefix ){
memcpy(&aPg[iOff], &pSeg->term.p[nPrefix], nPrefix2-nPrefix);
@@ -5454,7 +5453,7 @@ static void fts5DoSecureDelete(
u8 *aTermIdx = &pTerm->p[pTerm->szLeaf];
int nTermIdx = pTerm->nn - pTerm->szLeaf;
int iTermIdx = 0;
i64 iTermOff = 0;
int iTermOff = 0;
while( 1 ){
u32 iVal = 0;
@@ -5465,15 +5464,12 @@ static void fts5DoSecureDelete(
}
nTermIdx = iTermIdx;
if( iTermOff>pTerm->szLeaf ){
FTS5_CORRUPT_IDX(p);
}else{
memmove(&pTerm->p[iTermOff], &pTerm->p[pTerm->szLeaf], nTermIdx);
fts5PutU16(&pTerm->p[2], iTermOff);
fts5DataWrite(p, iId, pTerm->p, iTermOff+nTermIdx);
if( nTermIdx==0 ){
fts5SecureDeleteIdxEntry(p, iSegid, pSeg->iTermLeafPgno);
}
memmove(&pTerm->p[iTermOff], &pTerm->p[pTerm->szLeaf], nTermIdx);
fts5PutU16(&pTerm->p[2], iTermOff);
fts5DataWrite(p, iId, pTerm->p, iTermOff+nTermIdx);
if( nTermIdx==0 ){
fts5SecureDeleteIdxEntry(p, iSegid, pSeg->iTermLeafPgno);
}
}
fts5DataRelease(pTerm);
@@ -5496,9 +5492,7 @@ static void fts5DoSecureDelete(
int iPrevKeyOut = 0;
int iKeyIn = 0;
if( nMove>0 ){
memmove(&aPg[iOff], &aPg[iNextOff], nMove);
}
memmove(&aPg[iOff], &aPg[iNextOff], nMove);
iPgIdx -= nShift;
nPg = iPgIdx;
fts5PutU16(&aPg[2], iPgIdx);
@@ -5936,7 +5930,7 @@ int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){
fts5StructureRelease(pStruct);
pStruct = pNew;
nMin = 1;
nMerge = (nMerge==SMALLEST_INT32 ? LARGEST_INT32 : (nMerge*-1));
nMerge = nMerge*-1;
}
if( pStruct && pStruct->nLevel ){
if( fts5IndexMerge(p, &pStruct, nMerge, nMin) ){
@@ -6418,16 +6412,16 @@ struct Fts5TokenDataMap {
** aMap[] variables.
*/
struct Fts5TokenDataIter {
i64 nMapAlloc; /* Allocated size of aMap[] in entries */
i64 nMap; /* Number of valid entries in aMap[] */
int nMapAlloc; /* Allocated size of aMap[] in entries */
int nMap; /* Number of valid entries in aMap[] */
Fts5TokenDataMap *aMap; /* Array of (rowid+pos -> token) mappings */
/* The following are used for prefix-queries only. */
Fts5Buffer terms;
/* The following are used for other full-token tokendata queries only. */
i64 nIter;
i64 nIterAlloc;
int nIter;
int nIterAlloc;
Fts5PoslistReader *aPoslistReader;
int *aPoslistToIter;
Fts5Iter *apIter[FLEXARRAY];
@@ -6483,11 +6477,11 @@ static void fts5TokendataIterAppendMap(
){
if( p->rc==SQLITE_OK ){
if( pT->nMap==pT->nMapAlloc ){
i64 nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64;
i64 nAlloc = nNew * sizeof(Fts5TokenDataMap);
int nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64;
int nAlloc = nNew * sizeof(Fts5TokenDataMap);
Fts5TokenDataMap *aNew;
aNew = (Fts5TokenDataMap*)sqlite3_realloc64(pT->aMap, nAlloc);
aNew = (Fts5TokenDataMap*)sqlite3_realloc(pT->aMap, nAlloc);
if( aNew==0 ){
p->rc = SQLITE_NOMEM;
return;
@@ -6513,7 +6507,7 @@ static void fts5TokendataIterAppendMap(
*/
static void fts5TokendataIterSortMap(Fts5Index *p, Fts5TokenDataIter *pT){
Fts5TokenDataMap *aTmp = 0;
i64 nByte = pT->nMap * sizeof(Fts5TokenDataMap);
int nByte = pT->nMap * sizeof(Fts5TokenDataMap);
aTmp = (Fts5TokenDataMap*)sqlite3Fts5MallocZero(&p->rc, nByte);
if( aTmp ){
@@ -6835,7 +6829,7 @@ int sqlite3Fts5IndexReinit(Fts5Index *p){
fts5StructureInvalidate(p);
fts5IndexDiscardData(p);
pTmp = &uFts.sFts;
memset(uFts.tmpSpace, 0, sizeof(uFts.tmpSpace));
memset(pTmp, 0, SZ_FTS5STRUCTURE(1));
if( p->pConfig->bContentlessDelete ){
pTmp->nOriginCntr = 1;
}
@@ -7047,10 +7041,9 @@ static Fts5TokenDataIter *fts5AppendTokendataIter(
if( p->rc==SQLITE_OK ){
if( pIn==0 || pIn->nIter==pIn->nIterAlloc ){
i64 nAlloc = pIn ? pIn->nIterAlloc*2 : 16;
i64 nByte = SZ_FTS5TOKENDATAITER(nAlloc+1);
Fts5TokenDataIter *pNew;
pNew = (Fts5TokenDataIter*)sqlite3_realloc64(pIn, nByte);
int nAlloc = pIn ? pIn->nIterAlloc*2 : 16;
int nByte = SZ_FTS5TOKENDATAITER(nAlloc+1);
Fts5TokenDataIter *pNew = (Fts5TokenDataIter*)sqlite3_realloc(pIn, nByte);
if( pNew==0 ){
p->rc = SQLITE_NOMEM;
@@ -7147,8 +7140,8 @@ static void fts5IterSetOutputsTokendata(Fts5Iter *pIter){
/* Ensure the token-mapping is large enough */
if( eDetail==FTS5_DETAIL_FULL && pT->nMapAlloc<(pT->nMap + nByte) ){
i64 nNew = (pT->nMapAlloc + nByte) * 2;
Fts5TokenDataMap *aNew = (Fts5TokenDataMap*)sqlite3_realloc64(
int nNew = (pT->nMapAlloc + nByte) * 2;
Fts5TokenDataMap *aNew = (Fts5TokenDataMap*)sqlite3_realloc(
pT->aMap, nNew*sizeof(Fts5TokenDataMap)
);
if( aNew==0 ){
+27 -73
View File
@@ -511,17 +511,6 @@ static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){
#endif
}
static void fts5SetEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){
#if SQLITE_VERSION_NUMBER>=3008002
#ifndef SQLITE_CORE
if( sqlite3_libversion_number()>=3008002 )
#endif
{
pIdxInfo->estimatedRows = MAX(1, nRow);
}
#endif
}
static int fts5UsePatternMatch(
Fts5Config *pConfig,
struct sqlite3_index_constraint *p
@@ -586,30 +575,19 @@ static int fts5UsePatternMatch(
** a) If a MATCH operator is present, the cost depends on the other
** constraints also present. As follows:
**
** * No other constraints: cost=50000.0
** * One rowid range constraint: cost=37500.0
** * Both rowid range constraints: cost=30000.0
** * An == rowid constraint: cost=25000.0
** * No other constraints: cost=1000.0
** * One rowid range constraint: cost=750.0
** * Both rowid range constraints: cost=500.0
** * An == rowid constraint: cost=100.0
**
** b) Otherwise, if there is no MATCH:
**
** * No other constraints: cost=3000000.0
** * One rowid range constraints: cost=2250000.0
** * Both rowid range constraint: cost=750000.0
** * An == rowid constraint: cost=25.0
** * No other constraints: cost=1000000.0
** * One rowid range constraint: cost=750000.0
** * Both rowid range constraints: cost=250000.0
** * An == rowid constraint: cost=10.0
**
** Costs are not modified by the ORDER BY clause.
**
** The ratios used in case (a) are based on informal results obtained from
** the tool/fts5cost.tcl script. The "MATCH and ==" combination has the
** cost set quite high because the query may be a prefix query. Unless
** there is a prefix index, prefix queries with rowid constraints are much
** more expensive than non-prefix queries with rowid constraints.
**
** The estimated rows returned is set to the cost/40. For simple queries,
** experimental results show that cost/4 might be about right. But for
** more complex queries that use multiple terms the number of rows might
** be far fewer than this. So we compromise and use cost/40.
*/
static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
Fts5Table *pTab = (Fts5Table*)pVTab;
@@ -642,7 +620,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
return SQLITE_ERROR;
}
idxStr = (char*)sqlite3_malloc64((i64)pInfo->nConstraint * 8 + 1);
idxStr = (char*)sqlite3_malloc(pInfo->nConstraint * 8 + 1);
if( idxStr==0 ) return SQLITE_NOMEM;
pInfo->idxStr = idxStr;
pInfo->needToFreeIdxStr = 1;
@@ -668,7 +646,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
nSeenMatch++;
idxStr[iIdxStr++] = 'M';
sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol);
iIdxStr += (int)strlen(&idxStr[iIdxStr]);
idxStr += strlen(&idxStr[iIdxStr]);
assert( idxStr[iIdxStr]=='\0' );
}
pInfo->aConstraintUsage[i].argvIndex = ++iCons;
@@ -687,7 +665,6 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
idxStr[iIdxStr++] = '=';
bSeenEq = 1;
pInfo->aConstraintUsage[i].argvIndex = ++iCons;
pInfo->aConstraintUsage[i].omit = 1;
}
}
}
@@ -735,35 +712,17 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
/* Calculate the estimated cost based on the flags set in idxFlags. */
if( bSeenEq ){
pInfo->estimatedCost = nSeenMatch ? 25000.0 : 25.0;
fts5SetEstimatedRows(pInfo, 1);
fts5SetUniqueFlag(pInfo);
pInfo->estimatedCost = nSeenMatch ? 1000.0 : 10.0;
if( nSeenMatch==0 ) fts5SetUniqueFlag(pInfo);
}else if( bSeenLt && bSeenGt ){
pInfo->estimatedCost = nSeenMatch ? 5000.0 : 250000.0;
}else if( bSeenLt || bSeenGt ){
pInfo->estimatedCost = nSeenMatch ? 7500.0 : 750000.0;
}else{
i64 nEstRows;
if( nSeenMatch ){
if( bSeenLt && bSeenGt ){
pInfo->estimatedCost = 50000.0;
}else if( bSeenLt || bSeenGt ){
pInfo->estimatedCost = 37500.0;
}else{
pInfo->estimatedCost = 50000.0;
}
nEstRows = (i64)(pInfo->estimatedCost / 40.0);
for(i=1; i<nSeenMatch; i++){
pInfo->estimatedCost *= 2.5;
nEstRows = nEstRows / 2;
}
}else{
if( bSeenLt && bSeenGt ){
pInfo->estimatedCost = 750000.0;
}else if( bSeenLt || bSeenGt ){
pInfo->estimatedCost = 2250000.0;
}else{
pInfo->estimatedCost = 3000000.0;
}
nEstRows = (i64)(pInfo->estimatedCost / 4.0);
}
fts5SetEstimatedRows(pInfo, nEstRows);
pInfo->estimatedCost = nSeenMatch ? 10000.0 : 1000000.0;
}
for(i=1; i<nSeenMatch; i++){
pInfo->estimatedCost *= 0.4;
}
pInfo->idxNum = idxFlags;
@@ -962,9 +921,7 @@ static int fts5CursorReseek(Fts5Cursor *pCsr, int *pbSkip){
int bDesc = pCsr->bDesc;
i64 iRowid = sqlite3Fts5ExprRowid(pCsr->pExpr);
rc = sqlite3Fts5ExprFirst(
pCsr->pExpr, pTab->p.pIndex, iRowid, pCsr->iLastRowid, bDesc
);
rc = sqlite3Fts5ExprFirst(pCsr->pExpr, pTab->p.pIndex, iRowid, bDesc);
if( rc==SQLITE_OK && iRowid!=sqlite3Fts5ExprRowid(pCsr->pExpr) ){
*pbSkip = 1;
}
@@ -1136,9 +1093,7 @@ static int fts5CursorFirstSorted(
static int fts5CursorFirst(Fts5FullTable *pTab, Fts5Cursor *pCsr, int bDesc){
int rc;
Fts5Expr *pExpr = pCsr->pExpr;
rc = sqlite3Fts5ExprFirst(
pExpr, pTab->p.pIndex, pCsr->iFirstRowid, pCsr->iLastRowid, bDesc
);
rc = sqlite3Fts5ExprFirst(pExpr, pTab->p.pIndex, pCsr->iFirstRowid, bDesc);
if( sqlite3Fts5ExprEof(pExpr) ){
CsrFlagSet(pCsr, FTS5CSR_EOF);
}
@@ -2106,7 +2061,6 @@ static int fts5UpdateMethod(
}
update_out:
sqlite3Fts5IndexCloseReader(pTab->p.pIndex);
pTab->p.pConfig->pzErrmsg = 0;
return rc;
}
@@ -3647,9 +3601,9 @@ static void fts5LocaleFunc(
sqlite3_value **apArg /* Function arguments */
){
const char *zLocale = 0;
i64 nLocale = 0;
int nLocale = 0;
const char *zText = 0;
i64 nText = 0;
int nText = 0;
assert( nArg==2 );
UNUSED_PARAM(nArg);
@@ -3666,10 +3620,10 @@ static void fts5LocaleFunc(
Fts5Global *p = (Fts5Global*)sqlite3_user_data(pCtx);
u8 *pBlob = 0;
u8 *pCsr = 0;
i64 nBlob = 0;
int nBlob = 0;
nBlob = FTS5_LOCALE_HDR_SIZE + nLocale + 1 + nText;
pBlob = (u8*)sqlite3_malloc64(nBlob);
pBlob = (u8*)sqlite3_malloc(nBlob);
if( pBlob==0 ){
sqlite3_result_error_nomem(pCtx);
return;
@@ -3788,7 +3742,7 @@ static int fts5Init(sqlite3 *db){
int rc;
Fts5Global *pGlobal = 0;
pGlobal = (Fts5Global*)sqlite3_malloc64(sizeof(Fts5Global));
pGlobal = (Fts5Global*)sqlite3_malloc(sizeof(Fts5Global));
if( pGlobal==0 ){
rc = SQLITE_NOMEM;
}else{
+4 -4
View File
@@ -391,7 +391,7 @@ static int SQLITE_TCLAPI xF5tApi(
break;
}
CASE(12, "xSetAuxdata") {
F5tAuxData *pData = (F5tAuxData*)sqlite3_malloc64(sizeof(F5tAuxData));
F5tAuxData *pData = (F5tAuxData*)sqlite3_malloc(sizeof(F5tAuxData));
if( pData==0 ){
Tcl_AppendResult(interp, "out of memory", (char*)0);
return TCL_ERROR;
@@ -780,7 +780,7 @@ static int SQLITE_TCLAPI f5tTokenize(
}
if( nText>0 ){
pCopy = sqlite3_malloc64(nText);
pCopy = sqlite3_malloc(nText);
if( pCopy==0 ){
tokenizer.xDelete(pTok);
Tcl_AppendResult(interp, "error in sqlite3_malloc()", (char*)0);
@@ -1420,7 +1420,7 @@ static int f5tOrigintextCreate(
void *pTokCtx = 0;
int rc = SQLITE_OK;
pTok = (OriginTextTokenizer*)sqlite3_malloc64(sizeof(OriginTextTokenizer));
pTok = (OriginTextTokenizer*)sqlite3_malloc(sizeof(OriginTextTokenizer));
if( pTok==0 ){
rc = SQLITE_NOMEM;
}else if( nArg<1 ){
@@ -1480,7 +1480,7 @@ static int xOriginToken(
int nReq = nToken + 1 + (iEnd-iStart);
if( nReq>p->nBuf ){
sqlite3_free(p->aBuf);
p->aBuf = sqlite3_malloc64(nReq*2);
p->aBuf = sqlite3_malloc(nReq*2);
if( p->aBuf==0 ) return SQLITE_NOMEM;
p->nBuf = nReq*2;
}
+5 -5
View File
@@ -194,7 +194,7 @@ static int fts5tokConnectMethod(
}
if( rc==SQLITE_OK ){
pTab = (Fts5tokTable*)sqlite3_malloc64(sizeof(Fts5tokTable));
pTab = (Fts5tokTable*)sqlite3_malloc(sizeof(Fts5tokTable));
if( pTab==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -275,7 +275,7 @@ static int fts5tokBestIndexMethod(
static int fts5tokOpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
Fts5tokCursor *pCsr;
pCsr = (Fts5tokCursor *)sqlite3_malloc64(sizeof(Fts5tokCursor));
pCsr = (Fts5tokCursor *)sqlite3_malloc(sizeof(Fts5tokCursor));
if( pCsr==0 ){
return SQLITE_NOMEM;
}
@@ -347,7 +347,7 @@ static int fts5tokCb(
if( pCsr->nRow ){
pRow->iPos = pRow[-1].iPos + ((tflags & FTS5_TOKEN_COLOCATED) ? 0 : 1);
}
pRow->zToken = sqlite3_malloc64((sqlite3_int64)nToken+1);
pRow->zToken = sqlite3_malloc(nToken+1);
if( pRow->zToken==0 ) return SQLITE_NOMEM;
memcpy(pRow->zToken, pToken, nToken);
pRow->zToken[nToken] = 0;
@@ -373,8 +373,8 @@ static int fts5tokFilterMethod(
fts5tokResetCursor(pCsr);
if( idxNum==1 ){
const char *zByte = (const char *)sqlite3_value_text(apVal[0]);
sqlite3_int64 nByte = sqlite3_value_bytes(apVal[0]);
pCsr->zInput = sqlite3_malloc64(nByte+1);
int nByte = sqlite3_value_bytes(apVal[0]);
pCsr->zInput = sqlite3_malloc(nByte+1);
if( pCsr->zInput==0 ){
rc = SQLITE_NOMEM;
}else{
+4 -4
View File
@@ -72,7 +72,7 @@ static int fts5AsciiCreate(
if( nArg%2 ){
rc = SQLITE_ERROR;
}else{
p = sqlite3_malloc64(sizeof(AsciiTokenizer));
p = sqlite3_malloc(sizeof(AsciiTokenizer));
if( p==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -367,7 +367,7 @@ static int fts5UnicodeCreate(
if( nArg%2 ){
rc = SQLITE_ERROR;
}else{
p = (Unicode61Tokenizer*)sqlite3_malloc64(sizeof(Unicode61Tokenizer));
p = (Unicode61Tokenizer*)sqlite3_malloc(sizeof(Unicode61Tokenizer));
if( p ){
const char *zCat = "L* N* Co";
int i;
@@ -590,7 +590,7 @@ static int fts5PorterCreate(
zBase = azArg[0];
}
pRet = (PorterTokenizer*)sqlite3_malloc64(sizeof(PorterTokenizer));
pRet = (PorterTokenizer*)sqlite3_malloc(sizeof(PorterTokenizer));
if( pRet ){
memset(pRet, 0, sizeof(PorterTokenizer));
rc = pApi->xFindTokenizer_v2(pApi, zBase, &pUserdata, &pV2);
@@ -1297,7 +1297,7 @@ static int fts5TriCreate(
rc = SQLITE_ERROR;
}else{
int i;
pNew = (TrigramTokenizer*)sqlite3_malloc64(sizeof(*pNew));
pNew = (TrigramTokenizer*)sqlite3_malloc(sizeof(*pNew));
if( pNew==0 ){
rc = SQLITE_NOMEM;
}else{
+1 -12
View File
@@ -396,12 +396,7 @@ static int fts5VocabOpenMethod(
return rc;
}
/*
** Restore cursor pCsr to the state it was in immediately after being
** created by the xOpen() method.
*/
static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){
int nCol = pCsr->pFts5->pConfig->nCol;
pCsr->rowid = 0;
sqlite3Fts5IterClose(pCsr->pIter);
sqlite3Fts5StructureRelease(pCsr->pStruct);
@@ -411,12 +406,6 @@ static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){
pCsr->nLeTerm = -1;
pCsr->zLeTerm = 0;
pCsr->bEof = 0;
pCsr->iCol = 0;
pCsr->iInstPos = 0;
pCsr->iInstOff = 0;
pCsr->colUsed = 0;
memset(pCsr->aCnt, 0, sizeof(i64)*nCol);
memset(pCsr->aDoc, 0, sizeof(i64)*nCol);
}
/*
@@ -666,7 +655,7 @@ static int fts5VocabFilterMethod(
const char *zCopy = (const char *)sqlite3_value_text(pLe);
if( zCopy==0 ) zCopy = "";
pCsr->nLeTerm = sqlite3_value_bytes(pLe);
pCsr->zLeTerm = sqlite3_malloc64((i64)pCsr->nLeTerm+1);
pCsr->zLeTerm = sqlite3_malloc(pCsr->nLeTerm+1);
if( pCsr->zLeTerm==0 ){
rc = SQLITE_NOMEM;
}else{
-33
View File
@@ -294,39 +294,6 @@ do_execsql_test 7.0 {
INSERT INTO x1 VALUES($doc);
}
#-------------------------------------------------------------------------
# Forum post: https://sqlite.org/forum/forumpost/ea4d8c9acb
#
reset_db
do_execsql_test 8.0 {
PRAGMA encoding = 'UTF-16le';
CREATE VIRTUAL TABLE vt0 USING fts5(c0);
}
set v [db one {SELECT x'2a12'}]
do_execsql_test 8.1 {
INSERT INTO vt0 VALUES ($v);
}
do_execsql_test 8.2 {
SELECT quote(c0) FROM vt0
} {X'2A12'}
do_execsql_test 8.3 {
INSERT INTO vt0(vt0) VALUES('integrity-check');
} {}
reset_db
do_execsql_test 8.4 {
PRAGMA encoding = 'UTF-16le';
CREATE VIRTUAL TABLE vt0 USING fts5(c0);
}
do_execsql_test 8.5 {
INSERT INTO vt0 VALUES (x'2a12');
}
do_execsql_test 8.6 {
SELECT quote(c0) FROM vt0
} {X'2A12'}
do_execsql_test 8.7 {
INSERT INTO vt0(vt0) VALUES('integrity-check');
} {}
} ;# foreach_detail_mode...
-362
View File
@@ -16124,367 +16124,5 @@ do_catchsql_test 83.1 {
SELECT * FROM t1('R*R*R*R*R*R*R*R*') WHERE (a,b)<=(current_date,0 BETWEEN 'a'<>11 AND '') ORDER BY rowid DESC;
} {/.*fts5: corruption found/}
#-------------------------------------------------------------------------
reset_db
do_test 84.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
.open --hexdb
| size 53248 pagesize 4096 filename c1a.txt.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 0d .....@ ........
| 32: 00 00 00 02 00 00 00 01 00 00 00 09 00 00 00 04 ................
| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................
| 96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36 ...............6
| 112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 0d 92 00 00 00 00 ...k............
| 3472: 00 00 22 08 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet
| 3488: 32 74 32 0d 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE
| 3504: 20 74 32 28 78 29 56 07 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta
| 3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c
| 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB
| 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k
| 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v)
| 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[.
| 3600: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d
| 3616: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize
| 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't
| 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN
| 3664: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE
| 3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21 Y, sz BLOB)^...!
| 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont
| 3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52 entt1_content.CR
| 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c
| 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG
| 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
| 3776: 63 30 2c 20 63 31 2c 20 63 32 29 69 04 07 17 19 c0, c1, c2)i....
| 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt
| 3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42 1_idx.CREATE TAB
| 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi
| 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P
| 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid
| 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT
| 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t
| 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61 ablet1_datat1_da
| 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE
| 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT
| 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY
| 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8..
| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR
| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB
| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5
| 4032: 28 61 2c 62 2c 63 29 00 00 00 39 00 00 00 00 00 (a,b,c)...9.....
| page 3 offset 8192
| 0: 05 00 00 00 02 0f f1 00 00 00 00 0c 0f fb 0f f1 ................
| 4064: 00 00 0b 01 03 00 1c 81 3a 84 5e 81 3a 81 3a 0a ........:.^.:.:.
| 4080: 0a 00 00 00 0b 84 80 80 80 80 01 00 00 00 0a 0a ................
| page 4 offset 12288
| 0: 0a 00 00 00 01 0f fa 00 0f fa 00 00 00 00 00 00 ................
| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................
| page 7 offset 24576
| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................
| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
| page 10 offset 36864
| 0: 0d 00 00 00 02 0f e2 00 0f e2 0f ef 00 00 00 00 ................
| 4064: 00 00 0b 01 03 00 1c 81 3a 84 5e 81 3a 81 3a 0f ........:.^.:.:.
| 4080: 0a 03 00 24 00 00 00 00 01 01 02 00 01 01 01 09 ...$............
| page 11 offset 40960
| 0: 0d 00 00 00 01 00 22 00 00 22 00 00 00 00 00 00 ................
| 32: 00 00 9f 56 84 80 80 80 80 01 04 00 bf 30 00 00 ...V.........0..
| 48: 0f 58 02 30 30 19 02 05 01 02 05 01 02 05 16 02 .X.00...........
| 64: 05 01 02 05 01 02 05 61 02 05 01 02 05 01 02 05 .......a........
| 80: 13 02 05 01 02 05 01 02 05 0d 02 03 01 02 03 01 ................
| 96: 02 03 02 09 78 66 66 66 66 66 66 66 65 81 17 02 ....xfffffffe...
| 112: 05 01 02 05 01 02 05 01 01 31 04 02 04 01 02 04 .........1......
| 128: 01 02 04 01 02 05 01 02 05 01 02 05 0d 02 06 01 ................
| 144: 02 06 01 02 06 02 01 30 79 02 04 01 02 04 01 02 .......0y.......
| 160: 04 03 02 30 30 2b 02 05 01 02 05 01 02 05 58 02 ...00+........X.
| 176: 05 01 02 05 01 02 05 01 02 05 01 02 05 01 02 05 ................
| 192: 16 02 05 01 02 05 01 02 05 05 06 30 30 30 30 30 ...........00000
| 208: 30 81 0b 02 04 01 02 04 01 02 04 10 02 05 01 02 0...............
| 224: 05 01 02 05 03 02 32 34 76 02 05 01 02 05 01 02 ......24v.......
| 240: 05 02 01 38 07 02 04 01 02 04 01 02 04 01 01 32 ...8...........2
| 256: 28 02 04 01 02 04 01 02 04 04 02 05 01 02 05 01 (...............
| 272: 02 05 02 01 30 1f 02 05 01 02 05 01 02 05 03 02 ....0...........
| 288: 30 30 10 02 05 01 02 05 01 02 05 6a 02 04 01 02 00.........j....
| 304: 04 01 02 04 02 08 35 30 30 30 30 30 30 30 81 26 ......50000000.&
| 320: 02 05 01 02 05 01 02 05 01 01 33 07 02 06 01 02 ..........3.....
| 336: 06 01 02 06 81 2c 02 04 01 02 04 01 02 04 02 04 .....,..........
| 352: 32 37 36 36 81 23 02 05 01 02 05 01 02 05 01 01 2766.#..........
| 368: 34 13 02 05 01 02 05 01 02 05 02 03 30 39 36 1c 4...........096.
| 384: 02 05 01 02 05 01 02 05 07 02 05 01 02 05 01 02 ................
| 400: 05 01 03 35 30 30 7f 02 05 01 02 05 01 02 05 04 ...500..........
| 416: 02 30 30 81 0e 02 06 01 02 06 01 02 06 06 03 30 .00............0
| 432: 30 30 81 11 02 04 01 02 04 01 02 04 01 05 36 35 00............65
| 448: 35 33 36 81 1a 02 05 01 02 05 01 02 05 01 04 38 536............8
| 464: 31 39 32 81 02 02 06 01 02 06 01 02 06 01 05 61 192............a
| 480: 6c 6c 6f 77 01 02 02 01 02 02 01 02 02 02 02 72 llow...........r
| 496: 67 81 08 02 04 01 02 04 01 02 04 02 05 74 6f 6d g............tom
| 512: 69 63 04 02 02 01 02 02 01 02 02 03 06 74 61 63 ic...........tac
| 528: 68 65 64 79 02 03 01 02 03 01 02 03 02 0d 75 74 hedy..........ut
| 544: 6f 63 68 65 63 6b 70 6f 69 6e 74 2b 02 04 01 02 ocheckpoint+....
| 560: 04 01 02 04 05 06 76 61 63 75 75 6d 0d 02 03 01 ......vacuum....
| 576: 02 03 01 02 03 01 06 62 69 6e 61 72 79 03 06 01 .......binary...
| 592: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 608: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 624: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
| 640: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 656: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 672: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 688: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 704: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
| 720: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 736: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 752: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 768: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 784: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
| 800: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 816: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 832: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 848: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 864: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
| 880: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 896: 01 02 02 02 07 79 74 65 63 6f 64 65 37 02 03 01 .....ytecode7...
| 912: 02 03 01 02 03 01 05 63 61 63 68 65 10 02 03 01 .......cache....
| 928: 02 03 01 01 03 02 04 6c 61 6e 67 07 02 03 01 02 .......lang.....
| 944: 03 01 02 03 02 05 6f 6c 75 6d 6e 7c 02 03 01 02 ......olumn|....
| 960: 03 01 02 03 03 06 6d 6d 65 6e 74 73 43 02 04 01 ......mmentsC...
| 976: 02 04 01 02 04 04 05 70 69 6c 65 72 07 02 02 01 .......piler....
| 992: 02 02 01 02 02 05 04 6f 75 6e 64 7f 02 03 01 02 .......ound.....
| 1008: 03 01 02 03 03 03 75 6e 74 81 17 02 04 01 02 04 ......unt.......
| 1024: 01 02 04 02 05 75 72 73 6f 72 3a 02 03 01 02 03 .....ursor:.....
| 1040: 01 02 03 01 06 64 62 70 61 67 65 3d 02 03 01 02 .....dbpage=....
| 1056: 03 01 02 03 03 04 73 74 61 74 40 02 03 01 02 03 ......stat@.....
| 1072: 01 02 03 02 04 65 62 75 67 0a 02 02 01 02 02 01 .....ebug.......
| 1088: 02 02 03 05 66 61 75 6c 74 0d 02 02 01 02 02 01 ....fault.......
| 1104: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
| 1120: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
| 1136: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
| 1152: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
| 1168: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
| 1184: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
| 1200: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 4f 02 ..............O.
| 1216: 03 01 02 03 01 02 03 03 03 70 74 68 81 05 02 04 .........pth....
| 1232: 01 02 04 01 02 04 19 02 04 01 02 04 01 02 04 02 ................
| 1248: 05 69 72 65 63 74 34 02 02 01 02 02 01 02 02 01 .irect4.........
| 1264: 06 65 6e 61 62 6c 65 37 02 02 01 02 02 01 02 02 .enable7........
| 1280: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
| 1296: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
| 1312: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
| 1328: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
| 1344: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
| 1360: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
| 1376: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
| 1392: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
| 1408: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
| 1424: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
| 1440: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
| 1456: 02 01 02 02 02 06 78 70 6c 61 69 6e 43 02 03 01 ......xplainC...
| 1472: 02 03 01 02 03 04 01 72 81 05 02 03 01 02 03 01 .......r........
| 1488: 02 03 03 07 74 65 6e 73 69 6f 6e 81 2f 02 04 01 ....tension./...
| 1504: 02 04 01 02 04 01 04 66 69 6c 65 13 02 03 01 02 .......file.....
| 1520: 03 01 02 03 02 05 6f 72 6d 61 74 13 02 04 01 02 ......ormat.....
| 1536: 04 01 02 04 02 03 74 73 33 46 02 03 01 02 03 01 ......ts3F......
| 1552: 02 03 01 02 03 01 02 03 01 02 03 04 01 34 4c 02 .............4L.
| 1568: 03 01 02 03 01 02 03 04 01 35 4f 02 03 01 02 03 .........5O.....
| 1584: 01 02 03 02 03 75 6e 63 5e 02 05 01 02 05 01 02 .....unc^.......
| 1600: 05 05 04 74 69 6f 6e 73 02 05 01 02 05 01 02 05 ...tions........
| 1616: 13 02 03 01 02 03 01 02 03 09 01 73 55 02 04 01 ...........sU...
| 1632: 02 04 01 02 04 01 07 67 65 6f 70 6f 6c 79 52 02 .......geopolyR.
| 1648: 03 01 02 03 01 02 03 01 05 68 69 6e 74 73 3a 02 .........hints:.
| 1664: 04 01 02 04 01 02 04 02 03 6f 6f 6b 61 02 04 01 .........ooka...
| 1680: 02 04 01 02 04 01 02 69 6e 01 02 04 01 02 04 01 .......in.......
| 1696: 02 04 03 04 69 74 73 7a 1f 02 04 01 02 04 01 02 ....itsz........
| 1712: 04 03 08 74 72 69 6e 73 69 63 73 04 02 03 01 02 ...trinsics.....
| 1728: 03 01 02 03 01 07 6a 6f 75 72 6e 61 6c 16 02 03 ......journal...
| 1744: 01 02 03 01 02 03 01 06 6c 65 6e 67 74 68 81 0b ........length..
| 1760: 02 03 01 02 03 01 02 03 01 02 05 01 02 05 01 02 ................
| 1776: 05 0d 02 04 01 02 04 01 02 04 02 03 69 6b 65 81 ............ike.
| 1792: 0e 02 03 01 02 03 01 02 03 03 03 6d 69 74 16 02 ...........mit..
| 1808: 05 01 02 05 01 02 05 5e 02 04 01 02 04 01 02 04 .......^........
| 1824: 02 03 6f 61 64 81 2f 02 03 01 02 03 01 02 03 01 ..oad./.........
| 1840: 06 6d 61 6c 6c 6f 63 76 02 02 01 02 02 01 02 02 .mallocv........
| 1856: 3a 02 03 01 02 03 01 02 03 03 02 74 68 55 02 03 :..........thU..
| 1872: 01 02 03 01 02 03 03 01 78 79 02 02 01 02 02 01 ........xy......
| 1888: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
| 1904: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
| 1920: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
| 1936: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
| 1952: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
| 1968: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
| 1984: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
| 2000: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
| 2016: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
| 2032: 02 02 02 05 65 6d 6f 72 79 81 11 02 03 01 02 03 ....emory.......
| 2048: 01 02 03 04 04 73 79 73 35 58 02 03 01 02 03 01 .....sys5X......
| 2064: 02 03 02 03 6d 61 70 19 02 03 01 02 03 01 02 03 ....map.........
| 2080: 79 02 03 01 02 03 01 02 03 02 04 75 74 65 78 81 y..........utex.
| 2096: 2c 02 02 01 02 02 01 02 02 01 06 6e 6f 63 61 73 ,..........nocas
| 2112: 65 02 06 01 02 02 03 06 01 02 02 03 06 01 02 02 e...............
| 2128: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
| 2144: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 2160: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 2176: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 2192: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 2208: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
| 2224: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 2240: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 2256: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 2272: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 2288: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
| 2304: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 2320: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 2336: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 2352: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 2368: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
| 2384: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 2400: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 2416: 02 02 03 06 01 02 02 03 07 72 6d 61 6c 69 7a 65 .........rmalize
| 2432: 5b 02 03 01 02 03 01 02 03 02 05 75 6d 62 65 72 [..........umber
| 2448: 81 23 02 04 01 02 04 01 02 04 01 06 6f 66 66 73 .#..........offs
| 2464: 65 74 5e 02 03 01 02 03 01 02 03 02 03 6d 69 74 et^..........mit
| 2480: 81 2c 02 03 01 02 03 01 02 03 01 02 02 01 02 02 .,..............
| 2496: 01 02 02 02 01 70 81 26 02 04 01 02 04 01 02 04 .....p.&........
| 2512: 02 07 76 65 72 66 6c 6f 77 34 02 03 01 02 03 01 ..verflow4......
| 2528: 02 03 01 04 70 61 67 65 1c 02 03 01 02 03 01 02 ....page........
| 2544: 03 64 02 04 01 02 04 01 02 04 13 02 03 01 02 03 .d..............
| 2560: 01 02 03 01 02 03 01 02 03 01 02 03 03 09 72 65 ..............re
| 2576: 6e 74 68 65 73 69 73 49 02 04 01 02 04 01 02 04 nthesisI........
| 2592: 03 05 74 74 65 72 6e 81 0e 02 04 01 02 04 01 02 ..ttern.........
| 2608: 04 02 05 63 61 63 68 65 1f 02 03 01 02 03 01 02 ...cache........
| 2624: 03 02 08 72 65 75 70 64 61 74 65 61 02 03 01 02 ...reupdatea....
| 2640: 03 01 02 03 01 04 72 65 61 64 34 02 04 01 02 04 ......read4.....
| 2656: 01 02 04 03 07 63 75 72 73 69 76 65 22 02 03 01 .....cursive....
| 2672: 02 03 01 02 03 02 04 6f 77 69 64 01 02 03 01 02 .......owid.....
| 2688: 03 01 02 03 02 04 74 72 65 65 64 02 03 01 02 03 ......treed.....
| 2704: 01 02 03 04 02 69 6d 01 06 01 02 02 03 06 01 02 .....im.........
| 2720: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 2736: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
| 2752: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 2768: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 2784: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 2800: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 2816: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
| 2832: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 2848: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 2864: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 2880: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 2896: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
| 2912: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 2928: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 2944: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 2960: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 2976: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
| 2992: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 3008: 01 02 02 03 06 01 02 02 03 06 01 02 02 01 0a 73 ...............s
| 3024: 63 61 6e 73 74 61 74 75 73 70 02 04 01 02 04 01 canstatusp......
| 3040: 02 04 02 05 65 63 74 6f 72 25 02 03 01 02 03 01 ....ector%......
| 3056: 02 03 03 04 6c 65 63 74 7f 02 04 01 02 04 01 02 ....lect........
| 3072: 04 03 05 73 73 69 6f 6e 67 02 03 01 02 03 01 02 ...ssiong.......
| 3088: 03 02 03 69 7a 65 10 02 04 01 02 04 01 02 04 04 ...ize..........
| 3104: 02 04 01 02 04 01 02 04 01 02 04 01 02 04 01 02 ................
| 3120: 04 01 02 04 01 02 04 01 02 04 07 02 04 01 02 04 ................
| 3136: 01 02 04 5b 02 05 01 02 05 01 02 05 10 02 04 01 ...[............
| 3152: 02 04 01 02 04 04 02 04 01 02 04 01 02 04 02 03 ................
| 3168: 6f 66 74 76 02 03 01 02 03 01 02 03 02 02 71 6c oftv..........ql
| 3184: 5e 02 04 01 02 04 01 02 04 13 02 04 01 02 04 01 ^...............
| 3200: 02 04 28 02 03 01 02 03 01 02 03 02 04 74 61 74 ..(..........tat
| 3216: 34 6a 02 03 01 02 03 01 02 03 03 02 6d 74 70 02 4j..........mtp.
| 3232: 03 01 02 03 01 02 03 05 04 76 74 61 62 6d 02 03 .........vtabm..
| 3248: 01 02 03 01 02 03 03 03 6f 72 65 81 35 02 03 01 ........ore.5...
| 3264: 02 03 01 02 03 02 0a 79 6e 63 68 72 6f 6e 6f 75 .......ynchronou
| 3280: 73 28 02 03 01 02 03 01 02 03 04 02 04 01 02 04 s(..............
| 3296: 01 02 04 03 04 73 74 65 6d 81 32 02 02 01 02 02 .....stem.2.....
| 3312: 01 02 02 01 04 74 65 6d 70 81 35 02 02 01 02 02 .....temp.5.....
| 3328: 01 02 02 02 06 68 72 65 61 64 73 31 02 04 01 02 .....hreads1....
| 3344: 04 01 02 04 76 02 04 01 02 04 01 02 04 08 03 61 ....v..........a
| 3360: 66 65 81 38 02 02 01 02 02 01 02 02 02 06 72 69 fe.8..........ri
| 3376: 67 67 65 72 81 20 02 03 01 02 03 01 02 03 08 01 gger. ..........
| 3392: 73 22 02 04 01 02 04 01 02 04 01 07 75 6e 6b 6e s...........unkn
| 3408: 6f 77 6e 73 02 03 01 02 03 01 02 03 01 08 76 61 owns..........va
| 3424: 72 69 61 62 6c 65 81 23 02 03 01 02 03 01 02 03 riable.#........
| 3440: 02 03 64 62 65 81 26 02 03 01 02 03 01 02 03 02 ..dbe.&.........
| 3456: 03 69 65 77 01 02 05 01 02 05 01 02 05 02 03 74 .iew...........t
| 3472: 61 62 37 02 04 01 02 04 01 02 04 04 02 04 01 02 ab7.............
| 3488: 04 01 02 04 01 02 04 01 02 04 01 02 04 01 03 77 ...............w
| 3504: 61 6c 2b 02 03 01 02 03 01 02 03 01 02 03 01 02 al+.............
| 3520: 03 01 02 03 02 05 6f 72 6b 65 72 31 02 03 01 02 ......orker1....
| 3536: 03 01 02 03 76 02 03 01 02 03 01 02 03 01 01 78 ....v..........x
| 3552: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3568: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 3584: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 3600: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 3616: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 3632: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3648: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 3664: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 3680: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 3696: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 3712: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3728: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 3744: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 3760: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 3776: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 3792: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3808: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 3824: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 3840: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 3856: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 3872: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3888: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 3904: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 3920: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 3936: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 3952: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3968: 06 01 01 02 01 06 04 30 15 1e 0c 28 1b 0d 0c 15 .......0...(....
| 3984: 0c 16 14 16 10 0c 17 0e 0e 0f 11 10 10 0e 10 11 ................
| 4000: 18 11 82 3e 12 10 0f 10 11 10 0f 0f 10 11 0f 0f ...>............
| 4016: 81 05 18 10 81 45 11 0d 13 0f 10 17 0c 0c 0e 18 .....E..........
| 4032: 0c 12 10 0e 0d 0f 13 12 24 0f 17 0f 1a 0d 81 1c ........$.......
| 4048: 11 0f 17 10 82 3e 12 11 11 18 0d 12 2a 14 11 10 .....>......*...
| 4064: 13 0f 12 0f 0f 82 3a 15 10 0f 10 4d 0e 1f 0f 0d ......:....M....
| 4080: 0f 0f 1e 10 10 1a 0f 12 0c 12 14 0f 0e 20 17 19 ............. ..
| page 12 offset 45056
| 0: 0d 00 00 00 01 0d f4 00 0d f4 00 00 00 00 00 00 ................
| 3568: 00 00 00 00 84 04 84 80 80 80 80 02 04 00 88 0c ................
| 3584: 00 07 02 00 01 01 02 56 06 01 01 02 01 06 01 01 .......V........
| 3600: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 3616: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3632: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 3648: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 3664: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 3680: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 3696: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3712: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 3728: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 3744: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 3760: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 3776: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3792: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 3808: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 3824: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 3840: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 3856: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3872: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 3888: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 3904: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 3920: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 3936: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3952: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 3968: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 3984: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 4000: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 4016: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 4032: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 4048: 52 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 R...............
| 4064: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 4080: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| end c1a.txt.db
}]} {}
do_catchsql_test 84.1 {
SELECT * FROM t1('R*R*x') ORDER BY rowid DESC;
} {1 {fts5: corruption found reading blob 137438953475 from table "t1"}}
sqlite3_fts5_may_be_corrupt 0
finish_test
File diff suppressed because one or more lines are too long
-53
View File
@@ -1,53 +0,0 @@
# 2025 October 13
#
# 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 test is focused on really large position lists. Those that require
# 4 or 5 byte position-list size varints. Because of the amount of memory
# required, these tests only run on 64-bit platforms.
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5corruptbig
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
if { $tcl_platform(wordSize)<8 } {
finish_test
return
}
if { $SQLITE_MAX_LENGTH!=0x7FFFFFFF } {
finish_test
return
}
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(x);
}
do_execsql_test 1.1 {
UPDATE t1_data SET block = zeroblob(2147483640) WHERE id=10;
}
do_execsql_test 1.2 {
SELECT id, length(block) FROM t1_data
} {1 0 10 2147483640}
do_catchsql_test 1.3 {
SELECT * FROM t1('abc')
} {1 {out of memory}}
finish_test
+3
View File
@@ -379,6 +379,9 @@ do_execsql_test 12.2 {
db close
sqlite3 db test.db -readonly 1
explain_i {
PRAGMA integrity_check
}
do_execsql_test 12.3 {
PRAGMA integrity_check
} {ok}
-17
View File
@@ -64,21 +64,4 @@ foreach {tn sql} {
}
}
#-------------------------------------------------------------------------
# Verify that https://sqlite.org/forum/forumpost/95413eb410 has been
# fixed.
#
reset_db
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE f1 USING fts5(x);
BEGIN TRANSACTION;
INSERT INTO f1(x) VALUES('abc def ghi');
}
do_test 2.1 {
sqlite3_interrupt db
} {}
do_execsql_test 2.2 {
ROLLBACK
}
finish_test
-78
View File
@@ -1,78 +0,0 @@
# 2014 June 17
#
# 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 fts5join
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE vt USING fts5(x);
INSERT INTO vt VALUES('abc');
INSERT INTO vt VALUES('xyz');
CREATE TABLE t1(a INTEGER PRIMARY KEY, b TIMESTAMP);
INSERT INTO t1 VALUES(1, 1), (2, 2);
CREATE INDEX i1 ON t1(b);
}
# set sqlite_where_trace [expr 0xFFF]
do_eqp_test 1.1 {
SELECT * FROM vt, t1 WHERE vt.rowid = t1.rowid ORDER BY t1.rowid;
} {
QUERY PLAN
|--SCAN t1
`--SCAN vt VIRTUAL TABLE INDEX 0:=
}
do_eqp_test 1.2 {
SELECT * FROM vt, t1 WHERE vt.rowid = t1.rowid AND b>? ORDER BY b LIMIT 10
} {
QUERY PLAN
|--SEARCH t1 USING COVERING INDEX i1 (b>?)
`--SCAN vt VIRTUAL TABLE INDEX 0:=
}
do_eqp_test 1.3 {
SELECT * FROM vt, t1 WHERE vt.rowid = t1.rowid AND b>?
} {
QUERY PLAN
|--SEARCH t1 USING COVERING INDEX i1 (b>?)
`--SCAN vt VIRTUAL TABLE INDEX 0:=
}
do_eqp_test 1.4 {
SELECT * FROM vt, t1 WHERE vt.rowid = t1.rowid ORDER BY b
} {
QUERY PLAN
|--SCAN t1 USING COVERING INDEX i1
`--SCAN vt VIRTUAL TABLE INDEX 0:=
}
do_eqp_test 1.5 {
SELECT * FROM vt, t1
WHERE vt.rowid = t1.rowid AND vt MATCH ? AND b = ?
} {
QUERY PLAN
|--SCAN vt VIRTUAL TABLE INDEX 0:M1
`--SEARCH t1 USING INTEGER PRIMARY KEY (rowid=?)
}
finish_test
-16
View File
@@ -238,22 +238,6 @@ do_execsql_test 6.3 {
INSERT INTO g1(g1) VALUES('integrity-check');
}
#--------------------------------------------------------------------------
# Check that passing -2147483648 as the parameter to a merge command
# does not cause a signed integer overflow error.
#
reset_db
do_execsql_test 7.0 {
CREATE VIRTUAL TABLE f1 USING fts5(a);
}
do_execsql_test 7.1 {
INSERT INTO f1 VALUES('one two three');
INSERT INTO f1 VALUES('four five six');
INSERT INTO f1 VALUES('seven eight nine');
}
do_execsql_test 7.2 {
INSERT INTO f1(f1, rank) VALUES('merge', -2147483648);
}
finish_test
-12
View File
@@ -685,17 +685,5 @@ do_execsql_test 26.1 {
COMMIT;
}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 27.0 {
CREATE VIRTUAL TABLE ft1 USING fts5(a, b);
INSERT INTO ft1(rowid, a, b) VALUES(3, '3', '3');
}
do_execsql_test 27.1 {
SELECT * FROM ft1 WHERE rowid=3 AND b MATCH 'hello';
}
finish_test
+4 -4
View File
@@ -38,15 +38,15 @@ foreach {tn sql uses} {
1.2 { DELETE FROM ft WHERE rowid=? } 0
1.3 { DELETE FROM ft WHERE rowid=? } 0
1.4 { DELETE FROM ft WHERE ft MATCH '1' } 1
1.5 { DELETE FROM ft WHERE ft MATCH '1' AND rowid=? } 0
1.6 { DELETE FROM ft WHERE ft MATCH '1' AND rowid=? } 0
1.5 { DELETE FROM ft WHERE ft MATCH '1' AND rowid=? } 1
1.6 { DELETE FROM ft WHERE ft MATCH '1' AND rowid=? } 1
2.1 { UPDATE ft SET content='a b c' } 1
2.2 { UPDATE ft SET content='a b c' WHERE rowid=? } 0
2.3 { UPDATE ft SET content='a b c' WHERE rowid=? } 0
2.4 { UPDATE ft SET content='a b c' WHERE ft MATCH '1' } 1
2.5 { UPDATE ft SET content='a b c' WHERE ft MATCH '1' AND rowid=? } 0
2.6 { UPDATE ft SET content='a b c' WHERE ft MATCH '1' AND rowid=? } 0
2.5 { UPDATE ft SET content='a b c' WHERE ft MATCH '1' AND rowid=? } 1
2.6 { UPDATE ft SET content='a b c' WHERE ft MATCH '1' AND rowid=? } 1
} {
do_test 1.$tn { sql_uses_stmt db $sql } $uses
}
-22
View File
@@ -305,28 +305,6 @@ do_catchsql_test 6.2 {
sqlite3_fts5_may_be_corrupt 0
#-------------------------------------------------------------------------
reset_db
do_execsql_test 7.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, b);
CREATE VIRTUAL TABLE v1 USING fts5vocab(t1, col);
INSERT INTO t1 VALUES('xx', 'xx');
CREATE TABLE x1(t);
INSERT INTO x1 VALUES('xx');
INSERT INTO x1 VALUES('xx');
SELECT term, col FROM v1;
} {
xx a xx b
}
do_execsql_test 7.1 {
SELECT * FROM x1 WHERE 'a'=(SELECT col FROM v1 WHERE term=t)
} {xx xx}
finish_test
-153
View File
@@ -1,153 +0,0 @@
#
# 2026 March 20
#
# 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 script extracts the documentation for the API used by fts5 auxiliary
# functions from header file fts5.h. It outputs html text on stdout that
# is included in the documentation on the web.
#
sqlite3 db fts5cost.db
# Create an IPK table with 1,000,000 entries. Short records.
#
set res [list [catch { db eval {SELECT count(*) FROM t1} } msg] $msg]
if {$res!="0 1000000"} {
db eval {
PRAGMA mmap_size = 1000000000; -- 1GB
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT);
WITH s(i) AS (
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1_000_000
)
INSERT INTO t1 SELECT i, hex(randomblob(8)) FROM s;
}
}
# Create an FTS5 table with 1,000,000 entries. Each row contains a single
# column containing a document of 100 terms chosen pseudo-randomly from
# a vocabularly of 2000.
set res [list [catch { db eval {SELECT count(*) FROM f1} } msg] $msg]
if {$res!="0 1000000"} {
set nVocab 2000
set nTerm 100
db eval {
BEGIN;
DROP TABLE IF EXISTS vocab1;
CREATE TABLE vocab1(w);
}
for {set ii 0} {$ii<$nVocab} {incr ii} {
set word [format %06x [expr {int(abs(rand()) * 0xFFFFFF)}]]
db eval { INSERT INTO vocab1 VALUES($word) }
lappend lVocab $word
}
db func doc doc
proc doc {} {
for {set ii 0} {$ii<$::nTerm} {incr ii} {
lappend ret [lindex $::lVocab [expr int(abs(rand())*$::nVocab)]]
}
set ret
}
db eval {
DROP TABLE IF EXISTS f1;
CREATE VIRTUAL TABLE f1 USING fts5(x);
WITH s(i) AS (
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1_000_000
)
INSERT INTO f1(rowid, x) SELECT i, doc() FROM s;
COMMIT;
}
} else {
set lVocab [db eval { SELECT * FROM vocab1 }]
set nVocab [llength $lVocab]
}
proc rowid_query {n} {
set rowid 654
for {set ii 0} {$ii<$n} {incr ii} {
db eval { SELECT b FROM t1 WHERE a = $rowid }
set rowid [expr {($rowid + 7717) % 1000000}]
}
}
proc rowid_query_fts {n} {
set rowid 654
for {set ii 0} {$ii<$n} {incr ii} {
db eval { SELECT * FROM f1 WHERE rowid = $rowid }
set rowid [expr {($rowid + 7717) % 1000000}]
}
}
proc match_query_fts {n} {
set idx 654
for {set ii 0} {$ii<$n} {incr ii} {
set match [lrange $::lVocab $idx $idx+1]
db eval { SELECT * FROM f1($match) }
set idx [expr {($idx + 7717) % $::nVocab}]
}
}
proc prefix_query_fts {n} {
set idx 654
for {set ii 0} {$ii<$n} {incr ii} {
set match "[lindex $::lVocab $idx]*"
db eval { SELECT * FROM f1($match) }
set idx [expr {($idx + 7717) % $::nVocab}]
}
}
proc match_rowid_query_fts {n} {
set idx 654
for {set ii 0} {$ii<$n} {incr ii} {
set match "[lindex $::lVocab $idx]"
db eval { SELECT * FROM f1($match) WHERE rowid=500000 }
set idx [expr {($idx + 7717) % $::nVocab}]
}
}
proc prefix_rowid_query_fts {n} {
set idx 654
for {set ii 0} {$ii<$n} {incr ii} {
set match "[lindex $::lVocab $idx]*"
db eval { SELECT * FROM f1($match) WHERE rowid=500000 }
set idx [expr {($idx + 7717) % $::nVocab}]
}
}
proc mytime {cmd div} {
set tm [time $cmd]
expr {[lindex $tm 0] / $div}
}
#set us [mytime { match_rowid_query_fts 1000 } 1000]
#puts "1000 match/rowid queries on fts5 table: ${us} per query"
set us [mytime { prefix_rowid_query_fts 1000 } 1000]
puts "1000 prefix/rowid queries on fts5 table: ${us} per query"
set us [mytime { match_query_fts 10 } 10]
puts "10 match queries on fts5 table: ${us} per query"
set us [mytime { prefix_query_fts 10 } 10]
puts "10 prefix queries on fts5 table: ${us} per query"
set us [mytime { prefix_rowid_query_fts 1000 } 1000]
puts "1000 prefix/rowid queries on fts5 table: ${us} per query"
set us [mytime { rowid_query 10000 } 10000]
puts "10000 by-rowid queries on normal table: ${us} per query"
set us [mytime { rowid_query_fts 10000 } 10000]
puts "10000 by-rowid queries on fts5 table: ${us} per query"
-2
View File
@@ -139,7 +139,6 @@ do_test 2.3 {
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 0 0
db eval {
PRAGMA writable_schema=on;
DELETE FROM imp1 WHERE rowid=1;
DELETE FROM imp2 WHERE rowid=2;
}
@@ -175,7 +174,6 @@ do_test 3.2 {
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 0 0
db eval {
PRAGMA writable_schema=on;
DELETE FROM imp1 WHERE a=5;
}
execsql_pp {
-1
View File
@@ -29,7 +29,6 @@ do_execsql_test 1.0 {
proc imposter_edit {obj create sql} {
sqlite3 xdb test.db
set pgno [xdb one {SELECT rootpage FROM sqlite_schema WHERE name=$obj}]
xdb eval {PRAGMA Writable_schema=ON}
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER xdb main 1 $pgno
xdb eval $create
+1 -2
View File
@@ -160,7 +160,6 @@ static char *intckMprintf(sqlite3_intck *p, const char *zFmt, ...){
sqlite3_free(zRet);
zRet = 0;
}
va_end(ap);
return zRet;
}
@@ -319,7 +318,7 @@ static int intckGetToken(const char *z){
char c = z[0];
int iRet = 1;
if( c=='\'' || c=='"' || c=='`' ){
while( z[iRet] ){
while( 1 ){
if( z[iRet]==c ){
iRet++;
if( z[iRet]!=c ) break;
+16 -19
View File
@@ -13,14 +13,11 @@ Technical support is available in the forum:
<https://sqlite.org/forum>
> **FOREWARNING:** the JNI subproject is experimental and subject to
any number of changes. This API is "feature-complete", with only a
few difficult-to-reach corners of the C API not represented here,
but it is not a supported deliverable of the project so does not
have same backward compatibility guarantees which the C APIs
do. That said: the [C-style API](#1to1ish) is especially resistent
to compatibility breakage because it's designed to be as close to
the C API as feasible.
> **FOREWARNING:** this subproject is very much in development and
subject to any number of changes. Please do not rely on any
information about its API until this disclaimer is removed. The JNI
bindings released with version 3.43 are a "tech preview." Once
finalized, strong backward compatibility guarantees will apply.
Project goals/requirements:
@@ -165,13 +162,11 @@ or propagate exceptions and must return error information (if any) via
result codes or `null`. The only cases where the C-style APIs may
throw is through client-side misuse, e.g. passing in a null where it
may cause a `NullPointerException`. The APIs clearly mark function
parameters which should not be null, and it internally uses the
`SQLITE_API_ARMOR` mechanism to help product against such misuse. Some
C-style APIs explicitly accept `null` as a no-op for usability's sake,
and some of the JNI APIs deliberately return an error code, instead of
segfaulting, when passed a `null`. There are no known cases where it
will misuse memory if passed a `null` or out-of-range value from
client code.
parameters which should not be null, but does not generally actively
defend itself against such misuse. Some C-style APIs explicitly accept
`null` as a no-op for usability's sake, and some of the JNI APIs
deliberately return an error code, instead of segfaulting, when passed
a `null`.
Client-defined callbacks _must never throw exceptions_ unless _very
explicitly documented_ as being throw-safe. Exceptions are generally
@@ -199,8 +194,7 @@ Some constructs, when modelled 1-to-1 from C to Java, are unduly
clumsy to work with in Java because they try to shoehorn C's way of
doing certain things into Java's wildly different ways. The following
subsections cover those, starting with a verbose explanation and
demonstration of where such changes are "really necessary" for
usability's sake...
demonstration of where such changes are "really necessary"...
### Custom Collations
@@ -292,9 +286,12 @@ binding. The Java API has only one core function-registration function:
```java
int sqlite3_create_function(sqlite3 db, String funcName, int nArgs,
int flags, SQLFunction func);
int encoding, SQLFunction func);
```
> Design question: does the encoding argument serve any purpose in
Java? That's as-yet undetermined. If not, it will be removed.
`SQLFunction` is not used directly, but is instead instantiated via
one of its three subclasses:
@@ -316,4 +313,4 @@ in-flux nature of this API.
Various APIs which accept callbacks, e.g. `sqlite3_trace_v2()` and
`sqlite3_update_hook()`, use interfaces similar to those shown above.
Despite the changes in signature, the JNI layer makes every effort to
provide the same semantics as the C API documentation describes.
provide the same semantics as the C API documentation suggests.
+55 -64
View File
@@ -133,9 +133,11 @@
** Which sqlite3.c we're using needs to be configurable to enable
** building against a custom copy, e.g. the SEE variant. We have to
** include sqlite3.c, as opposed to sqlite3.h, in order to get access
** to some internal details like SQLITE_MAX_... and friends, and keep
** those consistent with this build. This increases the rebuild time
** considerably, however.
** to some internal details like SQLITE_MAX_... and friends. This
** increases the rebuild time considerably but we need this in order
** to access some internal functionality and keep the to-Java-exported
** values of SQLITE_MAX_... and SQLITE_LIMIT_... in sync with the C
** build.
*/
#ifndef SQLITE_C
# define SQLITE_C sqlite3.c
@@ -166,10 +168,6 @@
** Creates a verbose JNI function name. Suffix must be
** the JNI-mangled form of the function's name, minus the
** prefix seen in this macro.
**
** If you get java.lang.UnsatisfiedLinkError when calling newly-added
** native bindings, be sure that the mangled name is correct. It can
** be found in the generated sqlite3-jni.h.
*/
#define JniFuncName(Suffix) \
Java_org_sqlite_jni_capi_CApi_sqlite3_ ## Suffix
@@ -179,10 +177,10 @@
JNIEXPORT ReturnType JNICALL JniFuncName(Suffix)
/*
** S3JniApi's intent is that CFunc be the name(s) of the C API func(s)
** the being-declared JNI function is wrapping, making it easier to
** find those bindings' JNI-side entry points. The other args are for
** JniDecl. See the many examples in this file.
** S3JniApi's intent is that CFunc be the C API func(s) the
** being-declared JNI function is wrapping, making it easier to find
** that function's JNI-side entry point. The other args are for JniDecl.
** See the many examples in this file.
*/
#define S3JniApi(CFunc,ReturnType,Suffix) JniDecl(ReturnType,Suffix)
@@ -333,7 +331,7 @@ struct S3JniNphOp {
const char * const zMember /* Name of member property */;
const char * const zTypeSig /* JNI type signature of zMember */;
/*
** klazz is a global ref to the class represented by zName.
** klazz is a global ref to the class represented by pRef.
**
** According to:
**
@@ -997,20 +995,19 @@ static S3JniEnv * S3JniEnv__get(JNIEnv * const env){
** JNI bindings such as sqlite3_prepare_v2/v3(), and definitely not
** from client code.
**
** Returns err_code _unless_ err_code is 0 and sqlite3_set_errmsg()
** fails with OOM, in which case it may return SQLITE_OOM or fail
** fatally.
**
** This function predates sqlite3_set_errmsg(), which is why it has a
** slightly different interface. Before that function was introduced,
** this code used the SQLite-internal APIs to do this.
** Returns err_code.
*/
static int s3jni_db_error(JNIEnv * env, sqlite3* const db,
int err_code, const char * const zMsg){
static int s3jni_db_error(sqlite3* const db, int err_code,
const char * const zMsg){
if( db!=0 ){
int const rc = sqlite3_set_errmsg(db, err_code, zMsg);
s3jni_oom_fatal(0==rc);
if( rc && !err_code ) err_code=rc;
if( 0==zMsg ){
sqlite3Error(db, err_code);
}else{
const int nMsg = sqlite3Strlen30(zMsg);
sqlite3_mutex_enter(sqlite3_db_mutex(db));
sqlite3ErrorWithMsg(db, err_code, "%.*s", nMsg, zMsg);
sqlite3_mutex_leave(sqlite3_db_mutex(db));
}
}
return err_code;
}
@@ -1234,11 +1231,11 @@ static int s3jni__db_exception(JNIEnv * const env, sqlite3 * const pDb,
char * zMsg;
S3JniExceptionClear;
zMsg = s3jni_exception_error_msg(env, ex);
s3jni_db_error(env, pDb, errCode, zMsg ? zMsg : zDfltMsg);
s3jni_db_error(pDb, errCode, zMsg ? zMsg : zDfltMsg);
sqlite3_free(zMsg);
S3JniUnrefLocal(ex);
}else if( zDfltMsg ){
s3jni_db_error(env, pDb, errCode, zDfltMsg);
s3jni_db_error(pDb, errCode, zDfltMsg);
}
return errCode;
}
@@ -1955,6 +1952,15 @@ static void S3JniUdf_finalizer(void * s){
S3JniUdf_free(s3jni_env(), (S3JniUdf*)s, 1);
}
/*
** Helper for processing args to UDF handlers with signature
** (sqlite3_context*,int,sqlite3_value**).
*/
typedef struct {
jobject jcx /* sqlite3_context */;
jobjectArray jargv /* sqlite3_value[] */;
} udf_jargs;
/*
** Converts the given (cx, argc, argv) into arguments for the given
** UDF, writing the result (Java wrappers for cx and argv) in the
@@ -1996,7 +2002,7 @@ error_oom:
/*
** Requires that jCx and jArgv are sqlite3_context
** resp. array-of-sqlite3_value values initialized by udf_args(). The
** (argc,argv) are (0,NULL) for UDF types with no arguments. This
** latter will be 0-and-NULL for UDF types with no arguments. This
** function zeroes out the nativePointer member of jCx and each entry
** in jArgv. This is a safety-net precaution to avoid undefined
** behavior if a Java-side UDF holds a reference to its context or one
@@ -2089,19 +2095,19 @@ static int udf_xFSI(sqlite3_context* const pCx, int argc,
sqlite3_value** const argv, S3JniUdf * const s,
jmethodID xMethodID, const char * const zFuncType){
S3JniDeclLocal_env;
jobject jcx = 0 /* sqlite3_context */;
jobjectArray jargv = 0 /* sqlite3_value[] */;
int rc = udf_args(env, pCx, argc, argv, &jcx, &jargv);
udf_jargs args = {0,0};
int rc = udf_args(env, pCx, argc, argv, &args.jcx, &args.jargv);
if( 0 == rc ){
(*env)->CallVoidMethod(env, s->jObj, xMethodID, jcx, jargv);
(*env)->CallVoidMethod(env, s->jObj, xMethodID, args.jcx, args.jargv);
S3JniIfThrew{
rc = udf_report_exception(env, 'F'==zFuncType[1]/*xFunc*/, pCx,
s->zFuncName, zFuncType);
}
udf_unargs(env, jcx, argc, jargv);
udf_unargs(env, args.jcx, argc, args.jargv);
}
S3JniUnrefLocal(jcx);
S3JniUnrefLocal(jargv);
S3JniUnrefLocal(args.jcx);
S3JniUnrefLocal(args.jargv);
return rc;
}
@@ -3290,7 +3296,7 @@ static jobject s3jni_commit_rollback_hook(int isCommit, JNIEnv * const env,
S3JniDb_mutex_enter;
ps = S3JniDb_from_jlong(jpDb);
if( !ps ){
s3jni_db_error(env, ps->pDb, SQLITE_MISUSE, 0);
s3jni_db_error(ps->pDb, SQLITE_MISUSE, 0);
S3JniDb_mutex_leave;
return 0;
}
@@ -3310,14 +3316,13 @@ static jobject s3jni_commit_rollback_hook(int isCommit, JNIEnv * const env,
else sqlite3_rollback_hook(ps->pDb, 0, 0);
}else{
jclass const klazz = (*env)->GetObjectClass(env, jHook);
jmethodID const xCallback =
(*env)->GetMethodID(env, klazz, "call",
isCommit ? "()I" : "()V");
jmethodID const xCallback = (*env)->GetMethodID(env, klazz, "call",
isCommit ? "()I" : "()V");
S3JniUnrefLocal(klazz);
S3JniIfThrew {
S3JniExceptionReport;
S3JniExceptionClear;
s3jni_db_error(env, ps->pDb, SQLITE_ERROR,
s3jni_db_error(ps->pDb, SQLITE_ERROR,
"Cannot not find matching call() method in"
"hook object.");
}else{
@@ -3597,7 +3602,7 @@ S3JniApi(sqlite3_create_collation() sqlite3_create_collation_v2(),
(*env)->GetMethodID(env, klazz, "call", "([B[B)I");
S3JniUnrefLocal(klazz);
S3JniIfThrew{
rc = s3jni_db_error(env, ps->pDb, SQLITE_ERROR,
rc = s3jni_db_error(ps->pDb, SQLITE_ERROR,
"Could not get call() method from "
"CollationCallback object.");
}else{
@@ -3636,15 +3641,15 @@ S3JniApi(sqlite3_create_function() sqlite3_create_function_v2()
if( !pDb || !jFuncName ){
return SQLITE_MISUSE;
}else if( !encodingTypeIsValid(eTextRep & 0x0f) ){
return s3jni_db_error(env, pDb, SQLITE_FORMAT,
}else if( !encodingTypeIsValid(eTextRep) ){
return s3jni_db_error(pDb, SQLITE_FORMAT,
"Invalid function encoding option.");
}
s = S3JniUdf_alloc(env, jFunctor);
if( !s ) return SQLITE_NOMEM;
if( UDF_UNKNOWN_TYPE==s->type ){
rc = s3jni_db_error(env, pDb, SQLITE_MISUSE,
rc = s3jni_db_error(pDb, SQLITE_MISUSE,
"Cannot unambiguously determine function type.");
S3JniUdf_free(env, s, 1);
goto error_cleanup;
@@ -3851,19 +3856,6 @@ S3JniApi(sqlite3_errmsg(),jstring,1errmsg)(
effect should be identical to using errmsg16(), however. */;
}
S3JniApi(sqlite3_set_errmsg(),jint,1set_1errmsg)(
JniArgsEnvClass, jobject jpDb, jint errCode, jstring msg
){
sqlite3 * const pDb = PtrGet_sqlite3(jpDb);
const char *zUtf8;
jint rc;
if( !pDb ) return SQLITE_MISUSE;
zUtf8 = msg ? s3jni_jstring_to_mutf8(msg) : NULL;
rc = sqlite3_set_errmsg(pDb, (int)errCode, zUtf8);
s3jni_mutf8_release(msg, zUtf8);
return rc;
}
S3JniApi(sqlite3_errstr(),jstring,1errstr)(
JniArgsEnvClass, jint rcCode
){
@@ -4003,7 +3995,7 @@ S3JniApi(sqlite3_jni_db_error(), jint, 1jni_1db_1error)(
zStr = jStr
? s3jni_jstring_to_utf8( jStr, 0)
: NULL;
rc = s3jni_db_error(env, ps->pDb, (int)jRc, zStr );
rc = s3jni_db_error( ps->pDb, (int)jRc, zStr );
sqlite3_free(zStr);
}
return rc;
@@ -4312,7 +4304,7 @@ static void s3jni_updatepre_hook_impl(void * pState, sqlite3 *pDb, int opId,
jTable = jDbName ? s3jni_utf8_to_jstring( zTable, -1) : 0;
S3JniIfThrew {
S3JniExceptionClear;
s3jni_db_error(env, ps->pDb, SQLITE_NOMEM, 0);
s3jni_db_error(ps->pDb, SQLITE_NOMEM, 0);
}else{
assert( hook.jObj );
assert( hook.midCallback );
@@ -4414,7 +4406,7 @@ static jobject s3jni_updatepre_hook(JNIEnv * env, int isPre, jlong jpDb, jobject
S3JniUnrefLocal(klazz);
S3JniIfThrew {
S3JniExceptionClear;
s3jni_db_error(env, ps->pDb, SQLITE_ERROR,
s3jni_db_error(ps->pDb, SQLITE_ERROR,
"Cannot not find matching callback on "
"(pre)update hook object.");
}else{
@@ -4523,7 +4515,7 @@ S3JniApi(sqlite3_progress_handler(),void,1progress_1handler)(
S3JniUnrefLocal(klazz);
S3JniIfThrew {
S3JniExceptionClear;
s3jni_db_error(env, ps->pDb, SQLITE_ERROR,
s3jni_db_error(ps->pDb, SQLITE_ERROR,
"Cannot not find matching xCallback() on "
"ProgressHandler object.");
}else{
@@ -4897,9 +4889,8 @@ S3JniApi(sqlite3_set_authorizer(),jint,1set_1authorizer)(
")I");
S3JniUnrefLocal(klazz);
S3JniIfThrew {
rc = s3jni_db_error(env, ps->pDb, SQLITE_ERROR,
"Error setting up Java parts of "
"authorizer hook.");
rc = s3jni_db_error(ps->pDb, SQLITE_ERROR,
"Error setting up Java parts of authorizer hook.");
}else{
rc = sqlite3_set_authorizer(ps->pDb, s3jni_xAuth, ps);
}
@@ -5183,7 +5174,7 @@ S3JniApi(sqlite3_trace_v2(),jint,1trace_1v2)(
S3JniUnrefLocal(klazz);
S3JniIfThrew {
S3JniExceptionClear;
rc = s3jni_db_error(env, ps->pDb, SQLITE_ERROR,
rc = s3jni_db_error(ps->pDb, SQLITE_ERROR,
"Cannot not find matching call() on "
"TracerCallback object.");
}else{
+2 -12
View File
@@ -245,10 +245,8 @@ extern "C" {
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_USED_SHARED 11L
#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_SPILL
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_SPILL 12L
#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_TEMPBUF_SPILL
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_TEMPBUF_SPILL 13L
#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_MAX
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_MAX 13L
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_MAX 12L
#undef org_sqlite_jni_capi_CApi_SQLITE_UTF8
#define org_sqlite_jni_capi_CApi_SQLITE_UTF8 1L
#undef org_sqlite_jni_capi_CApi_SQLITE_UTF16LE
@@ -1344,7 +1342,7 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1data_1count
* Method: sqlite3_db_config
* Signature: (Lorg/sqlite/jni/capi/sqlite3;IILorg/sqlite/jni/capi/OutputPointer/Int32;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1db_1config__Lorg_sqlite_jni_capi_sqlite3_2IILorg_sqlite_jni_capi_OutputPointer_Int32_2
JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1db_1config__Lorg_sqlite_jni_capi_sqlite3_2IILorg_sqlite_jni_capi_OutputPointer_00024Int32_2
(JNIEnv *, jclass, jobject, jint, jint, jobject);
/*
@@ -1419,14 +1417,6 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1errcode
JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1errmsg
(JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_set_errmsg
* Signature: (Lorg/sqlite/jni/capi/sqlite3;ILjava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1set_1errmsg
(JNIEnv *, jclass, jobject, jint, jstring);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_error_offset
+4 -11
View File
@@ -115,9 +115,8 @@ public final class CApi {
JNIEnv is not cached, else returns true, but this information is
primarily for testing of the JNI bindings and is not information
which client-level code can use to make any informed
decisions. The semantics of its return type and value are not
considered stable and may change at any time. i.e. act as if it
returns null.
decisions. Its return type and semantics are not considered
stable and may change at any time.
*/
public static native boolean sqlite3_java_uncache_thread();
@@ -1198,15 +1197,10 @@ public final class CApi {
public static native String sqlite3_errmsg(@NotNull sqlite3 db);
/** Added in 3.51.0. */
public static native int sqlite3_set_errmsg(@NotNull sqlite3 db,
int resultCode,
String msg);
private static native int sqlite3_error_offset(@NotNull long ptrToDb);
/**
Caveat: the returned byte offset values assume UTF-8-encoded
Note that the returned byte offset values assume UTF-8-encoded
inputs, so won't always match character offsets in Java Strings.
*/
public static int sqlite3_error_offset(@NotNull sqlite3 db){
@@ -2586,8 +2580,7 @@ public final class CApi {
public static final int SQLITE_DBSTATUS_DEFERRED_FKS = 10;
public static final int SQLITE_DBSTATUS_CACHE_USED_SHARED = 11;
public static final int SQLITE_DBSTATUS_CACHE_SPILL = 12;
public static final int SQLITE_DBSTATUS_TEMPBUF_SPILL = 13;
public static final int SQLITE_DBSTATUS_MAX = 13;
public static final int SQLITE_DBSTATUS_MAX = 12;
// encodings
public static final int SQLITE_UTF8 = 1;
+1 -17
View File
@@ -815,9 +815,7 @@ public class Tester1 implements Runnable {
};
// Register and use the function...
int rc = sqlite3_create_function(db, "myfunc", -1,
SQLITE_UTF8 | SQLITE_INNOCUOUS,
func);
int rc = sqlite3_create_function(db, "myfunc", -1, SQLITE_UTF8, func);
affirm(0 == rc);
affirm(0 == xFuncAccum.value);
final sqlite3_stmt stmt = prepare(db, "SELECT myfunc(1,2,3)");
@@ -1876,20 +1874,6 @@ public class Tester1 implements Runnable {
sqlite3_close_v2(db);
}
private void testSetErrmsg(){
final sqlite3 db = createNewDb();
int rc = sqlite3_set_errmsg(db, SQLITE_RANGE, "nope");
affirm( 0==rc );
affirm( SQLITE_MISUSE == sqlite3_set_errmsg(null, 0, null) );
affirm( "nope".equals(sqlite3_errmsg(db)) );
affirm( SQLITE_RANGE == sqlite3_errcode(db) );
rc = sqlite3_set_errmsg(db, 0, null);
affirm( "not an error".equals(sqlite3_errmsg(db)) );
affirm( 0 == sqlite3_errcode(db) );
sqlite3_close_v2(db);
}
/* Copy/paste/rename this to add new tests. */
private void _testTemplate(){
final sqlite3 db = createNewDb();
@@ -171,7 +171,6 @@ public final class Sqlite implements AutoCloseable {
public static final int DBSTATUS_DEFERRED_FKS = CApi.SQLITE_DBSTATUS_DEFERRED_FKS;
public static final int DBSTATUS_CACHE_USED_SHARED = CApi.SQLITE_DBSTATUS_CACHE_USED_SHARED;
public static final int DBSTATUS_CACHE_SPILL = CApi.SQLITE_DBSTATUS_CACHE_SPILL;
public static final int DBSTATUS_TEMPBUF_SPILL = CApi.SQLITE_DBSTATUS_TEMPBUF_SPILL;
// Limits
public static final int LIMIT_LENGTH = CApi.SQLITE_LIMIT_LENGTH;
+10
View File
@@ -9,6 +9,11 @@ Each source file contains a description in its header comment. See the
header comments for details about each extension. Additional notes are
as follows:
* **carray.c** &mdash; This module implements the
[carray](https://sqlite.org/carray.html) table-valued function.
It is a good example of how to go about implementing a custom
[table-valued function](https://sqlite.org/vtab.html#tabfunc2).
* **csv.c** &mdash; A [virtual table](https://sqlite.org/vtab.html)
for reading
[Comma-Separated-Value (CSV) files](https://en.wikipedia.org/wiki/Comma-separated_values).
@@ -23,6 +28,11 @@ as follows:
[SQLite amalgamation](https://sqlite.org/amalgamation.html). See
<https://sqlite.org/json1.html> for additional information.
* **memvfs.c** &mdash; This file implements a custom
[VFS](https://sqlite.org/vfs.html) that stores an entire database
file in a single block of RAM. It serves as a good example of how
to implement a simple custom VFS.
* **rot13.c** &mdash; This file implements the very simple rot13()
substitution function. This file makes a good template for implementing
new custom SQL functions for SQLite.
+7 -7
View File
@@ -514,7 +514,7 @@ struct amatch_cursor {
sqlite3_int64 iRowid; /* The rowid of the current word */
amatch_langid iLang; /* Use this language ID */
amatch_cost rLimit; /* Maximum cost of any term */
sqlite3_int64 nBuf; /* Space allocated for zBuf */
int nBuf; /* Space allocated for zBuf */
int oomErr; /* True following an OOM error */
int nWord; /* Number of amatch_word objects */
char *zBuf; /* Temp-use buffer space */
@@ -847,7 +847,7 @@ static int amatchConnect(
(void)pAux;
*ppVtab = 0;
pNew = sqlite3_malloc64( sizeof(*pNew) );
pNew = sqlite3_malloc( sizeof(*pNew) );
if( pNew==0 ) return SQLITE_NOMEM;
rc = SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
@@ -928,7 +928,7 @@ amatchConnectError:
static int amatchOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
amatch_vtab *p = (amatch_vtab*)pVTab;
amatch_cursor *pCur;
pCur = sqlite3_malloc64( sizeof(*pCur) );
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
pCur->pVtab = p;
@@ -1039,7 +1039,7 @@ static void amatchAddWord(
nTail = (int)strlen(zWordTail);
if( nBase+nTail+3>pCur->nBuf ){
pCur->nBuf = nBase+nTail+100;
pCur->zBuf = sqlite3_realloc64(pCur->zBuf, pCur->nBuf);
pCur->zBuf = sqlite3_realloc(pCur->zBuf, pCur->nBuf);
if( pCur->zBuf==0 ){
pCur->nBuf = 0;
return;
@@ -1105,13 +1105,13 @@ static int amatchNext(sqlite3_vtab_cursor *cur){
amatch_avl *pNode;
int isMatch = 0;
amatch_vtab *p = pCur->pVtab;
sqlite3_int64 nWord;
int nWord;
int rc;
int i;
const char *zW;
amatch_rule *pRule;
char *zBuf = 0;
sqlite3_int64 nBuf = 0;
char nBuf = 0;
char zNext[8];
char zNextIn[8];
int nNextIn;
@@ -1158,7 +1158,7 @@ static int amatchNext(sqlite3_vtab_cursor *cur){
nWord = (int)strlen(pWord->zWord+2);
if( nWord+20>nBuf ){
nBuf = (char)(nWord+100);
zBuf = sqlite3_realloc64(zBuf, nBuf);
zBuf = sqlite3_realloc(zBuf, nBuf);
if( zBuf==0 ) return SQLITE_NOMEM;
}
amatchStrcpy(zBuf, pWord->zWord+2);
-827
View File
@@ -1,827 +0,0 @@
/*
** 2026-04-13
**
** 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.
**
******************************************************************************
**
** Partial reimplement of the sqlite3_analyzer utility program as
** loadable SQL function.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
/*
** State information for the analysis
*/
typedef struct Analysis Analysis;
struct Analysis {
sqlite3 *db; /* Database connection */
sqlite3_context *context; /* SQL function context */
sqlite3_str *pOut; /* Write output here */
char *zSU; /* Name of the temp.space_used table */
const char *zSchema; /* Schema to be analyzed */
};
/*
** Free all resources that the Analysis object references and
** reset the Analysis object.
**
** Call this routine multiple times on the same Analysis object
** is a harmless no-op, as long as the memory for the object itself
** has not been freed.
*/
static void analysisReset(Analysis *p){
if( p->zSU ){
char *zSql = sqlite3_mprintf("DROP TABLE temp.%s;", p->zSU);
if( zSql ){
sqlite3_exec(p->db, zSql, 0, 0, 0);
sqlite3_free(zSql);
}
}
sqlite3_str_free(p->pOut);
sqlite3_free(p->zSU);
memset(p, 0, sizeof(*p));
}
/*
** Report an error using formatted text. If zFormat==NULL then report
** an OOM error.
*/
static void analysisError(Analysis *p, const char *zFormat, ...){
char *zErr;
if( zFormat ){
va_list ap;
va_start(ap, zFormat);
zErr = sqlite3_vmprintf(zFormat, ap);
va_end(ap);
}else{
zErr = 0;
}
if( zErr==0 ){
sqlite3_result_error_nomem(p->context);
}else{
sqlite3_result_error(p->context, zErr, -1);
sqlite3_free(zErr);
}
analysisReset(p);
}
/*
** Prepare and return an SQL statement.
*/
static sqlite3_stmt *analysisVPrep(Analysis *p, const char *zFmt, va_list ap){
char *zSql;
int rc;
sqlite3_stmt *pStmt = 0;
zSql = sqlite3_vmprintf(zFmt, ap);
if( zSql==0 ){ analysisError(p,0); return 0; }
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
if( rc ){
analysisError(p, "SQL parse error: %s\nOriginal SQL: %s",
sqlite3_errmsg(p->db), zSql);
sqlite3_finalize(pStmt);
analysisReset(p);
pStmt = 0;
}
sqlite3_free(zSql);
return pStmt;
}
static sqlite3_stmt *analysisPrepare(Analysis *p, const char *zFormat, ...){
va_list ap;
sqlite3_stmt *pStmt = 0;
va_start(ap, zFormat);
pStmt = analysisVPrep(p,zFormat,ap);
va_end(ap);
return pStmt;
}
/*
** If rc is something other than SQLITE_DONE or SQLITE_OK, then report
** an error and return true.
**
** If rc is SQLITE_DONE or SQLITE_OK, then return false.
**
** The prepared statement is closed in either case.
*/
static int analysisStmtFinish(Analysis *p, int rc, sqlite3_stmt *pStmt){
if( rc==SQLITE_DONE ){
rc = SQLITE_OK;
}
if( rc!=SQLITE_OK || (rc = sqlite3_reset(pStmt))!=SQLITE_OK ){
analysisError(p, "SQL run-time error: %s\nOriginal SQL: %s",
sqlite3_errmsg(p->db), sqlite3_sql(pStmt));
analysisReset(p);
}
sqlite3_finalize(pStmt);
return rc;
}
/*
** Run SQL. Return the number of errors.
*/
static int analysisSql(Analysis *p, const char *zFormat, ...){
va_list ap;
int rc;
sqlite3_stmt *pStmt = 0;
va_start(ap, zFormat);
pStmt = analysisVPrep(p,zFormat,ap);
va_end(ap);
if( pStmt==0 ) return 1;
while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){}
if( rc==SQLITE_DONE ){
rc = SQLITE_OK;
}else{
analysisError(p, "SQL run-time error: %s\nOriginal SQL: %s",
sqlite3_errmsg(p->db), sqlite3_sql(pStmt));
analysisReset(p);
}
sqlite3_finalize(pStmt);
return rc;
}
/*
** Run an SQL query that returns an integer. Write that integer
** into *piRes. Return the number of errors.
*/
static int analysisSqlInt(
Analysis *p,
sqlite3_int64 *piRes,
const char *zFormat, ...
){
va_list ap;
int rc;
sqlite3_stmt *pStmt = 0;
va_start(ap, zFormat);
pStmt = analysisVPrep(p,zFormat,ap);
va_end(ap);
if( pStmt==0 ) return 1;
rc = sqlite3_step(pStmt);
if( rc==SQLITE_ROW ){
*piRes = sqlite3_column_int64(pStmt, 0);
rc = SQLITE_OK;
}else if( rc==SQLITE_DONE ){
rc = SQLITE_OK;
}else{
if( p->db ){
/* p->db is NULL if there was some prior error */
analysisError(p, "SQL run-time error: %s\nOriginal SQL: %s",
sqlite3_errmsg(p->db), sqlite3_sql(pStmt));
}
analysisReset(p);
}
sqlite3_finalize(pStmt);
return rc;
}
/*
** Add to the output a title line that contains the text determined
** by the format string. If the output is initially empty, begin
** the title line with "/" so that it forms the beginning of a C-style
** comment. Otherwise begin with a new-line. Always finish with a
** newline.
*/
static void analysisTitle(Analysis *p, const char *zFormat, ...){
char *zFirst;
char *zTitle;
size_t nTitle;
va_list ap;
va_start(ap, zFormat);
zTitle = sqlite3_vmprintf(zFormat, ap);
va_end(ap);
if( zTitle==0 ){
analysisError(p, 0);
return;
}
zFirst = sqlite3_str_length(p->pOut)==0 ? "/" : "\n*";
nTitle = strlen(zTitle);
if( nTitle>=75 ){
sqlite3_str_appendf(p->pOut, "%s** %z\n\n", zFirst, zTitle);
}else{
int nExtra = 74 - (int)nTitle;
sqlite3_str_appendf(p->pOut, "%s** %z %.*c\n\n", zFirst, zTitle,
nExtra, '*');
}
}
/*
** Add an output line that begins with the zDesc text extended out to
** 50 columns with "." characters, and followed by whatever text is
** described by zFormat.
*/
static void analysisLine(
Analysis *p, /* Analysis context */
const char *zDesc, /* Description */
const char *zFormat, /* Argument to the description */
...
){
char *zTxt;
size_t nDesc;
va_list ap;
va_start(ap, zFormat);
zTxt = sqlite3_vmprintf(zFormat, ap);
va_end(ap);
if( zTxt==0 ){
analysisError(p, 0);
return;
}
nDesc = strlen(zDesc);
if( nDesc>=50 ){
sqlite3_str_appendf(p->pOut, "%s %z", zDesc, zTxt);
}else{
int nExtra = 50 - (int)nDesc;
sqlite3_str_appendf(p->pOut, "%s%.*c %z", zDesc, nExtra, '.', zTxt);
}
}
/*
** Write a percentage into the output. The number written should show
** two or three significant digits, with the decimal point being the fourth
** character.
*/
static void analysisPercent(Analysis *p, double r){
char zNum[100];
char *zDP;
int nLeadingDigit;
int sz;
sqlite3_snprintf(sizeof(zNum)-5, zNum, r>=10.0 ? "%.3g" :"%.2g", r);
sz = (int)strlen(zNum);
zDP = strchr(zNum, '.');
if( zDP==0 ){
memcpy(zNum+sz,".0",3);
nLeadingDigit = sz;
sz += 2;
}else{
nLeadingDigit = (int)(zDP - zNum);
}
if( nLeadingDigit<3 ){
sqlite3_str_appendchar(p->pOut, 3-nLeadingDigit, ' ');
}
sqlite3_str_append(p->pOut, zNum, sz);
sqlite3_str_append(p->pOut, "%\n", 2);
}
/*
** Create a subreport on a subset of tables and/or indexes.
**
** The title if the subreport is given by zTitle. zWhere is
** a boolean expression that can go in the WHERE clause to select
** the relevant rows of the s.zSU table.
*/
static int analysisSubreport(
Analysis *p, /* Analysis context */
char *zTitle, /* Title for this subreport */
char *zWhere, /* WHERE clause for this subreport */
sqlite3_int64 pgsz, /* Database page size */
sqlite3_int64 nPage /* Number of pages in entire database */
){
sqlite3_stmt *pStmt; /* Statement to query p->zSU */
sqlite3_int64 nentry; /* Number of btree entires */
sqlite3_int64 payload; /* Payload in bytes */
sqlite3_int64 ovfl_payload; /* overflow payload in bytes */
sqlite3_int64 mx_payload; /* largest individual payload */
sqlite3_int64 ovfl_cnt; /* Number entries using overflow */
sqlite3_int64 leaf_pages; /* Leaf pages */
sqlite3_int64 int_pages; /* internal pages */
sqlite3_int64 ovfl_pages; /* overflow pages */
sqlite3_int64 leaf_unused; /* unused bytes on leaf pages */
sqlite3_int64 int_unused; /* unused bytes on internal pages */
sqlite3_int64 ovfl_unused; /* unused bytes on overflow pages */
sqlite3_int64 int_cell; /* B-tree entries on internal pages */
sqlite3_int64 depth; /* btree depth */
sqlite3_int64 cnt; /* Number of s.zSU entries that match */
sqlite3_int64 storage; /* Total bytes */
sqlite3_int64 total_pages; /* Total page count */
sqlite3_int64 total_unused; /* Total unused bytes */
sqlite3_int64 total_meta; /* Total metadata */
int rc;
if( zTitle==0 || zWhere==0 ){
analysisError(p, 0);
return SQLITE_NOMEM;
}
pStmt = analysisPrepare(p,
"SELECT\n"
" sum(if(is_without_rowid OR is_index,nentry,leaf_entries)),\n" /* 0 */
" sum(payload),\n" /* 1 */
" sum(ovfl_payload),\n" /* 2 */
" max(mx_payload),\n" /* 3 */
" sum(ovfl_cnt),\n" /* 4 */
" sum(leaf_pages),\n" /* 5 */
" sum(int_pages),\n" /* 6 */
" sum(ovfl_pages),\n" /* 7 */
" sum(leaf_unused),\n" /* 8 */
" sum(int_unused),\n" /* 9 */
" sum(ovfl_unused),\n" /* 10 */
" max(depth),\n" /* 11 */
" count(*),\n" /* 12 */
" sum(int_entries)\n" /* 13 */
" FROM temp.%s WHERE %s",
p->zSU, zWhere);
if( pStmt==0 ) return 1;
rc = sqlite3_step(pStmt);
if( rc==SQLITE_ROW ){
analysisTitle(p, zTitle);
nentry = sqlite3_column_int64(pStmt, 0);
payload = sqlite3_column_int64(pStmt, 1);
ovfl_payload = sqlite3_column_int64(pStmt, 2);
mx_payload = sqlite3_column_int64(pStmt, 3);
ovfl_cnt = sqlite3_column_int64(pStmt, 4);
leaf_pages = sqlite3_column_int64(pStmt, 5);
int_pages = sqlite3_column_int64(pStmt, 6);
ovfl_pages = sqlite3_column_int64(pStmt, 7);
leaf_unused = sqlite3_column_int64(pStmt, 8);
int_unused = sqlite3_column_int64(pStmt, 9);
ovfl_unused = sqlite3_column_int64(pStmt, 10);
depth = sqlite3_column_int64(pStmt, 11);
cnt = sqlite3_column_int64(pStmt, 12);
int_cell = sqlite3_column_int64(pStmt, 13);
rc = SQLITE_DONE;
total_pages = leaf_pages + int_pages + ovfl_pages;
analysisLine(p, "Percentage of total database", "%.3g%%\n",
(total_pages*100.0)/(double)nPage);
analysisLine(p, "Number of entries", "%lld\n", nentry);
storage = total_pages*pgsz;
analysisLine(p, "Bytes of storage consumed", "%lld\n", storage);
analysisLine(p, "Bytes of payload", "%-11lld ", payload);
analysisPercent(p, payload*100.0/(double)storage);
if( ovfl_cnt>0 ){
analysisLine(p, "Bytes of payload in overflow","%-11lld ",ovfl_payload);
analysisPercent(p, ovfl_payload*100.0/(double)payload);
}
total_unused = leaf_unused + int_unused + ovfl_unused;
total_meta = storage - payload - total_unused;
analysisLine(p, "Bytes of metadata","%-11lld ", total_meta);
analysisPercent(p, total_meta*100.0/(double)storage);
if( cnt==1 ){
analysisLine(p, "B-tree depth", "%lld\n", depth);
if( int_cell>1 ){
analysisLine(p, "Average fanout", "%.1f\n",
(double)(int_cell+int_pages)/(double)int_pages);
}
}
if( nentry>0 ){
analysisLine(p, "Average payload per entry", "%.1f\n",
(double)payload/(double)nentry);
analysisLine(p, "Average unused bytes per entry", "%.1f\n",
(double)total_unused/(double)nentry);
analysisLine(p, "Average metadata per entry", "%.1f\n",
(double)total_meta/(double)nentry);
}
analysisLine(p, "Maximum single-entry payload", "%lld\n", mx_payload);
if( nentry>0 ){
analysisLine(p, "Entries that use overflow", "%-11lld ", ovfl_cnt);
analysisPercent(p, ovfl_cnt*100.0/(double)nentry);
}
if( int_pages>0 ){
analysisLine(p, "Index pages used", "%lld\n", int_pages);
}
analysisLine(p, "Primary pages used", "%lld\n", leaf_pages);
if( ovfl_cnt ){
analysisLine(p, "Overflow pages used", "%lld\n", ovfl_pages);
}
analysisLine(p, "Total pages used", "%lld\n", total_pages);
if( int_pages>0 ){
analysisLine(p, "Unused bytes on index pages", "%lld\n", int_unused);
}
analysisLine(p, "Unused bytes on primary pages", "%lld\n", leaf_unused);
if( ovfl_cnt ){
analysisLine(p, "Unused bytes on overflow pages", "%lld\n", ovfl_unused);
}
analysisLine(p, "Unused bytes on all pages", "%-11lld ", total_unused);
analysisPercent(p, total_unused*100.0/(double)storage);
}
return analysisStmtFinish(p, rc, pStmt);
}
/*
** SQL Function: analyze(SCHEMA)
**
** Analyze the database schema named in the argument. Return text
** containing the analysis.
*/
static void analyzeFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
int rc;
sqlite3_stmt *pStmt;
int n;
sqlite3_int64 i64;
sqlite3_int64 pgsz;
sqlite3_int64 nPage;
sqlite3_int64 nPageInUse;
sqlite3_int64 nFreeList;
sqlite3_int64 nIndex;
sqlite3_int64 nWORowid;
Analysis s;
sqlite3_uint64 r[2];
memset(&s, 0, sizeof(s));
s.db = sqlite3_context_db_handle(context);
s.context = context;
s.pOut = sqlite3_str_new(0);
if( s.pOut==0 ){ analysisError(&s, 0); return; }
s.zSchema = (const char*)sqlite3_value_text(argv[0]);
if( s.zSchema==0 ){
s.zSchema = "main";
}else if( sqlite3_strlike("temp",s.zSchema,0)==0 ){
/* Attempt to analyze "temp" returns NULL */
analysisReset(&s);
return;
}
i64 = 0;
rc = analysisSqlInt(&s,&i64,"SELECT 1 FROM pragma_database_list"
" WHERE name=%Q COLLATE nocase",s.zSchema);
if( rc || i64==0 ){
/* Return NULL the named schema does not exist */
analysisReset(&s);
return;
}
sqlite3_randomness(sizeof(r), &r);
s.zSU = sqlite3_mprintf("analysis%016llx%016llx", r[0], r[1]);
if( s.zSU==0 ){ analysisError(&s, 0); return; }
/* The s.zSU table contains the data used for the analysis.
** The table name contains 128-bits of randomness to avoid
** collisions with preexisting tables in temp.
*/
rc = analysisSql(&s,
"CREATE TABLE temp.%s(\n"
" name text, -- A table or index\n"
" tblname text, -- Table that owns name\n"
" is_index boolean, -- TRUE if it is an index\n"
" is_without_rowid boolean, -- TRUE if WITHOUT ROWID table\n"
" nentry int, -- Number of entries in the BTree\n"
" leaf_entries int, -- Number of leaf entries\n"
" depth int, -- Depth of the b-tree\n"
" payload int, -- Total data stored in this table/index\n"
" ovfl_payload int, -- Total data stored on overflow pages\n"
" ovfl_cnt int, -- Number of entries that use overflow\n"
" mx_payload int, -- Maximum payload size\n"
" int_pages int, -- Interior pages used\n"
" leaf_pages int, -- Leaf pages used\n"
" ovfl_pages int, -- Overflow pages used\n"
" int_unused int, -- Unused bytes on interior pages\n"
" leaf_unused int, -- Unused bytes on primary pages\n"
" ovfl_unused int, -- Unused bytes on overflow pages\n"
" int_entries int -- Btree cells on internal pages\n"
");",
s.zSU
);
if( rc ) return;
/* Populate the s.zSU table
*/
rc = analysisSql(&s,
"WITH\n"
" allidx(idxname) AS (\n"
" SELECT name FROM \"%w\".sqlite_schema WHERE type='index'\n"
" ),\n"
" allobj(allname,tblname,isidx,isworowid) AS (\n"
" SELECT 'sqlite_schema',\n"
" 'sqlite_schema',\n"
" 0,\n"
" 0\n"
" UNION ALL\n"
" SELECT name,\n"
" tbl_name,\n"
" type='index',\n"
" EXISTS(SELECT 1\n"
" FROM pragma_index_list(sqlite_schema.name,%Q)\n"
" WHERE pragma_index_list.origin='pk'\n"
" AND pragma_index_list.name NOT IN allidx)\n"
" FROM \"%w\".sqlite_schema\n"
" )\n"
"INSERT INTO temp.%s\n"
" SELECT\n"
" allname,\n"
" tblname,\n"
" isidx,\n"
" isworowid,\n"
" sum(ncell),\n"
" sum((pagetype='leaf')*ncell),\n"
" max((length(if(path GLOB '*+*','',path))+3)/4),\n"
" sum(payload),\n"
" sum((pagetype='overflow')*payload),\n"
" sum(path GLOB '*+000000'),\n"
" max(mx_payload),\n"
" sum(pagetype='internal'),\n"
" sum(pagetype='leaf'),\n"
" sum(pagetype='overflow'),\n"
" sum((pagetype='internal')*unused),\n"
" sum((pagetype='leaf')*unused),\n"
" sum((pagetype='overflow')*unused),\n"
" sum(if(pagetype='internal',ncell))\n"
" FROM allobj CROSS JOIN dbstat(%Q) \n"
" WHERE dbstat.name=allobj.allname\n"
" GROUP BY allname;\n",
s.zSchema, /* %w.sqlite_schema -- in allidx */
s.zSchema, /* pragma_index_list(...,%Q) */
s.zSchema, /* %w.sqlite_schema */
s.zSU, /* INTO temp.%s */
s.zSchema /* JOIN dbstat(%Q) */
);
if( rc ) return;
/* Begin generating the report */
analysisTitle(&s, "Database storage utilization report");
pgsz = 0;
rc = analysisSqlInt(&s, &pgsz, "PRAGMA \"%w\".page_size", s.zSchema);
if( rc ) return;
analysisLine(&s, "Page size in bytes","%lld\n",pgsz);
nPage = 0;
rc = analysisSqlInt(&s, &nPage, "PRAGMA \"%w\".page_count", s.zSchema);
if( rc ) return;
analysisLine(&s, "Pages in the database", "%lld\n", nPage);
if( nPage<=0 ) nPage = 1;
nPageInUse = 0;
rc = analysisSqlInt(&s, &nPageInUse,
"SELECT sum(leaf_pages+int_pages+ovfl_pages) FROM temp.%s", s.zSU);
if( rc ) return;
analysisLine(&s, "Pages that store data", "%-11lld ", nPageInUse);
analysisPercent(&s, (nPageInUse*100.0)/(double)nPage);
nFreeList = 0;
rc = analysisSqlInt(&s, &nFreeList, "PRAGMA \"%w\".freelist_count",s.zSchema);
if( rc ) return;
analysisLine(&s, "Pages on the freelist", "%-11lld ", nFreeList);
analysisPercent(&s, (nFreeList*100.0)/(double)nPage);
i64 = 0;
rc = analysisSqlInt(&s, &i64, "PRAGMA \"%w\".auto_vacuum", s.zSchema);
if( rc ) return;
if( i64==0 || nPage<=1 ){
i64 = 0;
}else{
double rPtrsPerPage = pgsz/5;
double rAvPage = (nPage-1.0)/(rPtrsPerPage+1.0);
i64 = (sqlite3_int64)ceil(rAvPage);
}
analysisLine(&s, "Pages of auto-vacuum overhead", "%-11lld ", i64);
analysisPercent(&s, (i64*100.0)/(double)nPage);
i64 = 0;
rc = analysisSqlInt(&s, &i64,
"SELECT count(*)+1 FROM \"%w\".sqlite_schema WHERE type='table'",
s.zSchema);
if( rc ) return;
analysisLine(&s, "Number of tables", "%lld\n", i64);
nWORowid = 0;
rc = analysisSqlInt(&s, &nWORowid,
"SELECT count(*) FROM \"%w\".pragma_table_list WHERE wr",
s.zSchema);
if( rc ) return;
if( nWORowid>0 ){
analysisLine(&s, "Number of WITHOUT ROWID tables", "%lld\n", nWORowid);
analysisLine(&s, "Number of rowid tables", "%lld\n", i64 - nWORowid);
}
nIndex = 0;
rc = analysisSqlInt(&s, &nIndex,
"SELECT count(*) FROM \"%w\".sqlite_schema WHERE type='index'",
s.zSchema);
if( rc ) return;
analysisLine(&s, "Number of indexes", "%lld\n", nIndex);
i64 = 0;
rc = analysisSqlInt(&s, &i64,
"SELECT count(*) FROM \"%w\".sqlite_schema"
" WHERE name GLOB 'sqlite_autoindex_*' AND type='index'",
s.zSchema);
if( rc ) return;
analysisLine(&s, "Number of defined indexes", "%lld\n", nIndex - i64);
analysisLine(&s, "Number of implied indexes", "%lld\n", i64);
analysisLine(&s, "Size of the database in bytes", "%lld\n", pgsz*nPage);
i64 = 0;
rc = analysisSqlInt(&s, &i64,
"SELECT sum(payload) FROM temp.%s"
" WHERE NOT is_index AND name NOT LIKE 'sqlite_schema'",
s.zSU);
if( rc ) return;
analysisLine(&s, "Bytes of payload", "%-11lld ", i64);
analysisPercent(&s, i64*100.0/(double)(pgsz*nPage));
analysisTitle(&s, "Page counts for all tables with their indexes");
pStmt = analysisPrepare(&s,
"SELECT upper(tblname),\n"
" sum(int_pages+leaf_pages+ovfl_pages)\n"
" FROM temp.%s\n"
" GROUP BY 1\n"
" ORDER BY 2 DESC, 1;",
s.zSU);
if( pStmt==0 ) return;
while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
sqlite3_int64 n = sqlite3_column_int64(pStmt,1);
analysisLine(&s, (const char*)sqlite3_column_text(pStmt,0), "%-11lld ", n);
analysisPercent(&s, (n*100.0)/(double)nPage);
}
if( analysisStmtFinish(&s, rc, pStmt) ) return;
analysisTitle(&s, "Page counts for all tables and indexes separately");
pStmt = analysisPrepare(&s,
"SELECT upper(name),\n"
" sum(int_pages+leaf_pages+ovfl_pages)\n"
" FROM temp.%s\n"
" GROUP BY 1\n"
" ORDER BY 2 DESC, 1;",
s.zSU);
if( pStmt==0 ) return;
while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
sqlite3_int64 n = sqlite3_column_int64(pStmt,1);
analysisLine(&s, (const char*)sqlite3_column_text(pStmt,0), "%-11lld ", n);
analysisPercent(&s, (n*100.0)/(double)nPage);
}
if( analysisStmtFinish(&s, rc, pStmt) ) return;
rc = analysisSubreport(&s, "All tables and indexes", "1", pgsz, nPage);
if( rc ) return;
rc = analysisSubreport(&s, "All tables", "NOT is_index", pgsz, nPage);
if( rc ) return;
if( nWORowid>0 ){
rc = analysisSubreport(&s, "All WITHOUT ROWID tables", "is_without_rowid",
pgsz, nPage);
if( rc ) return;
rc = analysisSubreport(&s, "All rowid tables",
"NOT is_without_rowid AND NOT is_index",
pgsz, nPage);
if( rc ) return;
}
rc = analysisSubreport(&s, "All indexes", "is_index", pgsz, nPage);
if( rc ) return;
pStmt = analysisPrepare(&s,
"SELECT upper(tblname), tblname, sum(is_index) FROM temp.%s"
" GROUP BY 1 ORDER BY 1",
s.zSU);
if( pStmt==0 ) return;
while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
const char *zUpper = (const char*)sqlite3_column_text(pStmt, 0);
const char *zName = (const char*)sqlite3_column_text(pStmt, 1);
int nSubIndex = sqlite3_column_int(pStmt, 2);
if( nSubIndex==0 ){
char *zTitle = sqlite3_mprintf("Table %s", zUpper);
char *zWhere = sqlite3_mprintf("name=%Q", zName);
rc = analysisSubreport(&s, zTitle, zWhere, pgsz, nPage);
sqlite3_free(zTitle);
sqlite3_free(zWhere);
if( rc ) break;
}else{
sqlite3_stmt *pS2;
char *zTitle = sqlite3_mprintf("Table %s and all its indexes", zUpper);
char *zWhere = sqlite3_mprintf("tblname=%Q", zName);
rc = analysisSubreport(&s, zTitle, zWhere, pgsz, nPage);
sqlite3_free(zTitle);
sqlite3_free(zWhere);
if( rc ) break;
zTitle = sqlite3_mprintf("Table %s w/o any indexes", zUpper);
zWhere = sqlite3_mprintf("name=%Q", zName);
rc = analysisSubreport(&s, zTitle, zWhere, pgsz, nPage);
sqlite3_free(zTitle);
sqlite3_free(zWhere);
if( rc ) break;
if( nSubIndex>1 ){
zTitle = sqlite3_mprintf("All indexes of table %s", zUpper);
zWhere = sqlite3_mprintf("tblname=%Q AND is_index", zName);
rc = analysisSubreport(&s, zTitle, zWhere, pgsz, nPage);
sqlite3_free(zTitle);
sqlite3_free(zWhere);
if( rc ) break;
}
pS2 = analysisPrepare(&s,
"SELECT name, upper(name) FROM temp.%s"
" WHERE is_index AND tblname=%Q",
s.zSU, zName);
if( pS2==0 ){
rc = SQLITE_NOMEM;
break;
}
while( (rc = sqlite3_step(pS2))==SQLITE_ROW ){
const char *zU = (const char*)sqlite3_column_text(pS2, 1);
const char *zN = (const char*)sqlite3_column_text(pS2, 0);
zTitle = sqlite3_mprintf("Index %s", zU);
zWhere = sqlite3_mprintf("name=%Q", zN);
rc = analysisSubreport(&s, zTitle, zWhere, pgsz, nPage);
sqlite3_free(zTitle);
sqlite3_free(zWhere);
if( rc ) break;
}
rc = analysisStmtFinish(&s, rc, pS2);
if( rc ) break;
}
}
if( analysisStmtFinish(&s, rc, pStmt) ) return;
/* Append SQL statements that will recreate the raw data used for
** the analysis.
*/
analysisTitle(&s, "Raw data used to generate this report");
sqlite3_str_appendf(s.pOut,
"The following SQL will create a table named \"space_used\" which\n"
"contains most of the information used to generate the report above.\n"
"*/\n"
);
sqlite3_str_appendf(s.pOut,
"BEGIN;\n"
"CREATE TABLE space_used(\n"
" name text, -- A table or index\n" /* 0 */
" tblname text, -- Table that owns name\n" /* 1 */
" is_index boolean, -- TRUE if it is an index\n" /* 2 */
" is_without_rowid boolean, -- TRUE if WITHOUT ROWID table\n" /* 3 */
" nentry int, -- Number of entries in the BTree\n" /* 4 */
" leaf_entries int, -- Number of leaf entries\n" /* 5 */
" depth int, -- Depth of the b-tree\n" /* 6 */
" payload int, -- Total data in this table/index\n" /* 7 */
" ovfl_payload int, -- Total data on overflow pages\n" /* 8 */
" ovfl_cnt int, -- Entries that use overflow\n" /* 9 */
" mx_payload int, -- Maximum payload size\n" /* 10 */
" int_pages int, -- Interior pages used\n" /* 11 */
" leaf_pages int, -- Leaf pages used\n" /* 12 */
" ovfl_pages int, -- Overflow pages used\n" /* 13 */
" int_unused int, -- Unused bytes on interior pages\n" /* 14 */
" leaf_unused int, -- Unused bytes on primary pages\n" /* 15 */
" ovfl_unused int, -- Unused bytes on overflow pages\n" /* 16 */
" int_entries int -- B-tree entries on internal pages\n"/* 17 */
");\n"
"INSERT INTO space_used VALUES\n"
);
pStmt = analysisPrepare(&s,
"SELECT quote(name), quote(tblname),\n" /* 0..1 */
" is_index, is_without_rowid, nentry, leaf_entries,\n" /* 2..5 */
" depth, payload, ovfl_payload, ovfl_cnt, mx_payload,\n" /* 6..10 */
" int_pages, leaf_pages, ovfl_pages, int_unused,\n" /* 11..14 */
" leaf_unused, ovfl_unused, int_entries\n" /* 15..17 */
" FROM temp.%s;",
s.zSU);
if( pStmt==0 ) return;
n = 0;
while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
if( n++ ) sqlite3_str_appendf(s.pOut,",\n");
sqlite3_str_appendf(s.pOut,
" (%s,%s,%lld,%lld,%lld,%lld,%lld,%lld,%lld,"
"%lld,%lld,%lld,%lld,%lld,%lld,%lld,%lld,%lld)",
sqlite3_column_text(pStmt, 0),
sqlite3_column_text(pStmt, 1),
sqlite3_column_int64(pStmt, 2),
sqlite3_column_int64(pStmt, 3),
sqlite3_column_int64(pStmt, 4),
sqlite3_column_int64(pStmt, 5),
sqlite3_column_int64(pStmt, 6),
sqlite3_column_int64(pStmt, 7),
sqlite3_column_int64(pStmt, 8),
sqlite3_column_int64(pStmt, 9),
sqlite3_column_int64(pStmt, 10),
sqlite3_column_int64(pStmt, 11),
sqlite3_column_int64(pStmt, 12),
sqlite3_column_int64(pStmt, 13),
sqlite3_column_int64(pStmt, 14),
sqlite3_column_int64(pStmt, 15),
sqlite3_column_int64(pStmt, 16),
sqlite3_column_int64(pStmt, 17));
}
if( rc!=SQLITE_DONE ){
analysisError(&s, "SQL run-time error: %s\nSQL: %s",
sqlite3_errmsg(s.db), sqlite3_sql(pStmt));
sqlite3_finalize(pStmt);
return;
}
sqlite3_str_appendf(s.pOut,";\nCOMMIT;");
sqlite3_finalize(pStmt);
if( sqlite3_str_length(s.pOut) ){
sqlite3_result_text(context, sqlite3_str_finish(s.pOut), -1,
sqlite3_free);
s.pOut = 0;
}
analysisReset(&s);
}
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_analyze_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
rc = sqlite3_create_function(db, "analyze", 1,
SQLITE_UTF8|SQLITE_INNOCUOUS,
0, analyzeFunc, 0, 0);
return rc;
}
+5 -7
View File
@@ -207,9 +207,7 @@ static u8* fromBase64( char *pIn, int ncIn, u8 *pOut ){
/* This function does the work for the SQLite base64(x) UDF. */
static void base64(sqlite3_context *context, int na, sqlite3_value *av[]){
sqlite3_int64 nb;
sqlite3_int64 nv = sqlite3_value_bytes(av[0]);
sqlite3_int64 nc;
int nb, nc, nv = sqlite3_value_bytes(av[0]);
int nvMax = sqlite3_limit(sqlite3_context_db_handle(context),
SQLITE_LIMIT_LENGTH, -1);
char *cBuf;
@@ -218,7 +216,7 @@ static void base64(sqlite3_context *context, int na, sqlite3_value *av[]){
switch( sqlite3_value_type(av[0]) ){
case SQLITE_BLOB:
nb = nv;
nc = 4*((nv+2)/3); /* quads needed */
nc = 4*(nv+2/3); /* quads needed */
nc += (nc+(B64_DARK_MAX-1))/B64_DARK_MAX + 1; /* LFs and a 0-terminator */
if( nvMax < nc ){
sqlite3_result_error(context, "blob expanded to base64 too big", -1);
@@ -232,7 +230,7 @@ static void base64(sqlite3_context *context, int na, sqlite3_value *av[]){
sqlite3_result_text(context,"",-1,SQLITE_STATIC);
break;
}
cBuf = sqlite3_malloc64(nc);
cBuf = sqlite3_malloc(nc);
if( !cBuf ) goto memFail;
nc = (int)(toBase64(bBuf, nb, cBuf) - cBuf);
sqlite3_result_text(context, cBuf, nc, sqlite3_free);
@@ -254,7 +252,7 @@ static void base64(sqlite3_context *context, int na, sqlite3_value *av[]){
sqlite3_result_zeroblob(context, 0);
break;
}
bBuf = sqlite3_malloc64(nb);
bBuf = sqlite3_malloc(nb);
if( !bBuf ) goto memFail;
nb = (int)(fromBase64(cBuf, nc, bBuf) - bBuf);
sqlite3_result_blob(context, bBuf, nb, sqlite3_free);
@@ -275,7 +273,7 @@ static void base64(sqlite3_context *context, int na, sqlite3_value *av[]){
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_base64_init
int sqlite3_base_init
#else
static int sqlite3_base64_init
#endif
+10 -10
View File
@@ -262,7 +262,7 @@ static int allBase85( char *p, int len ){
#ifndef BASE85_STANDALONE
#ifndef OMIT_BASE85_CHECKER
# ifndef OMIT_BASE85_CHECKER
/* This function does the work for the SQLite is_base85(t) UDF. */
static void is_base85(sqlite3_context *context, int na, sqlite3_value *av[]){
assert(na==1);
@@ -282,11 +282,11 @@ static void is_base85(sqlite3_context *context, int na, sqlite3_value *av[]){
return;
}
}
#endif
# endif
/* This function does the work for the SQLite base85(x) UDF. */
static void base85(sqlite3_context *context, int na, sqlite3_value *av[]){
sqlite3_int64 nb, nc, nv = sqlite3_value_bytes(av[0]);
int nb, nc, nv = sqlite3_value_bytes(av[0]);
int nvMax = sqlite3_limit(sqlite3_context_db_handle(context),
SQLITE_LIMIT_LENGTH, -1);
char *cBuf;
@@ -309,7 +309,7 @@ static void base85(sqlite3_context *context, int na, sqlite3_value *av[]){
sqlite3_result_text(context,"",-1,SQLITE_STATIC);
break;
}
cBuf = sqlite3_malloc64(nc);
cBuf = sqlite3_malloc(nc);
if( !cBuf ) goto memFail;
nc = (int)(toBase85(bBuf, nb, cBuf, "\n") - cBuf);
sqlite3_result_text(context, cBuf, nc, sqlite3_free);
@@ -331,7 +331,7 @@ static void base85(sqlite3_context *context, int na, sqlite3_value *av[]){
sqlite3_result_zeroblob(context, 0);
break;
}
bBuf = sqlite3_malloc64(nb);
bBuf = sqlite3_malloc(nb);
if( !bBuf ) goto memFail;
nb = (int)(fromBase85(cBuf, nc, bBuf) - bBuf);
sqlite3_result_blob(context, bBuf, nb, sqlite3_free);
@@ -352,14 +352,14 @@ static void base85(sqlite3_context *context, int na, sqlite3_value *av[]){
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_base85_init
int sqlite3_base_init
#else
static int sqlite3_base85_init
#endif
(sqlite3 *db, char **pzErr, const sqlite3_api_routines *pApi){
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErr;
#ifndef OMIT_BASE85_CHECKER
# ifndef OMIT_BASE85_CHECKER
{
int rc = sqlite3_create_function
(db, "is_base85", 1,
@@ -367,7 +367,7 @@ static int sqlite3_base85_init
0, is_base85, 0, 0);
if( rc!=SQLITE_OK ) return rc;
}
#endif
# endif
return sqlite3_create_function
(db, "base85", 1,
SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS|SQLITE_DIRECTONLY|SQLITE_UTF8,
@@ -432,9 +432,9 @@ int main(int na, char *av[]){
int nc = strlen(cBuf);
size_t nbo = fromBase85( cBuf, nc, bBuf ) - bBuf;
if( 1 != fwrite(bBuf, nbo, 1, fb) ) rc = 1;
#ifndef OMIT_BASE85_CHECKER
# ifndef OMIT_BASE85_CHECKER
b85Clean &= allBase85( cBuf, nc );
#endif
# endif
}
break;
default:
+1 -5
View File
@@ -306,10 +306,6 @@ static int binfoCompute(sqlite3 *db, int pgno, BinfoCursor *pCsr){
nEntry *= (nCell+1);
if( aData[0]==10 || aData[0]==13 ) break;
nPage *= (nCell+1);
if( 14+2*(nCell/2)>=pgsz ){
rc = SQLITE_CORRUPT;
break;
}
if( nCell<=1 ){
pgno = get_uint32(aData+8);
}else{
@@ -343,7 +339,7 @@ static int binfoColumn(
sqlite3 *db = sqlite3_context_db_handle(ctx);
int rc = binfoCompute(db, pgno, pCsr);
if( rc ){
pCursor->pVtab->zErrMsg = sqlite3_mprintf("%s", sqlite3_errstr(rc));
pCursor->pVtab->zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
return SQLITE_ERROR;
}
}
+100 -97
View File
@@ -10,7 +10,7 @@
**
*************************************************************************
**
** This file implements a table-valued-function that
** This file demonstrates how to create a table-valued-function that
** returns the values in a C-language array.
** Examples:
**
@@ -52,9 +52,11 @@
** as the number of elements in the array. The virtual table steps through
** the array, element by element.
*/
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_CARRAY)
#include "sqliteInt.h"
#if defined(_WIN32) || defined(__RTP__) || defined(_WRS_KERNEL)
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>
#ifdef _WIN32
struct iovec {
void *iov_base;
size_t iov_len;
@@ -62,13 +64,33 @@
#else
# include <sys/uio.h>
#endif
/* Allowed values for the mFlags parameter to sqlite3_carray_bind().
** Must exactly match the definitions in carray.h.
*/
#ifndef CARRAY_INT32
# define CARRAY_INT32 0 /* Data is 32-bit signed integers */
# define CARRAY_INT64 1 /* Data is 64-bit signed integers */
# define CARRAY_DOUBLE 2 /* Data is doubles */
# define CARRAY_TEXT 3 /* Data is char* */
# define CARRAY_BLOB 4 /* Data is struct iovec* */
#endif
#ifndef SQLITE_API
# ifdef _WIN32
# define SQLITE_API __declspec(dllexport)
# else
# define SQLITE_API
# endif
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Names of allowed datatypes
*/
static const char *azCarrayType[] = {
"int32", "int64", "double", "char*", "struct iovec"
};
static const char *azType[] = { "int32", "int64", "double", "char*",
"struct iovec" };
/*
** Structure used to hold the sqlite3_carray_bind() information
@@ -79,7 +101,6 @@ struct carray_bind {
int nData; /* Number of elements */
int mFlags; /* Control flags */
void (*xDel)(void*); /* Destructor for aData */
void *pDel; /* Alternative argument to xDel() */
};
@@ -188,7 +209,7 @@ static int carrayColumn(
case CARRAY_COLUMN_POINTER: return SQLITE_OK;
case CARRAY_COLUMN_COUNT: x = pCur->iCnt; break;
case CARRAY_COLUMN_CTYPE: {
sqlite3_result_text(ctx, azCarrayType[pCur->eType], -1, SQLITE_STATIC);
sqlite3_result_text(ctx, azType[pCur->eType], -1, SQLITE_STATIC);
return SQLITE_OK;
}
default: {
@@ -213,11 +234,10 @@ static int carrayColumn(
sqlite3_result_text(ctx, p[pCur->iRowid-1], -1, SQLITE_TRANSIENT);
return SQLITE_OK;
}
default: {
case CARRAY_BLOB: {
const struct iovec *p = (struct iovec*)pCur->pPtr;
assert( pCur->eType==CARRAY_BLOB );
sqlite3_result_blob(ctx, p[pCur->iRowid-1].iov_base,
(int)p[pCur->iRowid-1].iov_len, SQLITE_TRANSIENT);
(int)p[pCur->iRowid-1].iov_len, SQLITE_TRANSIENT);
return SQLITE_OK;
}
}
@@ -276,10 +296,10 @@ static int carrayFilter(
}else{
unsigned char i;
const char *zType = (const char*)sqlite3_value_text(argv[2]);
for(i=0; i<sizeof(azCarrayType)/sizeof(azCarrayType[0]); i++){
if( sqlite3_stricmp(zType, azCarrayType[i])==0 ) break;
for(i=0; i<sizeof(azType)/sizeof(azType[0]); i++){
if( sqlite3_stricmp(zType, azType[i])==0 ) break;
}
if( i>=sizeof(azCarrayType)/sizeof(azCarrayType[0]) ){
if( i>=sizeof(azType)/sizeof(azType[0]) ){
pVtabCursor->pVtab->zErrMsg = sqlite3_mprintf(
"unknown datatype: %Q", zType);
return SQLITE_ERROR;
@@ -322,14 +342,12 @@ static int carrayBestIndex(
int ptrIdx = -1; /* Index of the pointer= constraint, or -1 if none */
int cntIdx = -1; /* Index of the count= constraint, or -1 if none */
int ctypeIdx = -1; /* Index of the ctype= constraint, or -1 if none */
unsigned seen = 0; /* Bitmask of == constrainted columns */
const struct sqlite3_index_constraint *pConstraint;
pConstraint = pIdxInfo->aConstraint;
for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
if( pConstraint->iColumn>=0 ) seen |= 1 << pConstraint->iColumn;
if( pConstraint->usable==0 ) continue;
if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
switch( pConstraint->iColumn ){
case CARRAY_COLUMN_POINTER:
ptrIdx = i;
@@ -356,15 +374,7 @@ static int carrayBestIndex(
pIdxInfo->aConstraintUsage[ctypeIdx].argvIndex = 3;
pIdxInfo->aConstraintUsage[ctypeIdx].omit = 1;
pIdxInfo->idxNum = 3;
}else if( seen & (1<<CARRAY_COLUMN_CTYPE) ){
/* In a three-argument carray(), we need to know the value of all
** three arguments */
return SQLITE_CONSTRAINT;
}
}else if( seen & (1<<CARRAY_COLUMN_COUNT) ){
/* In a two-argument carray(), we need to know the value of both
** arguments */
return SQLITE_CONSTRAINT;
}
}else{
pIdxInfo->estimatedCost = (double)2147483647;
@@ -412,7 +422,7 @@ static sqlite3_module carrayModule = {
static void carrayBindDel(void *pPtr){
carray_bind *p = (carray_bind*)pPtr;
if( p->xDel!=SQLITE_STATIC ){
p->xDel(p->pDel);
p->xDel(p->aData);
}
sqlite3_free(p);
}
@@ -420,74 +430,51 @@ static void carrayBindDel(void *pPtr){
/*
** Invoke this interface in order to bind to the single-argument
** version of CARRAY().
**
** pStmt The prepared statement to which to bind
** idx The index of the parameter of pStmt to which to bind
** aData The data to be bound
** nData The number of elements in aData
** mFlags One of SQLITE_CARRAY_xxxx indicating datatype of aData
** xDestroy Destructor for pDestroy or aData if pDestroy==NULL.
** pDestroy Invoke xDestroy on this pointer if not NULL
**
** The destructor is called pDestroy if pDestroy!=NULL, or against
** aData if pDestroy==NULL.
*/
SQLITE_API int sqlite3_carray_bind_v2(
SQLITE_API int sqlite3_carray_bind(
sqlite3_stmt *pStmt,
int idx,
void *aData,
int nData,
int mFlags,
void (*xDestroy)(void*),
void *pDestroy
void (*xDestroy)(void*)
){
carray_bind *pNew = 0;
carray_bind *pNew;
int i;
int rc = SQLITE_OK;
/* Ensure that the mFlags value is acceptable. */
assert( CARRAY_INT32==0 && CARRAY_INT64==1 && CARRAY_DOUBLE==2 );
assert( CARRAY_TEXT==3 && CARRAY_BLOB==4 );
if( mFlags<CARRAY_INT32 || mFlags>CARRAY_BLOB ){
rc = SQLITE_ERROR;
goto carray_bind_error;
}
pNew = sqlite3_malloc64(sizeof(*pNew));
if( pNew==0 ){
rc = SQLITE_NOMEM;
goto carray_bind_error;
if( xDestroy!=SQLITE_STATIC && xDestroy!=SQLITE_TRANSIENT ){
xDestroy(aData);
}
return SQLITE_NOMEM;
}
pNew->nData = nData;
pNew->mFlags = mFlags;
if( xDestroy==SQLITE_TRANSIENT ){
sqlite3_int64 sz = nData;
switch( mFlags ){
switch( mFlags & 0x07 ){
case CARRAY_INT32: sz *= 4; break;
case CARRAY_INT64: sz *= 8; break;
case CARRAY_DOUBLE: sz *= 8; break;
case CARRAY_TEXT: sz *= sizeof(char*); break;
default: sz *= sizeof(struct iovec); break;
case CARRAY_BLOB: sz *= sizeof(struct iovec); break;
}
if( mFlags==CARRAY_TEXT ){
if( (mFlags & 0x07)==CARRAY_TEXT ){
for(i=0; i<nData; i++){
const char *z = ((char**)aData)[i];
if( z ) sz += strlen(z) + 1;
}
}else if( mFlags==CARRAY_BLOB ){
}else if( (mFlags & 0x07)==CARRAY_BLOB ){
for(i=0; i<nData; i++){
sz += ((struct iovec*)aData)[i].iov_len;
}
}
pNew->aData = sqlite3_malloc64( sz );
if( pNew->aData==0 ){
rc = SQLITE_NOMEM;
goto carray_bind_error;
sqlite3_free(pNew);
return SQLITE_NOMEM;
}
if( mFlags==CARRAY_TEXT ){
if( (mFlags & 0x07)==CARRAY_TEXT ){
char **az = (char**)pNew->aData;
char *z = (char*)&az[nData];
for(i=0; i<nData; i++){
@@ -502,7 +489,7 @@ SQLITE_API int sqlite3_carray_bind_v2(
memcpy(z, zData, n+1);
z += n+1;
}
}else if( mFlags==CARRAY_BLOB ){
}else if( (mFlags & 0x07)==CARRAY_BLOB ){
struct iovec *p = (struct iovec*)pNew->aData;
unsigned char *z = (unsigned char*)&p[nData];
for(i=0; i<nData; i++){
@@ -516,43 +503,59 @@ SQLITE_API int sqlite3_carray_bind_v2(
memcpy(pNew->aData, aData, sz);
}
pNew->xDel = sqlite3_free;
pNew->pDel = pNew->aData;
}else{
pNew->aData = aData;
pNew->xDel = xDestroy;
pNew->pDel = pDestroy;
}
return sqlite3_bind_pointer(pStmt, idx, pNew, "carray-bind", carrayBindDel);
carray_bind_error:
if( xDestroy!=SQLITE_STATIC && xDestroy!=SQLITE_TRANSIENT ){
xDestroy(pDestroy);
}
/*
** For testing purpose in the TCL test harness, we need a method for
** setting the pointer value. The inttoptr(X) SQL function accomplishes
** this. Tcl script will bind an integer to X and the inttoptr() SQL
** function will use sqlite3_result_pointer() to convert that integer into
** a pointer.
**
** This is for testing on TCL only.
*/
#ifdef SQLITE_TEST
static void inttoptrFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
void *p;
sqlite3_int64 i64;
i64 = sqlite3_value_int64(argv[0]);
if( sizeof(i64)==sizeof(p) ){
memcpy(&p, &i64, sizeof(p));
}else{
int i32 = i64 & 0xffffffff;
memcpy(&p, &i32, sizeof(p));
}
sqlite3_free(pNew);
sqlite3_result_pointer(context, p, "carray", 0);
}
#endif /* SQLITE_TEST */
#endif /* SQLITE_OMIT_VIRTUALTABLE */
SQLITE_API int sqlite3_carray_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
#ifndef SQLITE_OMIT_VIRTUALTABLE
rc = sqlite3_create_module(db, "carray", &carrayModule, 0);
#ifdef SQLITE_TEST
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "inttoptr", 1, SQLITE_UTF8, 0,
inttoptrFunc, 0, 0);
}
#endif /* SQLITE_TEST */
#endif /* SQLITE_OMIT_VIRTUALTABLE */
return rc;
}
/*
** Invoke this interface in order to bind to the single-argument
** version of CARRAY(). Same as sqlite3_carray_bind_v2() with the
** pDestroy parameter set to NULL.
*/
SQLITE_API int sqlite3_carray_bind(
sqlite3_stmt *pStmt,
int idx,
void *aData,
int nData,
int mFlags,
void (*xDestroy)(void*)
){
return sqlite3_carray_bind_v2(pStmt,idx,aData,nData,mFlags,xDestroy,aData);
}
/*
** Invoke this routine to register the carray() function.
*/
Module *sqlite3CarrayRegister(sqlite3 *db){
return sqlite3VtabCreateModule(db, "carray", &carrayModule, 0, 0);
}
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_CARRAY) */
+50
View File
@@ -0,0 +1,50 @@
/*
** 2020-11-17
**
** 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.
**
*************************************************************************
**
** Interface definitions for the CARRAY table-valued function
** extension.
*/
#ifndef _CARRAY_H
#define _CARRAY_H
#include "sqlite3.h" /* Required for error code definitions */
#ifdef __cplusplus
extern "C" {
#endif
/* Use this interface to bind an array to the single-argument version
** of CARRAY().
*/
SQLITE_API int sqlite3_carray_bind(
sqlite3_stmt *pStmt, /* Statement to be bound */
int i, /* Parameter index */
void *aData, /* Pointer to array data */
int nData, /* Number of data elements */
int mFlags, /* CARRAY flags */
void (*xDel)(void*) /* Destructgor for aData*/
);
/* Allowed values for the mFlags parameter to sqlite3_carray_bind().
*/
#define CARRAY_INT32 0 /* Data is 32-bit signed integers */
#define CARRAY_INT64 1 /* Data is 64-bit signed integers */
#define CARRAY_DOUBLE 2 /* Data is doubles */
#define CARRAY_TEXT 3 /* Data is char* */
#define CARRAY_BLOB 4 /* Data is struct iovec */
#ifdef __cplusplus
} /* end of the 'extern "C"' block */
#endif
#endif /* ifndef _CARRAY_H */
+3 -3
View File
@@ -516,7 +516,7 @@ static int closureConnect(
(void)pAux;
*ppVtab = 0;
pNew = sqlite3_malloc64( sizeof(*pNew) );
pNew = sqlite3_malloc( sizeof(*pNew) );
if( pNew==0 ) return SQLITE_NOMEM;
rc = SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
@@ -579,7 +579,7 @@ closureConnectError:
static int closureOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
closure_vtab *p = (closure_vtab*)pVTab;
closure_cursor *pCur;
pCur = sqlite3_malloc64( sizeof(*pCur) );
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
pCur->pVtab = p;
@@ -638,7 +638,7 @@ static int closureInsertNode(
sqlite3_int64 id, /* The node ID */
int iGeneration /* The generation number for this node */
){
closure_avl *pNew = sqlite3_malloc64( sizeof(*pNew) );
closure_avl *pNew = sqlite3_malloc( sizeof(*pNew) );
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
pNew->id = id;
+15 -30
View File
@@ -132,7 +132,7 @@ static int completionConnect(
" phase INT HIDDEN" /* Used for debugging only */
")");
if( rc==SQLITE_OK ){
pNew = sqlite3_malloc64( sizeof(*pNew) );
pNew = sqlite3_malloc( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
@@ -154,7 +154,7 @@ static int completionDisconnect(sqlite3_vtab *pVtab){
*/
static int completionOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
completion_cursor *pCur;
pCur = sqlite3_malloc64( sizeof(*pCur) );
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
pCur->db = ((completion_vtab*)p)->db;
@@ -199,7 +199,6 @@ static int completionNext(sqlite3_vtab_cursor *cur){
completion_cursor *pCur = (completion_cursor*)cur;
int eNextPhase = 0; /* Next phase to try if current phase reaches end */
int iCol = -1; /* If >=0, step pCur->pStmt and use the i-th column */
int rc;
pCur->iRowid++;
while( pCur->ePhase!=COMPLETION_EOF ){
switch( pCur->ePhase ){
@@ -225,27 +224,22 @@ static int completionNext(sqlite3_vtab_cursor *cur){
case COMPLETION_TABLES: {
if( pCur->pStmt==0 ){
sqlite3_stmt *pS2;
sqlite3_str* pStr = sqlite3_str_new(pCur->db);
char *zSql = 0;
const char *zSep = "";
sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
while( sqlite3_step(pS2)==SQLITE_ROW ){
const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
sqlite3_str_appendf(pStr,
"%s"
zSql = sqlite3_mprintf(
"%z%s"
"SELECT name FROM \"%w\".sqlite_schema",
zSep, zDb
zSql, zSep, zDb
);
if( zSql==0 ) return SQLITE_NOMEM;
zSep = " UNION ";
}
rc = sqlite3_finalize(pS2);
zSql = sqlite3_str_finish(pStr);
if( zSql==0 ) return SQLITE_NOMEM;
if( rc==SQLITE_OK ){
sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
}
sqlite3_finalize(pS2);
sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
sqlite3_free(zSql);
if( rc ) return rc;
}
iCol = 0;
eNextPhase = COMPLETION_COLUMNS;
@@ -254,29 +248,24 @@ static int completionNext(sqlite3_vtab_cursor *cur){
case COMPLETION_COLUMNS: {
if( pCur->pStmt==0 ){
sqlite3_stmt *pS2;
sqlite3_str *pStr = sqlite3_str_new(pCur->db);
char *zSql = 0;
const char *zSep = "";
sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
while( sqlite3_step(pS2)==SQLITE_ROW ){
const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
sqlite3_str_appendf(pStr,
"%s"
zSql = sqlite3_mprintf(
"%z%s"
"SELECT pti.name FROM \"%w\".sqlite_schema AS sm"
" JOIN pragma_table_xinfo(sm.name,%Q) AS pti"
" WHERE sm.type='table'",
zSep, zDb, zDb
zSql, zSep, zDb, zDb
);
if( zSql==0 ) return SQLITE_NOMEM;
zSep = " UNION ";
}
rc = sqlite3_finalize(pS2);
zSql = sqlite3_str_finish(pStr);
if( zSql==0 ) return SQLITE_NOMEM;
if( rc==SQLITE_OK ){
sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
}
sqlite3_finalize(pS2);
sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
sqlite3_free(zSql);
if( rc ) return rc;
}
iCol = 0;
eNextPhase = COMPLETION_EOF;
@@ -293,10 +282,9 @@ static int completionNext(sqlite3_vtab_cursor *cur){
pCur->szRow = sqlite3_column_bytes(pCur->pStmt, iCol);
}else{
/* When all rows are finished, advance to the next phase */
rc = sqlite3_finalize(pCur->pStmt);
sqlite3_finalize(pCur->pStmt);
pCur->pStmt = 0;
pCur->ePhase = eNextPhase;
if( rc ) return rc;
continue;
}
}
@@ -382,7 +370,6 @@ static int completionFilter(
if( pCur->nPrefix>0 ){
pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
pCur->nPrefix = (int)strlen(pCur->zPrefix);
}
iArg = 1;
}
@@ -391,7 +378,6 @@ static int completionFilter(
if( pCur->nLine>0 ){
pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
if( pCur->zLine==0 ) return SQLITE_NOMEM;
pCur->nLine = (int)strlen(pCur->zLine);
}
}
if( pCur->zLine!=0 && pCur->zPrefix==0 ){
@@ -403,7 +389,6 @@ static int completionFilter(
if( pCur->nPrefix>0 ){
pCur->zPrefix = sqlite3_mprintf("%.*s", pCur->nPrefix, pCur->zLine + i);
if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
pCur->nPrefix = (int)strlen(pCur->zPrefix);
}
}
pCur->iRowid = 0;
+2 -2
View File
@@ -59,7 +59,7 @@ static void compressFunc(
pIn = sqlite3_value_blob(argv[0]);
nIn = sqlite3_value_bytes(argv[0]);
nOut = 13 + nIn + (nIn+999)/1000;
pOut = sqlite3_malloc64( nOut+5 );
pOut = sqlite3_malloc( nOut+5 );
for(i=4; i>=0; i--){
x[i] = (nIn >> (7*(4-i)))&0x7f;
}
@@ -98,7 +98,7 @@ static void uncompressFunc(
nOut = (nOut<<7) | (pIn[i]&0x7f);
if( (pIn[i]&0x80)!=0 ){ i++; break; }
}
pOut = sqlite3_malloc64( nOut+1 );
pOut = sqlite3_malloc( nOut+1 );
rc = uncompress(pOut, &nOut, &pIn[i], nIn-i);
if( rc==Z_OK ){
sqlite3_result_blob(context, pOut, nOut, sqlite3_free);
+15 -18
View File
@@ -24,8 +24,8 @@
** schema= parameter, like this:
**
** CREATE VIRTUAL TABLE temp.csv2 USING csv(
** filename = '../http.log',
** schema = 'CREATE TABLE x(date,ipaddr,url,referrer,userAgent)'
** filename = "../http.log",
** schema = "CREATE TABLE x(date,ipaddr,url,referrer,userAgent)"
** );
**
** Instead of specifying a file, the text of the CSV can be loaded using
@@ -62,10 +62,6 @@ SQLITE_EXTENSION_INIT1
# define CSV_NOINLINE
#endif
#ifndef SQLITEINT_H
typedef sqlite3_int64 i64;
typedef sqlite3_uint64 u64;
#endif
/* Max size of the error message in a CsvReader */
#define CSV_MXERR 200
@@ -78,9 +74,9 @@ typedef struct CsvReader CsvReader;
struct CsvReader {
FILE *in; /* Read the CSV text from this input stream */
char *z; /* Accumulated text for a field */
i64 n; /* Number of bytes in z */
i64 nAlloc; /* Space allocated for z[] */
i64 nLine; /* Current line number */
int n; /* Number of bytes in z */
int nAlloc; /* Space allocated for z[] */
int nLine; /* Current line number */
int bNotFirst; /* True if prior text has been seen */
int cTerm; /* Character that terminated the most recent field */
size_t iIn; /* Next unread character in the input buffer */
@@ -129,7 +125,7 @@ static int csv_reader_open(
const char *zData /* ... or use this data */
){
if( zFilename ){
p->zIn = sqlite3_malloc64( CSV_INBUFSZ );
p->zIn = sqlite3_malloc( CSV_INBUFSZ );
if( p->zIn==0 ){
csv_errmsg(p, "out of memory");
return 1;
@@ -178,7 +174,7 @@ static int csv_getc(CsvReader *p){
** Return 0 on success and non-zero if there is an OOM error */
static CSV_NOINLINE int csv_resize_and_append(CsvReader *p, char c){
char *zNew;
i64 nNew = p->nAlloc*2 + 100;
int nNew = p->nAlloc*2 + 100;
zNew = sqlite3_realloc64(p->z, nNew);
if( zNew ){
p->z = zNew;
@@ -222,7 +218,7 @@ static char *csv_read_one_field(CsvReader *p){
}
if( c=='"' ){
int pc, ppc;
i64 startLine = p->nLine;
int startLine = p->nLine;
pc = ppc = 0;
while( 1 ){
c = csv_getc(p);
@@ -326,7 +322,7 @@ typedef struct CsvCursor {
sqlite3_vtab_cursor base; /* Base class. Must be first */
CsvReader rdr; /* The CsvReader object */
char **azVal; /* Value of the current row */
i64 *aLen; /* Length of each entry */
int *aLen; /* Length of each entry */
sqlite3_int64 iRowid; /* The current rowid. Negative for EOF */
} CsvCursor;
@@ -498,7 +494,7 @@ static int csvtabConnect(
CsvTable *pNew = 0; /* The CsvTable object to construct */
int bHeader = -1; /* header= flags. -1 means not seen yet */
int rc = SQLITE_OK; /* Result code from this routine */
u64 i, j; /* Loop counters */
int i, j; /* Loop counters */
#ifdef SQLITE_TEST
int tstFlags = 0; /* Value for testflags=N parameter */
#endif
@@ -514,10 +510,11 @@ static int csvtabConnect(
# define CSV_DATA (azPValue[1])
# define CSV_SCHEMA (azPValue[2])
assert( sizeof(azPValue)==sizeof(azParam) );
memset(&sRdr, 0, sizeof(sRdr));
memset(azPValue, 0, sizeof(azPValue));
for(i=3; i<(u64)argc; i++){
for(i=3; i<argc; i++){
const char *z = argv[i];
const char *zValue;
for(j=0; j<sizeof(azParam)/sizeof(azParam[0]); j++){
@@ -564,7 +561,7 @@ static int csvtabConnect(
){
goto csvtab_connect_error;
}
pNew = sqlite3_malloc64( sizeof(*pNew) );
pNew = sqlite3_malloc( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) goto csvtab_connect_oom;
memset(pNew, 0, sizeof(*pNew));
@@ -710,12 +707,12 @@ static int csvtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
CsvTable *pTab = (CsvTable*)p;
CsvCursor *pCur;
size_t nByte;
nByte = sizeof(*pCur) + (sizeof(char*)+sizeof(i64))*pTab->nCol;
nByte = sizeof(*pCur) + (sizeof(char*)+sizeof(int))*pTab->nCol;
pCur = sqlite3_malloc64( nByte );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, nByte);
pCur->azVal = (char**)&pCur[1];
pCur->aLen = (i64*)&pCur->azVal[pTab->nCol];
pCur->aLen = (int*)&pCur->azVal[pTab->nCol];
*ppCursor = &pCur->base;
if( csv_reader_open(&pCur->rdr, pTab->zFilename, pTab->zData) ){
csv_xfer_error(pTab, &pCur->rdr);
+6 -6
View File
@@ -67,9 +67,9 @@ struct DState {
*/
typedef struct DText DText;
struct DText {
char *z; /* The text */
sqlite3_int64 n; /* Number of bytes of content in z[] */
sqlite3_int64 nAlloc; /* Number of bytes allocated to z[] */
char *z; /* The text */
int n; /* Number of bytes of content in z[] */
int nAlloc; /* Number of bytes allocated to z[] */
};
/*
@@ -107,7 +107,7 @@ static void appendText(DText *p, char const *zAppend, char quote){
if( p->n+len>=p->nAlloc ){
char *zNew;
p->nAlloc = p->nAlloc*2 + len + 20;
zNew = sqlite3_realloc64(p->z, p->nAlloc);
zNew = sqlite3_realloc(p->z, p->nAlloc);
if( zNew==0 ){
freeText(p);
return;
@@ -179,8 +179,8 @@ static char **tableColumnList(DState *p, const char *zTab){
char **azCol = 0;
sqlite3_stmt *pStmt = 0;
char *zSql;
sqlite3_int64 nCol = 0;
sqlite3_int64 nAlloc = 0;
int nCol = 0;
int nAlloc = 0;
int nPK = 0; /* Number of PRIMARY KEY columns seen */
int isIPK = 0; /* True if one PRIMARY KEY column of type INTEGER */
int preserveRowid = 1;
+19 -84
View File
@@ -31,10 +31,6 @@ SQLITE_EXTENSION_INIT1
#define IsSpace(X) isspace((unsigned char)X)
#endif
#ifndef SQLITE_DECIMAL_MAX_DIGIT
# define SQLITE_DECIMAL_MAX_DIGIT 10000000
#endif
/* A decimal object */
typedef struct Decimal Decimal;
struct Decimal {
@@ -73,8 +69,7 @@ static Decimal *decimalNewFromText(const char *zIn, int n){
int i;
int iExp = 0;
if( zIn==0 ) goto new_from_text_failed;
p = sqlite3_malloc64( sizeof(*p) );
p = sqlite3_malloc( sizeof(*p) );
if( p==0 ) goto new_from_text_failed;
p->sign = 0;
p->oom = 0;
@@ -133,10 +128,8 @@ static Decimal *decimalNewFromText(const char *zIn, int n){
}
}
if( iExp>0 ){
signed char *a = sqlite3_realloc64(p->a, (sqlite3_int64)p->nDigit
+ (sqlite3_int64)iExp + 1 );
if( a==0 ) goto new_from_text_failed;
p->a = a;
p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 );
if( p->a==0 ) goto new_from_text_failed;
memset(p->a+p->nDigit, 0, iExp);
p->nDigit += iExp;
}
@@ -154,21 +147,14 @@ static Decimal *decimalNewFromText(const char *zIn, int n){
}
}
if( iExp>0 ){
signed char *a = sqlite3_realloc64(p->a, (sqlite3_int64)p->nDigit
+ (sqlite3_int64)iExp + 1 );
if( a==0 ) goto new_from_text_failed;
p->a = a;
p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 );
if( p->a==0 ) goto new_from_text_failed;
memmove(p->a+iExp, p->a, p->nDigit);
memset(p->a, 0, iExp);
p->nDigit += iExp;
p->nFrac += iExp;
}
}
if( p->sign ){
for(i=0; i<p->nDigit && p->a[i]==0; i++){}
if( i>=p->nDigit ) p->sign = 0;
}
if( p->nDigit>SQLITE_DECIMAL_MAX_DIGIT ) goto new_from_text_failed;
return p;
new_from_text_failed:
@@ -261,7 +247,7 @@ static void decimal_result(sqlite3_context *pCtx, Decimal *p){
sqlite3_result_null(pCtx);
return;
}
z = sqlite3_malloc64( (sqlite3_int64)p->nDigit+4 );
z = sqlite3_malloc( p->nDigit+4 );
if( z==0 ){
sqlite3_result_error_nomem(pCtx);
return;
@@ -299,38 +285,12 @@ static void decimal_result(sqlite3_context *pCtx, Decimal *p){
sqlite3_result_text(pCtx, z, i, sqlite3_free);
}
/*
** Round a decimal value to N significant digits. N must be positive.
*/
static void decimal_round(Decimal *p, int N){
int i;
int nZero;
if( N<1 ) return;
if( p==0 ) return;
if( p->nDigit<=N ) return;
for(nZero=0; nZero<p->nDigit && p->a[nZero]==0; nZero++){}
N += nZero;
if( p->nDigit<=N ) return;
if( p->a[N]>4 ){
p->a[N-1]++;
for(i=N-1; i>0 && p->a[i]>9; i--){
p->a[i] = 0;
p->a[i-1]++;
}
if( p->a[0]>9 ){
p->a[0] = 1;
p->nFrac--;
}
}
memset(&p->a[N], 0, p->nDigit - N);
}
/*
** Make the given Decimal the result in an format similar to '%+#e'.
** In other words, show exponential notation with leading and trailing
** zeros omitted.
*/
static void decimal_result_sci(sqlite3_context *pCtx, Decimal *p, int N){
static void decimal_result_sci(sqlite3_context *pCtx, Decimal *p){
char *z; /* The output buffer */
int i; /* Loop counter */
int nZero; /* Number of leading zeros */
@@ -348,12 +308,11 @@ static void decimal_result_sci(sqlite3_context *pCtx, Decimal *p, int N){
sqlite3_result_null(pCtx);
return;
}
if( N<1 ) N = 0;
for(nDigit=p->nDigit; nDigit>N && p->a[nDigit-1]==0; nDigit--){}
for(nDigit=p->nDigit; nDigit>0 && p->a[nDigit-1]==0; nDigit--){}
for(nZero=0; nZero<nDigit && p->a[nZero]==0; nZero++){}
nFrac = p->nFrac + (nDigit - p->nDigit);
nDigit -= nZero;
z = sqlite3_malloc64( (sqlite3_int64)nDigit+20 );
z = sqlite3_malloc( nDigit+20 );
if( z==0 ){
sqlite3_result_error_nomem(pCtx);
return;
@@ -398,21 +357,13 @@ static void decimal_result_sci(sqlite3_context *pCtx, Decimal *p, int N){
** pB!=0
** pB->isNull==0
*/
static int decimal_cmp(Decimal *pA, Decimal *pB){
static int decimal_cmp(const Decimal *pA, const Decimal *pB){
int nASig, nBSig, rc, n;
while( pA->nFrac>0 && pA->a[pA->nDigit-1]==0 ){
pA->nDigit--;
pA->nFrac--;
}
while( pB->nFrac>0 && pB->a[pB->nDigit-1]==0 ){
pB->nDigit--;
pB->nFrac--;
}
if( pA->sign!=pB->sign ){
return pA->sign ? -1 : +1;
}
if( pA->sign ){
Decimal *pTemp = pA;
const Decimal *pTemp = pA;
pA = pB;
pB = pTemp;
}
@@ -465,18 +416,15 @@ cmp_done:
static void decimal_expand(Decimal *p, int nDigit, int nFrac){
int nAddSig;
int nAddFrac;
signed char *a;
if( p==0 ) return;
nAddFrac = nFrac - p->nFrac;
nAddSig = (nDigit - p->nDigit) - nAddFrac;
if( nAddFrac==0 && nAddSig==0 ) return;
if( nDigit+1>SQLITE_DECIMAL_MAX_DIGIT ){ p->oom = 1; return; }
a = sqlite3_realloc64(p->a, nDigit+1);
if( a==0 ){
p->a = sqlite3_realloc64(p->a, nDigit+1);
if( p->a==0 ){
p->oom = 1;
return;
}
p->a = a;
if( nAddSig ){
memmove(p->a+nAddSig, p->a, p->nDigit);
memset(p->a, 0, nAddSig);
@@ -571,18 +519,13 @@ static void decimalMul(Decimal *pA, Decimal *pB){
signed char *acc = 0;
int i, j, k;
int minFrac;
sqlite3_int64 sumDigit;
if( pA==0 || pA->oom || pA->isNull
|| pB==0 || pB->oom || pB->isNull
){
goto mul_end;
}
sumDigit = pA->nDigit;
sumDigit += pB->nDigit;
sumDigit += 2;
if( sumDigit>SQLITE_DECIMAL_MAX_DIGIT ){ pA->oom = 1; return; }
acc = sqlite3_malloc64( sumDigit );
acc = sqlite3_malloc64( pA->nDigit + pB->nDigit + 2 );
if( acc==0 ){
pA->oom = 1;
goto mul_end;
@@ -669,7 +612,7 @@ static Decimal *decimalFromDouble(double r){
isNeg = 0;
}
memcpy(&a,&r,sizeof(a));
if( a==0 || a==(sqlite3_int64)0x8000000000000000LL){
if( a==0 ){
e = 0;
m = 0;
}else{
@@ -719,16 +662,10 @@ static void decimalFunc(
sqlite3_value **argv
){
Decimal *p = decimal_new(context, argv[0], 0);
int N;
if( argc==2 ){
N = sqlite3_value_int(argv[1]);
if( N>0 ) decimal_round(p, N);
}else{
N = 0;
}
UNUSED_PARAMETER(argc);
if( p ){
if( sqlite3_user_data(context)!=0 ){
decimal_result_sci(context, p, N);
decimal_result_sci(context, p);
}else{
decimal_result(context, p);
}
@@ -814,7 +751,7 @@ static void decimalSumStep(
if( p==0 ) return;
if( !p->isInit ){
p->isInit = 1;
p->a = sqlite3_malloc64(2);
p->a = sqlite3_malloc(2);
if( p->a==0 ){
p->oom = 1;
}else{
@@ -898,7 +835,7 @@ static void decimalPow2Func(
UNUSED_PARAMETER(argc);
if( sqlite3_value_type(argv[0])==SQLITE_INTEGER ){
Decimal *pA = decimalPow2(sqlite3_value_int(argv[0]));
decimal_result_sci(context, pA, 0);
decimal_result_sci(context, pA);
decimal_free(pA);
}
}
@@ -919,9 +856,7 @@ int sqlite3_decimal_init(
void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
} aFunc[] = {
{ "decimal", 1, 0, decimalFunc },
{ "decimal", 2, 0, decimalFunc },
{ "decimal_exp", 1, 1, decimalFunc },
{ "decimal_exp", 2, 1, decimalFunc },
{ "decimal_cmp", 2, 0, decimalCmpFunc },
{ "decimal_add", 2, 0, decimalAddFunc },
{ "decimal_sub", 2, 0, decimalSubFunc },
+2 -2
View File
@@ -92,7 +92,7 @@ static int explainConnect(
rc = sqlite3_declare_vtab(db,
"CREATE TABLE x(addr,opcode,p1,p2,p3,p4,p5,comment,sql HIDDEN)");
if( rc==SQLITE_OK ){
pNew = sqlite3_malloc64( sizeof(*pNew) );
pNew = sqlite3_malloc( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
@@ -114,7 +114,7 @@ static int explainDisconnect(sqlite3_vtab *pVtab){
*/
static int explainOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
explain_cursor *pCur;
pCur = sqlite3_malloc64( sizeof(*pCur) );
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
pCur->db = ((explain_vtab*)p)->db;
+75 -177
View File
@@ -73,6 +73,11 @@
** $path is a relative path, then $path is interpreted relative to $dir.
** And the paths returned in the "name" column of the table are also
** relative to directory $dir.
**
** Notes on building this extension for Windows:
** Unless linked statically with the SQLite library, a preprocessor
** symbol, FILEIO_WIN32_DLL, must be #define'd to create a stand-alone
** DLL form of this extension for WIN32. See its use below for details.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
@@ -89,16 +94,12 @@ SQLITE_EXTENSION_INIT1
# include <utime.h>
# include <sys/time.h>
# define STRUCT_STAT struct stat
# include <limits.h>
# include <stdlib.h>
#else
# include "windirent.h"
# include <direct.h>
# define STRUCT_STAT struct _stat
# define chmod(path,mode) fileio_chmod(path,mode)
# define mkdir(path,mode) fileio_mkdir(path)
extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR);
#endif
#include <time.h>
#include <errno.h>
@@ -130,9 +131,12 @@ SQLITE_EXTENSION_INIT1
*/
#if defined(_WIN32) || defined(WIN32)
static int fileio_chmod(const char *zPath, int pmode){
sqlite3_int64 sz = strlen(zPath);
wchar_t *b1 = sqlite3_malloc64( (sz+1)*sizeof(b1[0]) );
int rc;
wchar_t *b1 = sqlite3_win32_utf8_to_unicode(zPath);
if( b1==0 ) return -1;
sz = MultiByteToWideChar(CP_UTF8, 0, zPath, sz, b1, sz);
b1[sz] = 0;
rc = _wchmod(b1, pmode);
sqlite3_free(b1);
return rc;
@@ -144,9 +148,12 @@ static int fileio_chmod(const char *zPath, int pmode){
*/
#if defined(_WIN32) || defined(WIN32)
static int fileio_mkdir(const char *zPath){
sqlite3_int64 sz = strlen(zPath);
wchar_t *b1 = sqlite3_malloc64( (sz+1)*sizeof(b1[0]) );
int rc;
wchar_t *b1 = sqlite3_win32_utf8_to_unicode(zPath);
if( b1==0 ) return -1;
sz = MultiByteToWideChar(CP_UTF8, 0, zPath, sz, b1, sz);
b1[sz] = 0;
rc = _wmkdir(b1);
sqlite3_free(b1);
return rc;
@@ -259,7 +266,50 @@ static sqlite3_uint64 fileTimeToUnixTime(
return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000;
}
#endif /* _WIN32 */
#if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
# /* To allow a standalone DLL, use this next replacement function: */
# undef sqlite3_win32_utf8_to_unicode
# define sqlite3_win32_utf8_to_unicode utf8_to_utf16
#
LPWSTR utf8_to_utf16(const char *z){
int nAllot = MultiByteToWideChar(CP_UTF8, 0, z, -1, NULL, 0);
LPWSTR rv = sqlite3_malloc(nAllot * sizeof(WCHAR));
if( rv!=0 && 0 < MultiByteToWideChar(CP_UTF8, 0, z, -1, rv, nAllot) )
return rv;
sqlite3_free(rv);
return 0;
}
#endif
/*
** This function attempts to normalize the time values found in the stat()
** buffer to UTC. This is necessary on Win32, where the runtime library
** appears to return these values as local times.
*/
static void statTimesToUtc(
const char *zPath,
STRUCT_STAT *pStatBuf
){
HANDLE hFindFile;
WIN32_FIND_DATAW fd;
LPWSTR zUnicodeName;
extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath);
if( zUnicodeName ){
memset(&fd, 0, sizeof(WIN32_FIND_DATAW));
hFindFile = FindFirstFileW(zUnicodeName, &fd);
if( hFindFile!=NULL ){
pStatBuf->st_ctime = (time_t)fileTimeToUnixTime(&fd.ftCreationTime);
pStatBuf->st_atime = (time_t)fileTimeToUnixTime(&fd.ftLastAccessTime);
pStatBuf->st_mtime = (time_t)fileTimeToUnixTime(&fd.ftLastWriteTime);
FindClose(hFindFile);
}
sqlite3_free(zUnicodeName);
}
}
#endif
/*
** This function is used in place of stat(). On Windows, special handling
@@ -271,23 +321,14 @@ static int fileStat(
STRUCT_STAT *pStatBuf
){
#if defined(_WIN32)
sqlite3_int64 sz = strlen(zPath);
wchar_t *b1 = sqlite3_malloc64( (sz+1)*sizeof(b1[0]) );
int rc;
wchar_t *b1 = sqlite3_win32_utf8_to_unicode(zPath);
if( b1==0 ) return 1;
sz = MultiByteToWideChar(CP_UTF8, 0, zPath, sz, b1, sz);
b1[sz] = 0;
rc = _wstat(b1, pStatBuf);
if( rc==0 ){
HANDLE hFindFile;
WIN32_FIND_DATAW fd;
memset(&fd, 0, sizeof(WIN32_FIND_DATAW));
hFindFile = FindFirstFileW(b1, &fd);
if( hFindFile!=NULL ){
pStatBuf->st_ctime = (time_t)fileTimeToUnixTime(&fd.ftCreationTime);
pStatBuf->st_atime = (time_t)fileTimeToUnixTime(&fd.ftLastAccessTime);
pStatBuf->st_mtime = (time_t)fileTimeToUnixTime(&fd.ftLastWriteTime);
FindClose(hFindFile);
}
}
sqlite3_free(b1);
if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
return rc;
#else
return stat(zPath, pStatBuf);
@@ -418,6 +459,7 @@ static int writeFile(
if( mtime>=0 ){
#if defined(_WIN32)
#if !SQLITE_OS_WINRT
/* Windows */
FILETIME lastAccess;
FILETIME lastWrite;
@@ -448,6 +490,7 @@ static int writeFile(
}else{
return 1;
}
#endif
#elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */
/* Recent unix */
struct timespec times[2];
@@ -613,7 +656,7 @@ static int fsdirConnect(
(void)pzErr;
rc = sqlite3_declare_vtab(db, "CREATE TABLE x" FSDIR_SCHEMA);
if( rc==SQLITE_OK ){
pNew = (fsdir_tab*)sqlite3_malloc64( sizeof(*pNew) );
pNew = (fsdir_tab*)sqlite3_malloc( sizeof(*pNew) );
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
@@ -636,7 +679,7 @@ static int fsdirDisconnect(sqlite3_vtab *pVtab){
static int fsdirOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
fsdir_cursor *pCur;
(void)p;
pCur = sqlite3_malloc64( sizeof(*pCur) );
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
pCur->iLvl = -1;
@@ -717,7 +760,7 @@ static int fsdirNext(sqlite3_vtab_cursor *cur){
pCur->zPath = 0;
pLvl->pDir = opendir(pLvl->zDir);
if( pLvl->pDir==0 ){
fsdirSetErrmsg(pCur, "cannot read directory: %s", pLvl->zDir);
fsdirSetErrmsg(pCur, "cannot read directory: %s", pCur->zPath);
return SQLITE_ERROR;
}
}
@@ -1051,154 +1094,6 @@ static int fsdirRegister(sqlite3 *db){
# define fsdirRegister(x) SQLITE_OK
#endif
/*
** This version of realpath() works on any system. The string
** returned is held in memory allocated using sqlite3_malloc64().
** The caller is responsible for calling sqlite3_free().
*/
static char *portable_realpath(const char *zPath){
#if !defined(_WIN32) /* BEGIN unix */
char *zOut = 0; /* Result */
char *z; /* Temporary buffer */
#if defined(PATH_MAX)
char zBuf[PATH_MAX+1]; /* Space for the temporary buffer */
#endif
if( zPath==0 ) return 0;
#if defined(PATH_MAX)
z = realpath(zPath, zBuf);
if( z ){
zOut = sqlite3_mprintf("%s", zBuf);
}
#endif /* defined(PATH_MAX) */
if( zOut==0 ){
/* Try POSIX.1-2008 malloc behavior */
z = realpath(zPath, NULL);
if( z ){
zOut = sqlite3_mprintf("%s", z);
free(z);
}
}
return zOut;
#else /* End UNIX, Begin WINDOWS */
wchar_t *zPath16; /* UTF16 translation of zPath */
char *zOut = 0; /* Result */
wchar_t *z = 0; /* Temporary buffer */
if( zPath==0 ) return 0;
zPath16 = sqlite3_win32_utf8_to_unicode(zPath);
if( zPath16==0 ) return 0;
z = _wfullpath(NULL, zPath16, 0);
sqlite3_free(zPath16);
if( z ){
zOut = sqlite3_win32_unicode_to_utf8(z);
free(z);
}
return zOut;
#endif /* End WINDOWS, Begin common code */
}
/*
** SQL function: realpath(X)
**
** Try to convert file or pathname X into its real, absolute pathname.
** Return NULL if unable.
**
** The file or directory X is not required to exist. The answer is formed
** by calling system realpath() on the prefix of X that does exist and
** appending the tail of X that does not (yet) exist.
*/
static void realpathFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
const char *zPath; /* Original input path */
char *zCopy; /* An editable copy of zPath */
char *zOut; /* The result */
char cSep = 0; /* Separator turned into \000 */
size_t len; /* Prefix length before cSep */
#ifdef _WIN32
const int isWin = 1;
#else
const int isWin = 0;
#endif
(void)argc;
zPath = (const char*)sqlite3_value_text(argv[0]);
if( zPath==0 ) return;
if( zPath[0]==0 ) zPath = ".";
zCopy = sqlite3_mprintf("%s",zPath);
len = strlen(zCopy);
while( len>1 && (zCopy[len-1]=='/' || (isWin && zCopy[len-1]=='\\')) ){
len--;
}
zCopy[len] = 0;
while( 1 /*exit-by-break*/ ){
zOut = portable_realpath(zCopy);
zCopy[len] = cSep;
if( zOut ){
if( cSep ){
zOut = sqlite3_mprintf("%z%s",zOut,&zCopy[len]);
}
break;
}else{
size_t i = len-1;
while( i>0 ){
if( zCopy[i]=='/' || (isWin && zCopy[i]=='\\') ) break;
i--;
}
if( i<=0 ){
if( zCopy[0]=='/' ){
zOut = zCopy;
zCopy = 0;
}else if( (zOut = portable_realpath("."))!=0 ){
zOut = sqlite3_mprintf("%z/%s", zOut, zCopy);
}
break;
}
cSep = zCopy[i];
zCopy[i] = 0;
len = i;
}
}
sqlite3_free(zCopy);
if( zOut ){
/* Simplify any "/./" or "/../" that might have snuck into the
** pathname due to appending of zCopy. We only have to consider
** unix "/" separators, because the _wfilepath() system call on
** Windows will have already done this simplification for us. */
size_t i, j, n;
n = strlen(zOut);
for(i=j=0; i<n; i++){
if( zOut[i]=='/' ){
if( zOut[i+1]=='/' ) continue;
if( zOut[i+1]=='.' && i+2<n && zOut[i+2]=='/' ){
i += 1;
continue;
}
if( zOut[i+1]=='.' && i+3<n && zOut[i+2]=='.' && zOut[i+3]=='/' ){
while( j>0 && zOut[j-1]!='/' ){ j--; }
if( j>0 ){ j--; }
i += 2;
continue;
}
}
zOut[j++] = zOut[i];
}
zOut[j] = 0;
/* Return the result */
sqlite3_result_text(context, zOut, -1, sqlite3_free);
}
}
#ifdef _WIN32
__declspec(dllexport)
#endif
@@ -1225,10 +1120,13 @@ int sqlite3_fileio_init(
if( rc==SQLITE_OK ){
rc = fsdirRegister(db);
}
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "realpath", 1,
SQLITE_UTF8, 0,
realpathFunc, 0, 0);
}
return rc;
}
#if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
/* To allow a standalone DLL, make test_windirent.c use the same
* redefined SQLite API calls as the above extension code does.
* Just pull in this .c to accomplish this. As a beneficial side
* effect, this extension becomes a single translation unit. */
# include "test_windirent.c"
#endif
+14 -30
View File
@@ -27,7 +27,7 @@
** This delta format is used by the RBU extension, which is the main
** reason that these routines are included in the extension library.
** RBU does not use this extension directly. Rather, this extension is
** provided as a convenience to developers who want to analyze RBU files
** provided as a convenience to developers who want to analyze RBU files
** that contain deltas.
*/
#include <string.h>
@@ -38,11 +38,9 @@ SQLITE_EXTENSION_INIT1
#ifndef SQLITE_AMALGAMATION
/*
** The "u32" type must be an unsigned 32-bit integer. "u64" is
** an unsigned 64-bit integer.
** The "u32" type must be an unsigned 32-bit integer. Adjust this
*/
typedef unsigned int u32;
typedef sqlite3_uint64 u64;
/*
** Must be a 16-bit value
@@ -543,8 +541,8 @@ static int delta_apply(
int lenDelta, /* Length of the delta */
char *zOut /* Write the output into this preallocated buffer */
){
sqlite3_uint64 limit;
sqlite3_uint64 total = 0;
unsigned int limit;
unsigned int total = 0;
#ifdef FOSSIL_ENABLE_DELTA_CKSUM_TEST
char *zOrigOut = zOut;
#endif
@@ -572,7 +570,7 @@ static int delta_apply(
/* ERROR: copy exceeds output file size */
return -1;
}
if( (u64)ofst+(u64)cnt > (u64)lenSrc ){
if( ofst+cnt > lenSrc ){
/* ERROR: copy extends past end of input */
return -1;
}
@@ -843,7 +841,7 @@ static int deltaparsevtabDisconnect(sqlite3_vtab *pVtab){
*/
static int deltaparsevtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
deltaparsevtab_cursor *pCur;
pCur = sqlite3_malloc64( sizeof(*pCur) );
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
*ppCursor = &pCur->base;
@@ -870,21 +868,11 @@ static int deltaparsevtabNext(sqlite3_vtab_cursor *cur){
int i = 0;
pCur->iCursor = pCur->iNext;
if( pCur->iCursor >= pCur->nDelta ){
pCur->eOp = DELTAPARSE_OP_ERROR;
pCur->iNext = pCur->nDelta;
return SQLITE_OK;
}
z = pCur->aDelta + pCur->iCursor;
pCur->a1 = deltaGetInt(&z, &i);
switch( z[0] ){
case '@': {
z++;
if( pCur->iNext>=pCur->nDelta ){
pCur->eOp = DELTAPARSE_OP_ERROR;
pCur->iNext = pCur->nDelta;
break;
}
pCur->a2 = deltaGetInt(&z, &i);
pCur->eOp = DELTAPARSE_OP_COPY;
pCur->iNext = (int)(&z[1] - pCur->aDelta);
@@ -938,12 +926,8 @@ static int deltaparsevtabColumn(
if( pCur->eOp==DELTAPARSE_OP_COPY ){
sqlite3_result_int(ctx, pCur->a2);
}else if( pCur->eOp==DELTAPARSE_OP_INSERT ){
if( pCur->a2 + pCur->a1 > pCur->nDelta ){
sqlite3_result_zeroblob(ctx, pCur->a1);
}else{
sqlite3_result_blob(ctx, pCur->aDelta+pCur->a2, pCur->a1,
SQLITE_TRANSIENT);
}
sqlite3_result_blob(ctx, pCur->aDelta+pCur->a2, pCur->a1,
SQLITE_TRANSIENT);
}
break;
}
@@ -971,17 +955,17 @@ static int deltaparsevtabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
*/
static int deltaparsevtabEof(sqlite3_vtab_cursor *cur){
deltaparsevtab_cursor *pCur = (deltaparsevtab_cursor*)cur;
return pCur->eOp==DELTAPARSE_OP_EOF || pCur->iCursor>=pCur->nDelta;
return pCur->eOp==DELTAPARSE_OP_EOF;
}
/*
** This method is called to "rewind" the deltaparsevtab_cursor object back
** to the first row of output. This method is always called at least
** once prior to any call to deltaparsevtabColumn() or deltaparsevtabRowid() or
** once prior to any call to deltaparsevtabColumn() or deltaparsevtabRowid() or
** deltaparsevtabEof().
*/
static int deltaparsevtabFilter(
sqlite3_vtab_cursor *pVtabCursor,
sqlite3_vtab_cursor *pVtabCursor,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv
){
@@ -1047,7 +1031,7 @@ static int deltaparsevtabBestIndex(
}
/*
** This following structure defines all the methods for the
** This following structure defines all the methods for the
** virtual table.
*/
static sqlite3_module deltaparsevtabModule = {
@@ -1084,8 +1068,8 @@ static sqlite3_module deltaparsevtabModule = {
__declspec(dllexport)
#endif
int sqlite3_fossildelta_init(
sqlite3 *db,
char **pzErrMsg,
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
static const int enc = SQLITE_UTF8|SQLITE_INNOCUOUS;
+3 -3
View File
@@ -556,7 +556,7 @@ static int fuzzerConnect(
static int fuzzerOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
fuzzer_vtab *p = (fuzzer_vtab*)pVTab;
fuzzer_cursor *pCur;
pCur = sqlite3_malloc64( sizeof(*pCur) );
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
pCur->pVtab = p;
@@ -617,12 +617,12 @@ static int fuzzerRender(
int *pnBuf /* Size of the buffer */
){
const fuzzer_rule *pRule = pStem->pRule;
sqlite3_int64 n; /* Size of output term without nul-term */
int n; /* Size of output term without nul-term */
char *z; /* Buffer to assemble output term in */
n = pStem->nBasis + pRule->nTo - pRule->nFrom;
if( (*pnBuf)<n+1 ){
(*pzBuf) = sqlite3_realloc64((*pzBuf), n+100);
(*pzBuf) = sqlite3_realloc((*pzBuf), n+100);
if( (*pzBuf)==0 ) return SQLITE_NOMEM;
(*pnBuf) = n+100;
}
+1 -38
View File
@@ -134,9 +134,6 @@ static void ieee754func(
if( a==0 ){
e = 0;
m = 0;
}else if( a==(sqlite3_int64)0x8000000000000000LL ){
e = -1996;
m = -1;
}else{
e = a>>52;
m = a & ((((sqlite3_int64)1)<<52)-1);
@@ -179,9 +176,9 @@ static void ieee754func(
}
if( m<0 ){
if( m<(-9223372036854775807LL) ) return;
isNeg = 1;
m = -m;
if( m<0 ) return;
}else if( m==0 && e>-1000 && e<1000 ){
sqlite3_result_double(context, 0.0);
return;
@@ -259,38 +256,6 @@ static void ieee754func_to_blob(
}
}
/*
** Functions to convert between 64-bit integers and floats.
**
** The bit patterns are copied. The numeric values are different.
*/
static void ieee754func_from_int(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
UNUSED_PARAMETER(argc);
if( sqlite3_value_type(argv[0])==SQLITE_INTEGER ){
double r;
sqlite3_int64 v = sqlite3_value_int64(argv[0]);
memcpy(&r, &v, sizeof(r));
sqlite3_result_double(context, r);
}
}
static void ieee754func_to_int(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
UNUSED_PARAMETER(argc);
if( sqlite3_value_type(argv[0])==SQLITE_FLOAT ){
double r = sqlite3_value_double(argv[0]);
sqlite3_uint64 v;
memcpy(&v, &r, sizeof(v));
sqlite3_result_int64(context, v);
}
}
/*
** SQL Function: ieee754_inc(r,N)
**
@@ -343,8 +308,6 @@ int sqlite3_ieee_init(
{ "ieee754_exponent", 1, 2, ieee754func },
{ "ieee754_to_blob", 1, 0, ieee754func_to_blob },
{ "ieee754_from_blob", 1, 0, ieee754func_from_blob },
{ "ieee754_to_int", 1, 0, ieee754func_to_int },
{ "ieee754_from_int", 1, 0, ieee754func_from_int },
{ "ieee754_inc", 2, 0, ieee754inc },
};
unsigned int i;
+2 -2
View File
@@ -85,7 +85,7 @@ static int memstatConnect(
rc = sqlite3_declare_vtab(db,"CREATE TABLE x(name,schema,value,hiwtr)");
if( rc==SQLITE_OK ){
pNew = sqlite3_malloc64( sizeof(*pNew) );
pNew = sqlite3_malloc( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
@@ -107,7 +107,7 @@ static int memstatDisconnect(sqlite3_vtab *pVtab){
*/
static int memstatOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
memstat_cursor *pCur;
pCur = sqlite3_malloc64( sizeof(*pCur) );
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
pCur->db = ((memstat_vtab*)p)->db;
+575
View File
@@ -0,0 +1,575 @@
/*
** 2016-09-07
**
** 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 is an in-memory VFS implementation. The application supplies
** a chunk of memory to hold the database file.
**
** Because there is place to store a rollback or wal journal, the database
** must use one of journal_mode=MEMORY or journal_mode=NONE.
**
** USAGE:
**
** sqlite3_open_v2("file:/whatever?ptr=0xf05538&sz=14336&max=65536", &db,
** SQLITE_OPEN_READWRITE | SQLITE_OPEN_URI,
** "memvfs");
**
** These are the query parameters:
**
** ptr= The address of the memory buffer that holds the database.
**
** sz= The current size the database file
**
** maxsz= The maximum size of the database. In other words, the
** amount of space allocated for the ptr= buffer.
**
** freeonclose= If true, then sqlite3_free() is called on the ptr=
** value when the connection closes.
**
** The ptr= and sz= query parameters are required. If maxsz= is omitted,
** then it defaults to the sz= value. Parameter values can be in either
** decimal or hexadecimal. The filename in the URI is ignored.
*/
#include <sqlite3ext.h>
SQLITE_EXTENSION_INIT1
#include <string.h>
#include <assert.h>
/*
** Forward declaration of objects used by this utility
*/
typedef struct sqlite3_vfs MemVfs;
typedef struct MemFile MemFile;
/* Access to a lower-level VFS that (might) implement dynamic loading,
** access to randomness, etc.
*/
#define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
/* An open file */
struct MemFile {
sqlite3_file base; /* IO methods */
sqlite3_int64 sz; /* Size of the file */
sqlite3_int64 szMax; /* Space allocated to aData */
unsigned char *aData; /* content of the file */
int bFreeOnClose; /* Invoke sqlite3_free() on aData at close */
};
/*
** Methods for MemFile
*/
static int memClose(sqlite3_file*);
static int memRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
static int memWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
static int memTruncate(sqlite3_file*, sqlite3_int64 size);
static int memSync(sqlite3_file*, int flags);
static int memFileSize(sqlite3_file*, sqlite3_int64 *pSize);
static int memLock(sqlite3_file*, int);
static int memUnlock(sqlite3_file*, int);
static int memCheckReservedLock(sqlite3_file*, int *pResOut);
static int memFileControl(sqlite3_file*, int op, void *pArg);
static int memSectorSize(sqlite3_file*);
static int memDeviceCharacteristics(sqlite3_file*);
static int memShmMap(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
static int memShmLock(sqlite3_file*, int offset, int n, int flags);
static void memShmBarrier(sqlite3_file*);
static int memShmUnmap(sqlite3_file*, int deleteFlag);
static int memFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
static int memUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p);
/*
** Methods for MemVfs
*/
static int memOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
static int memDelete(sqlite3_vfs*, const char *zName, int syncDir);
static int memAccess(sqlite3_vfs*, const char *zName, int flags, int *);
static int memFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
static void *memDlOpen(sqlite3_vfs*, const char *zFilename);
static void memDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
static void (*memDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void);
static void memDlClose(sqlite3_vfs*, void*);
static int memRandomness(sqlite3_vfs*, int nByte, char *zOut);
static int memSleep(sqlite3_vfs*, int microseconds);
static int memCurrentTime(sqlite3_vfs*, double*);
static int memGetLastError(sqlite3_vfs*, int, char *);
static int memCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
static sqlite3_vfs mem_vfs = {
2, /* iVersion */
0, /* szOsFile (set when registered) */
1024, /* mxPathname */
0, /* pNext */
"memvfs", /* zName */
0, /* pAppData (set when registered) */
memOpen, /* xOpen */
memDelete, /* xDelete */
memAccess, /* xAccess */
memFullPathname, /* xFullPathname */
memDlOpen, /* xDlOpen */
memDlError, /* xDlError */
memDlSym, /* xDlSym */
memDlClose, /* xDlClose */
memRandomness, /* xRandomness */
memSleep, /* xSleep */
memCurrentTime, /* xCurrentTime */
memGetLastError, /* xGetLastError */
memCurrentTimeInt64 /* xCurrentTimeInt64 */
};
static const sqlite3_io_methods mem_io_methods = {
3, /* iVersion */
memClose, /* xClose */
memRead, /* xRead */
memWrite, /* xWrite */
memTruncate, /* xTruncate */
memSync, /* xSync */
memFileSize, /* xFileSize */
memLock, /* xLock */
memUnlock, /* xUnlock */
memCheckReservedLock, /* xCheckReservedLock */
memFileControl, /* xFileControl */
memSectorSize, /* xSectorSize */
memDeviceCharacteristics, /* xDeviceCharacteristics */
memShmMap, /* xShmMap */
memShmLock, /* xShmLock */
memShmBarrier, /* xShmBarrier */
memShmUnmap, /* xShmUnmap */
memFetch, /* xFetch */
memUnfetch /* xUnfetch */
};
/*
** Close an mem-file.
**
** The pData pointer is owned by the application, so there is nothing
** to free.
*/
static int memClose(sqlite3_file *pFile){
MemFile *p = (MemFile *)pFile;
if( p->bFreeOnClose ) sqlite3_free(p->aData);
return SQLITE_OK;
}
/*
** Read data from an mem-file.
*/
static int memRead(
sqlite3_file *pFile,
void *zBuf,
int iAmt,
sqlite_int64 iOfst
){
MemFile *p = (MemFile *)pFile;
memcpy(zBuf, p->aData+iOfst, iAmt);
return SQLITE_OK;
}
/*
** Write data to an mem-file.
*/
static int memWrite(
sqlite3_file *pFile,
const void *z,
int iAmt,
sqlite_int64 iOfst
){
MemFile *p = (MemFile *)pFile;
if( iOfst+iAmt>p->sz ){
if( iOfst+iAmt>p->szMax ) return SQLITE_FULL;
if( iOfst>p->sz ) memset(p->aData+p->sz, 0, iOfst-p->sz);
p->sz = iOfst+iAmt;
}
memcpy(p->aData+iOfst, z, iAmt);
return SQLITE_OK;
}
/*
** Truncate an mem-file.
*/
static int memTruncate(sqlite3_file *pFile, sqlite_int64 size){
MemFile *p = (MemFile *)pFile;
if( size>p->sz ){
if( size>p->szMax ) return SQLITE_FULL;
memset(p->aData+p->sz, 0, size-p->sz);
}
p->sz = size;
return SQLITE_OK;
}
/*
** Sync an mem-file.
*/
static int memSync(sqlite3_file *pFile, int flags){
return SQLITE_OK;
}
/*
** Return the current file-size of an mem-file.
*/
static int memFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
MemFile *p = (MemFile *)pFile;
*pSize = p->sz;
return SQLITE_OK;
}
/*
** Lock an mem-file.
*/
static int memLock(sqlite3_file *pFile, int eLock){
return SQLITE_OK;
}
/*
** Unlock an mem-file.
*/
static int memUnlock(sqlite3_file *pFile, int eLock){
return SQLITE_OK;
}
/*
** Check if another file-handle holds a RESERVED lock on an mem-file.
*/
static int memCheckReservedLock(sqlite3_file *pFile, int *pResOut){
*pResOut = 0;
return SQLITE_OK;
}
/*
** File control method. For custom operations on an mem-file.
*/
static int memFileControl(sqlite3_file *pFile, int op, void *pArg){
MemFile *p = (MemFile *)pFile;
int rc = SQLITE_NOTFOUND;
if( op==SQLITE_FCNTL_VFSNAME ){
*(char**)pArg = sqlite3_mprintf("mem(%p,%lld)", p->aData, p->sz);
rc = SQLITE_OK;
}
return rc;
}
/*
** Return the sector-size in bytes for an mem-file.
*/
static int memSectorSize(sqlite3_file *pFile){
return 1024;
}
/*
** Return the device characteristic flags supported by an mem-file.
*/
static int memDeviceCharacteristics(sqlite3_file *pFile){
return SQLITE_IOCAP_ATOMIC |
SQLITE_IOCAP_POWERSAFE_OVERWRITE |
SQLITE_IOCAP_SAFE_APPEND |
SQLITE_IOCAP_SEQUENTIAL;
}
/* Create a shared memory file mapping */
static int memShmMap(
sqlite3_file *pFile,
int iPg,
int pgsz,
int bExtend,
void volatile **pp
){
return SQLITE_IOERR_SHMMAP;
}
/* Perform locking on a shared-memory segment */
static int memShmLock(sqlite3_file *pFile, int offset, int n, int flags){
return SQLITE_IOERR_SHMLOCK;
}
/* Memory barrier operation on shared memory */
static void memShmBarrier(sqlite3_file *pFile){
return;
}
/* Unmap a shared memory segment */
static int memShmUnmap(sqlite3_file *pFile, int deleteFlag){
return SQLITE_OK;
}
/* Fetch a page of a memory-mapped file */
static int memFetch(
sqlite3_file *pFile,
sqlite3_int64 iOfst,
int iAmt,
void **pp
){
MemFile *p = (MemFile *)pFile;
*pp = (void*)(p->aData + iOfst);
return SQLITE_OK;
}
/* Release a memory-mapped page */
static int memUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
return SQLITE_OK;
}
/*
** Open an mem file handle.
*/
static int memOpen(
sqlite3_vfs *pVfs,
const char *zName,
sqlite3_file *pFile,
int flags,
int *pOutFlags
){
MemFile *p = (MemFile*)pFile;
memset(p, 0, sizeof(*p));
if( (flags & SQLITE_OPEN_MAIN_DB)==0 ) return SQLITE_CANTOPEN;
p->aData = (unsigned char*)sqlite3_uri_int64(zName,"ptr",0);
if( p->aData==0 ) return SQLITE_CANTOPEN;
p->sz = sqlite3_uri_int64(zName,"sz",0);
if( p->sz<0 ) return SQLITE_CANTOPEN;
p->szMax = sqlite3_uri_int64(zName,"max",p->sz);
if( p->szMax<p->sz ) return SQLITE_CANTOPEN;
p->bFreeOnClose = sqlite3_uri_boolean(zName,"freeonclose",0);
pFile->pMethods = &mem_io_methods;
return SQLITE_OK;
}
/*
** Delete the file located at zPath. If the dirSync argument is true,
** ensure the file-system modifications are synced to disk before
** returning.
*/
static int memDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
return SQLITE_IOERR_DELETE;
}
/*
** Test for access permissions. Return true if the requested permission
** is available, or false otherwise.
*/
static int memAccess(
sqlite3_vfs *pVfs,
const char *zPath,
int flags,
int *pResOut
){
*pResOut = 0;
return SQLITE_OK;
}
/*
** Populate buffer zOut with the full canonical pathname corresponding
** to the pathname in zPath. zOut is guaranteed to point to a buffer
** of at least (INST_MAX_PATHNAME+1) bytes.
*/
static int memFullPathname(
sqlite3_vfs *pVfs,
const char *zPath,
int nOut,
char *zOut
){
sqlite3_snprintf(nOut, zOut, "%s", zPath);
return SQLITE_OK;
}
/*
** Open the dynamic library located at zPath and return a handle.
*/
static void *memDlOpen(sqlite3_vfs *pVfs, const char *zPath){
return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath);
}
/*
** Populate the buffer zErrMsg (size nByte bytes) with a human readable
** utf-8 string describing the most recent error encountered associated
** with dynamic libraries.
*/
static void memDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg);
}
/*
** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
*/
static void (*memDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym);
}
/*
** Close the dynamic library handle pHandle.
*/
static void memDlClose(sqlite3_vfs *pVfs, void *pHandle){
ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle);
}
/*
** Populate the buffer pointed to by zBufOut with nByte bytes of
** random data.
*/
static int memRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
}
/*
** Sleep for nMicro microseconds. Return the number of microseconds
** actually slept.
*/
static int memSleep(sqlite3_vfs *pVfs, int nMicro){
return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro);
}
/*
** Return the current time as a Julian Day number in *pTimeOut.
*/
static int memCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
}
static int memGetLastError(sqlite3_vfs *pVfs, int a, char *b){
return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
}
static int memCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p);
}
#ifdef MEMVFS_TEST
/*
** memvfs_from_file(FILENAME, MAXSIZE)
**
** This an SQL function used to help in testing the memvfs VFS. The
** function reads the content of a file into memory and then returns
** a URI that can be handed to ATTACH to attach the memory buffer as
** a database. Example:
**
** ATTACH memvfs_from_file('test.db',1048576) AS inmem;
**
** The optional MAXSIZE argument gives the size of the memory allocation
** used to hold the database. If omitted, it defaults to the size of the
** file on disk.
*/
#include <stdio.h>
static void memvfsFromFileFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
unsigned char *p;
sqlite3_int64 sz;
sqlite3_int64 szMax;
FILE *in;
const char *zFilename = (const char*)sqlite3_value_text(argv[0]);
char *zUri;
if( zFilename==0 ) return;
in = fopen(zFilename, "rb");
if( in==0 ) return;
fseek(in, 0, SEEK_END);
szMax = sz = ftell(in);
rewind(in);
if( argc>=2 ){
szMax = sqlite3_value_int64(argv[1]);
if( szMax<sz ) szMax = sz;
}
p = sqlite3_malloc64( szMax );
if( p==0 ){
fclose(in);
sqlite3_result_error_nomem(context);
return;
}
fread(p, sz, 1, in);
fclose(in);
zUri = sqlite3_mprintf(
"file:/mem?vfs=memvfs&ptr=%lld&sz=%lld&max=%lld&freeonclose=1",
(sqlite3_int64)p, sz, szMax);
sqlite3_result_text(context, zUri, -1, sqlite3_free);
}
#endif /* MEMVFS_TEST */
#ifdef MEMVFS_TEST
/*
** memvfs_to_file(SCHEMA, FILENAME)
**
** The schema identified by SCHEMA must be a memvfs database. Write
** the content of this database into FILENAME.
*/
static void memvfsToFileFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
MemFile *p = 0;
FILE *out;
int rc;
sqlite3 *db = sqlite3_context_db_handle(context);
sqlite3_vfs *pVfs = 0;
const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
const char *zFilename = (const char*)sqlite3_value_text(argv[1]);
if( zFilename==0 ) return;
out = fopen(zFilename, "wb");
if( out==0 ) return;
rc = sqlite3_file_control(db, zSchema, SQLITE_FCNTL_VFS_POINTER, &pVfs);
if( rc || pVfs==0 ) return;
if( strcmp(pVfs->zName,"memvfs")!=0 ) return;
rc = sqlite3_file_control(db, zSchema, SQLITE_FCNTL_FILE_POINTER, &p);
if( rc ) return;
fwrite(p->aData, 1, (size_t)p->sz, out);
fclose(out);
}
#endif /* MEMVFS_TEST */
#ifdef MEMVFS_TEST
/* Called for each new database connection */
static int memvfsRegister(
sqlite3 *db,
char **pzErrMsg,
const struct sqlite3_api_routines *pThunk
){
sqlite3_create_function(db, "memvfs_from_file", 1, SQLITE_UTF8, 0,
memvfsFromFileFunc, 0, 0);
sqlite3_create_function(db, "memvfs_from_file", 2, SQLITE_UTF8, 0,
memvfsFromFileFunc, 0, 0);
sqlite3_create_function(db, "memvfs_to_file", 2, SQLITE_UTF8, 0,
memvfsToFileFunc, 0, 0);
return SQLITE_OK;
}
#endif /* MEMVFS_TEST */
#ifdef _WIN32
__declspec(dllexport)
#endif
/*
** This routine is called when the extension is loaded.
** Register the new VFS.
*/
int sqlite3_memvfs_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
mem_vfs.pAppData = sqlite3_vfs_find(0);
if( mem_vfs.pAppData==0 ) return SQLITE_ERROR;
mem_vfs.szOsFile = sizeof(MemFile);
rc = sqlite3_vfs_register(&mem_vfs, 1);
#ifdef MEMVFS_TEST
if( rc==SQLITE_OK ){
rc = sqlite3_auto_extension((void(*)(void))memvfsRegister);
}
if( rc==SQLITE_OK ){
rc = memvfsRegister(db, pzErrMsg, pApi);
}
#endif
if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
return rc;
}
+3 -4
View File
@@ -297,9 +297,8 @@ static const unsigned char sqlite3CtypeMap[256] = {
** Return the length (in bytes) of the token that begins at z[0].
** Store the token type in *tokenType before returning.
*/
static sqlite3_int64 sqlite3GetToken(const unsigned char *z, int *tokenType){
sqlite3_int64 i;
int c;
static int sqlite3GetToken(const unsigned char *z, int *tokenType){
int i, c;
switch( aiClass[*z] ){ /* Switch on the character-class of the first byte
** of the token. See the comment on the CC_ defines
** above. */
@@ -560,7 +559,7 @@ char *sqlite3_normalize(const char *zSql){
int i; /* Next character to read from zSql[] */
int j; /* Next slot to fill in on z[] */
int tokenType; /* Type of the next token */
sqlite3_int64 n; /* Size of the next token */
int n; /* Size of the next token */
int k; /* Loop counter */
nSql = strlen(zSql);
+2 -2
View File
@@ -75,7 +75,7 @@ static int prefixesConnect(
"CREATE TABLE prefixes(prefix TEXT, original_string TEXT HIDDEN)"
);
if( rc==SQLITE_OK ){
pNew = sqlite3_malloc64( sizeof(*pNew) );
pNew = sqlite3_malloc( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
@@ -98,7 +98,7 @@ static int prefixesDisconnect(sqlite3_vtab *pVtab){
*/
static int prefixesOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
prefixes_cursor *pCur;
pCur = sqlite3_malloc64( sizeof(*pCur) );
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
*ppCursor = &pCur->base;
+2 -2
View File
@@ -152,7 +152,7 @@ static int qpvtabConnect(
#define QPVTAB_FLAGS 11
#define QPVTAB_NONE 12
if( rc==SQLITE_OK ){
pNew = sqlite3_malloc64( sizeof(*pNew) );
pNew = sqlite3_malloc( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
@@ -174,7 +174,7 @@ static int qpvtabDisconnect(sqlite3_vtab *pVtab){
*/
static int qpvtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
qpvtab_cursor *pCur;
pCur = sqlite3_malloc64( sizeof(*pCur) );
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
*ppCursor = &pCur->base;
+47 -93
View File
@@ -32,7 +32,7 @@
** ^X X occurring at the beginning of the string
** X$ X occurring at the end of the string
** . Match any single character
** \c Character c where c is one of \{}()[]|*+?-.
** \c Character c where c is one of \{}()[]|*+?.
** \c C-language escapes for c in afnrtv. ex: \t or \n
** \uXXXX Where XXXX is exactly 4 hex digits, unicode value XXXX
** \xXX Where XX is exactly 2 hex digits, unicode value XX
@@ -55,8 +55,6 @@
** to p copies of X following by q-p copies of X? and that the size of the
** regular expression in the O(N*M) performance bound is computed after
** this expansion.
**
** To help prevent DoS attacks, the maximum size of the NFA is restricted.
*/
#include <string.h>
#include <stdlib.h>
@@ -98,6 +96,32 @@ SQLITE_EXTENSION_INIT1
#define RE_OP_BOUNDARY 17 /* Boundary between word and non-word */
#define RE_OP_ATSTART 18 /* Currently at the start of the string */
#if defined(SQLITE_DEBUG)
/* Opcode names used for symbolic debugging */
static const char *ReOpName[] = {
"EOF",
"MATCH",
"ANY",
"ANYSTAR",
"FORK",
"GOTO",
"ACCEPT",
"CC_INC",
"CC_EXC",
"CC_VALUE",
"CC_RANGE",
"WORD",
"NOTWORD",
"DIGIT",
"NOTDIGIT",
"SPACE",
"NOTSPACE",
"BOUNDARY",
"ATSTART",
};
#endif /* SQLITE_DEBUG */
/* Each opcode is a "state" in the NFA */
typedef unsigned short ReStateNumber;
@@ -134,7 +158,6 @@ struct ReCompiled {
int nInit; /* Number of bytes in zInit */
unsigned nState; /* Number of entries in aOp[] and aArg[] */
unsigned nAlloc; /* Slots allocated for aOp[] and aArg[] */
unsigned mxAlloc; /* Complexity limit */
};
/* Add a state to the given state set if it is not already there */
@@ -349,15 +372,14 @@ re_match_end:
/* Resize the opcode and argument arrays for an RE under construction.
*/
static int re_resize(ReCompiled *p, unsigned int N){
static int re_resize(ReCompiled *p, int N){
char *aOp;
int *aArg;
if( N>p->mxAlloc ){ p->zErr = "REGEXP pattern too big"; return 1; }
aOp = sqlite3_realloc64(p->aOp, N*sizeof(p->aOp[0]));
if( aOp==0 ){ p->zErr = "out of memory"; return 1; }
if( aOp==0 ) return 1;
p->aOp = aOp;
aArg = sqlite3_realloc64(p->aArg, N*sizeof(p->aArg[0]));
if( aArg==0 ){ p->zErr = "out of memory"; return 1; }
if( aArg==0 ) return 1;
p->aArg = aArg;
p->nAlloc = N;
return 0;
@@ -388,7 +410,7 @@ static int re_append(ReCompiled *p, int op, int arg){
/* Make a copy of N opcodes starting at iStart onto the end of the RE
** under construction.
*/
static void re_copy(ReCompiled *p, int iStart, unsigned int N){
static void re_copy(ReCompiled *p, int iStart, int N){
if( p->nState+N>=p->nAlloc && re_resize(p, p->nAlloc*2+N) ) return;
memcpy(&p->aOp[p->nState], &p->aOp[iStart], N*sizeof(p->aOp[0]));
memcpy(&p->aArg[p->nState], &p->aArg[iStart], N*sizeof(p->aArg[0]));
@@ -417,7 +439,7 @@ static int re_hex(int c, int *pV){
** return its interpretation.
*/
static unsigned re_esc_char(ReCompiled *p){
static const char zEsc[] = "afnrtv\\()*.+?[$^{|}]-";
static const char zEsc[] = "afnrtv\\()*.+?[$^{|}]";
static const char zTrans[] = "\a\f\n\r\t\v";
int i, v = 0;
char c;
@@ -541,26 +563,18 @@ static const char *re_subcompile_string(ReCompiled *p){
break;
}
case '{': {
unsigned int m = 0, n = 0;
unsigned int sz, j;
int m = 0, n = 0;
int sz, j;
if( iPrev<0 ) return "'{m,n}' without operand";
while( (c=rePeek(p))>='0' && c<='9' ){
m = m*10 + c - '0';
if( m*2>p->mxAlloc ) return "REGEXP pattern too big";
p->sIn.i++;
}
while( (c=rePeek(p))>='0' && c<='9' ){ m = m*10 + c - '0'; p->sIn.i++; }
n = m;
if( c==',' ){
p->sIn.i++;
n = 0;
while( (c=rePeek(p))>='0' && c<='9' ){
n = n*10 + c-'0';
if( n*2>p->mxAlloc ) return "REGEXP pattern too big";
p->sIn.i++;
}
while( (c=rePeek(p))>='0' && c<='9' ){ n = n*10 + c-'0'; p->sIn.i++; }
}
if( c!='}' ) return "unmatched '{'";
if( n<m ) return "n less than m in '{m,n}'";
if( n>0 && n<m ) return "n less than m in '{m,n}'";
p->sIn.i++;
sz = p->nState - iPrev;
if( m==0 ){
@@ -576,7 +590,7 @@ static const char *re_subcompile_string(ReCompiled *p){
re_copy(p, iPrev, sz);
}
if( n==0 && m>0 ){
re_append(p, RE_OP_FORK, -(int)sz);
re_append(p, RE_OP_FORK, -sz);
}
break;
}
@@ -642,7 +656,8 @@ static const char *re_subcompile_string(ReCompiled *p){
** regular expression. Applications should invoke this routine once
** for every call to re_compile() to avoid memory leaks.
*/
static void re_free(ReCompiled *pRe){
static void re_free(void *p){
ReCompiled *pRe = (ReCompiled*)p;
if( pRe ){
sqlite3_free(pRe->aOp);
sqlite3_free(pRe->aArg);
@@ -650,43 +665,27 @@ static void re_free(ReCompiled *pRe){
}
}
/*
** Version of re_free() that accepts a pointer of type (void*). Required
** to satisfy sanitizers when the re_free() function is called via a
** function pointer.
*/
static void re_free_voidptr(void *p){
re_free((ReCompiled*)p);
}
/*
** Compile a textual regular expression in zIn[] into a compiled regular
** expression suitable for us by re_match() and return a pointer to the
** compiled regular expression in *ppRe. Return NULL on success or an
** error message if something goes wrong.
*/
static const char *re_compile(
ReCompiled **ppRe, /* OUT: write compiled NFA here */
const char *zIn, /* Input regular expression */
int mxRe, /* Complexity limit */
int noCase /* True for caseless comparisons */
){
static const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){
ReCompiled *pRe;
const char *zErr;
int i, j;
*ppRe = 0;
pRe = sqlite3_malloc64( sizeof(*pRe) );
pRe = sqlite3_malloc( sizeof(*pRe) );
if( pRe==0 ){
return "out of memory";
}
memset(pRe, 0, sizeof(*pRe));
pRe->xNextChar = noCase ? re_next_char_nocase : re_next_char;
pRe->mxAlloc = mxRe;
if( re_resize(pRe, 30) ){
zErr = pRe->zErr;
re_free(pRe);
return zErr;
return "out of memory";
}
if( zIn[0]=='^' ){
zIn++;
@@ -739,21 +738,6 @@ static const char *re_compile(
return pRe->zErr;
}
/*
** The value of LIMIT_MAX_PATTERN_LENGTH.
*/
static int re_maxlen(sqlite3_context *context){
sqlite3 *db = sqlite3_context_db_handle(context);
return sqlite3_limit(db, SQLITE_LIMIT_LIKE_PATTERN_LENGTH,-1);
}
/*
** Maximum NFA size given a maximum pattern length.
*/
static int re_maxnfa(int mxlen){
return 75+mxlen/2;
}
/*
** Implementation of the regexp() SQL function. This function implements
** the build-in REGEXP operator. The first argument to the function is the
@@ -777,17 +761,9 @@ static void re_sql_func(
(void)argc; /* Unused */
pRe = sqlite3_get_auxdata(context, 0);
if( pRe==0 ){
int mxLen = re_maxlen(context);
int nPattern;
zPattern = (const char*)sqlite3_value_text(argv[0]);
if( zPattern==0 ) return;
nPattern = sqlite3_value_bytes(argv[0]);
if( nPattern>mxLen ){
zErr = "REGEXP pattern too big";
}else{
zErr = re_compile(&pRe, zPattern, re_maxnfa(mxLen),
sqlite3_user_data(context)!=0);
}
zErr = re_compile(&pRe, zPattern, sqlite3_user_data(context)!=0);
if( zErr ){
re_free(pRe);
sqlite3_result_error(context, zErr, -1);
@@ -804,7 +780,7 @@ static void re_sql_func(
sqlite3_result_int(context, re_match(pRe, zStr, -1));
}
if( setAux ){
sqlite3_set_auxdata(context, 0, pRe, re_free_voidptr);
sqlite3_set_auxdata(context, 0, pRe, (void(*)(void*))re_free);
}
}
@@ -828,33 +804,11 @@ static void re_bytecode_func(
int i;
int n;
char *z;
static const char *ReOpName[] = {
"EOF",
"MATCH",
"ANY",
"ANYSTAR",
"FORK",
"GOTO",
"ACCEPT",
"CC_INC",
"CC_EXC",
"CC_VALUE",
"CC_RANGE",
"WORD",
"NOTWORD",
"DIGIT",
"NOTDIGIT",
"SPACE",
"NOTSPACE",
"BOUNDARY",
"ATSTART",
};
(void)argc;
zPattern = (const char*)sqlite3_value_text(argv[0]);
if( zPattern==0 ) return;
zErr = re_compile(&pRe, zPattern, re_maxnfa(re_maxlen(context)),
sqlite3_user_data(context)!=0);
zErr = re_compile(&pRe, zPattern, sqlite3_user_data(context)!=0);
if( zErr ){
re_free(pRe);
sqlite3_result_error(context, zErr, -1);
+1 -1
View File
@@ -92,7 +92,7 @@ static void scrubBackupErr(ScrubState *p, const char *zFormat, ...){
static u8 *scrubBackupAllocPage(ScrubState *p){
u8 *pPage;
if( p->rcErr ) return 0;
pPage = sqlite3_malloc64( p->szPage );
pPage = sqlite3_malloc( p->szPage );
if( pPage==0 ) p->rcErr = SQLITE_NOMEM;
return pPage;
}
+232 -301
View File
@@ -30,20 +30,19 @@
** SELECT * FROM generate_series(0,100,5);
**
** The query above returns integers from 0 through 100 counting by steps
** of 5. In other words, 0, 5, 10, 15, ..., 90, 95, 100. There are a total
** of 21 rows.
** of 5.
**
** SELECT * FROM generate_series(0,100);
**
** Integers from 0 through 100 with a step size of 1. 101 rows.
** Integers from 0 through 100 with a step size of 1.
**
** SELECT * FROM generate_series(20) LIMIT 10;
**
** Integers 20 through 29. 10 rows.
** Integers 20 through 29.
**
** SELECT * FROM generate_series(0,-100,-5);
**
** Integers 0 -5 -10 ... -100. 21 rows.
** Integers 0 -5 -10 ... -100.
**
** SELECT * FROM generate_series(0,-1);
**
@@ -119,89 +118,140 @@ SQLITE_EXTENSION_INIT1
#include <math.h>
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Return that member of a generate_series(...) sequence whose 0-based
** index is ix. The 0th member is given by smBase. The sequence members
** progress per ix increment by smStep.
*/
static sqlite3_int64 genSeqMember(
sqlite3_int64 smBase,
sqlite3_int64 smStep,
sqlite3_uint64 ix
){
static const sqlite3_uint64 mxI64 =
((sqlite3_uint64)0x7fffffff)<<32 | 0xffffffff;
if( ix>=mxI64 ){
/* Get ix into signed i64 range. */
ix -= mxI64;
/* With 2's complement ALU, this next can be 1 step, but is split into
* 2 for UBSAN's satisfaction (and hypothetical 1's complement ALUs.) */
smBase += (mxI64/2) * smStep;
smBase += (mxI64 - mxI64/2) * smStep;
}
/* Under UBSAN (or on 1's complement machines), must do this last term
* in steps to avoid the dreaded (and harmless) signed multiply overflow. */
if( ix>=2 ){
sqlite3_int64 ix2 = (sqlite3_int64)ix/2;
smBase += ix2*smStep;
ix -= ix2;
}
return smBase + ((sqlite3_int64)ix)*smStep;
}
typedef unsigned char u8;
typedef struct SequenceSpec {
sqlite3_int64 iOBase; /* Original starting value ("start") */
sqlite3_int64 iOTerm; /* Original terminal value ("stop") */
sqlite3_int64 iBase; /* Starting value to actually use */
sqlite3_int64 iTerm; /* Terminal value to actually use */
sqlite3_int64 iStep; /* Increment ("step") */
sqlite3_uint64 uSeqIndexMax; /* maximum sequence index (aka "n") */
sqlite3_uint64 uSeqIndexNow; /* Current index during generation */
sqlite3_int64 iValueNow; /* Current value during generation */
u8 isNotEOF; /* Sequence generation not exhausted */
u8 isReversing; /* Sequence is being reverse generated */
} SequenceSpec;
/*
** Prepare a SequenceSpec for use in generating an integer series
** given initialized iBase, iTerm and iStep values. Sequence is
** initialized per given isReversing. Other members are computed.
*/
static void setupSequence( SequenceSpec *pss ){
int bSameSigns;
pss->uSeqIndexMax = 0;
pss->isNotEOF = 0;
bSameSigns = (pss->iBase < 0)==(pss->iTerm < 0);
if( pss->iTerm < pss->iBase ){
sqlite3_uint64 nuspan = 0;
if( bSameSigns ){
nuspan = (sqlite3_uint64)(pss->iBase - pss->iTerm);
}else{
/* Under UBSAN (or on 1's complement machines), must do this in steps.
* In this clause, iBase>=0 and iTerm<0 . */
nuspan = 1;
nuspan += pss->iBase;
nuspan += -(pss->iTerm+1);
}
if( pss->iStep<0 ){
pss->isNotEOF = 1;
if( nuspan==ULONG_MAX ){
pss->uSeqIndexMax = ( pss->iStep>LLONG_MIN )? nuspan/-pss->iStep : 1;
}else if( pss->iStep>LLONG_MIN ){
pss->uSeqIndexMax = nuspan/-pss->iStep;
}
}
}else if( pss->iTerm > pss->iBase ){
sqlite3_uint64 puspan = 0;
if( bSameSigns ){
puspan = (sqlite3_uint64)(pss->iTerm - pss->iBase);
}else{
/* Under UBSAN (or on 1's complement machines), must do this in steps.
* In this clause, iTerm>=0 and iBase<0 . */
puspan = 1;
puspan += pss->iTerm;
puspan += -(pss->iBase+1);
}
if( pss->iStep>0 ){
pss->isNotEOF = 1;
pss->uSeqIndexMax = puspan/pss->iStep;
}
}else if( pss->iTerm == pss->iBase ){
pss->isNotEOF = 1;
pss->uSeqIndexMax = 0;
}
pss->uSeqIndexNow = (pss->isReversing)? pss->uSeqIndexMax : 0;
pss->iValueNow = (pss->isReversing)
? genSeqMember(pss->iBase, pss->iStep, pss->uSeqIndexMax)
: pss->iBase;
}
/*
** Progress sequence generator to yield next value, if any.
** Leave its state to either yield next value or be at EOF.
** Return whether there is a next value, or 0 at EOF.
*/
static int progressSequence( SequenceSpec *pss ){
if( !pss->isNotEOF ) return 0;
if( pss->isReversing ){
if( pss->uSeqIndexNow > 0 ){
pss->uSeqIndexNow--;
pss->iValueNow -= pss->iStep;
}else{
pss->isNotEOF = 0;
}
}else{
if( pss->uSeqIndexNow < pss->uSeqIndexMax ){
pss->uSeqIndexNow++;
pss->iValueNow += pss->iStep;
}else{
pss->isNotEOF = 0;
}
}
return pss->isNotEOF;
}
/* series_cursor is a subclass of sqlite3_vtab_cursor which will
** serve as the underlying representation of a cursor that scans
** over rows of the result.
**
** iOBase, iOTerm, and iOStep are the original values of the
** start=, stop=, and step= constraints on the query. These are
** the values reported by the start, stop, and step columns of the
** virtual table.
**
** iBase, iTerm, iStep, and bDescp are the actual values used to generate
** the sequence. These might be different from the iOxxxx values.
** For example in
**
** SELECT value FROM generate_series(1,11,2)
** WHERE value BETWEEN 4 AND 8;
**
** The iOBase is 1, but the iBase is 5. iOTerm is 11 but iTerm is 7.
** Another example:
**
** SELECT value FROM generate_series(1,15,3) ORDER BY value DESC;
**
** The cursor initialization for the above query is:
**
** iOBase = 1 iBase = 13
** iOTerm = 15 iTerm = 1
** iOStep = 3 iStep = 3 bDesc = 1
**
** The actual step size is unsigned so that can have a value of
** +9223372036854775808 which is needed for querys like this:
**
** SELECT value
** FROM generate_series(9223372036854775807,
** -9223372036854775808,
** -9223372036854775808)
** ORDER BY value ASC;
**
** The setup for the previous query will be:
**
** iOBase = 9223372036854775807 iBase = -1
** iOTerm = -9223372036854775808 iTerm = 9223372036854775807
** iOStep = -9223372036854775808 iStep = 9223372036854775808 bDesc = 0
** over rows of the result
*/
typedef unsigned char u8;
typedef struct series_cursor series_cursor;
struct series_cursor {
sqlite3_vtab_cursor base; /* Base class - must be first */
sqlite3_int64 iOBase; /* Original starting value ("start") */
sqlite3_int64 iOTerm; /* Original terminal value ("stop") */
sqlite3_int64 iOStep; /* Original step value */
sqlite3_int64 iBase; /* Starting value to actually use */
sqlite3_int64 iTerm; /* Terminal value to actually use */
sqlite3_uint64 iStep; /* The step size */
sqlite3_int64 iValue; /* Current value */
u8 bDesc; /* iStep is really negative */
u8 bDone; /* True if stepped past last element */
SequenceSpec ss; /* (this) Derived class data */
};
/*
** Computed the difference between two 64-bit signed integers using a
** convoluted computation designed to work around the silly restriction
** against signed integer overflow in C.
*/
static sqlite3_uint64 span64(sqlite3_int64 a, sqlite3_int64 b){
assert( a>=b );
return (*(sqlite3_uint64*)&a) - (*(sqlite3_uint64*)&b);
}
/*
** Add or substract an unsigned 64-bit integer from a signed 64-bit integer
** and return the new signed 64-bit integer.
*/
static sqlite3_int64 add64(sqlite3_int64 a, sqlite3_uint64 b){
sqlite3_uint64 x = *(sqlite3_uint64*)&a;
x += b;
return *(sqlite3_int64*)&x;
}
static sqlite3_int64 sub64(sqlite3_int64 a, sqlite3_uint64 b){
sqlite3_uint64 x = *(sqlite3_uint64*)&a;
x -= b;
return *(sqlite3_int64*)&x;
}
/*
** The seriesConnect() method is invoked to create a new
** series_vtab that describes the generate_series virtual table.
@@ -239,7 +289,7 @@ static int seriesConnect(
rc = sqlite3_declare_vtab(db,
"CREATE TABLE x(value,start hidden,stop hidden,step hidden)");
if( rc==SQLITE_OK ){
pNew = *ppVtab = sqlite3_malloc64( sizeof(*pNew) );
pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
@@ -261,7 +311,7 @@ static int seriesDisconnect(sqlite3_vtab *pVtab){
static int seriesOpen(sqlite3_vtab *pUnused, sqlite3_vtab_cursor **ppCursor){
series_cursor *pCur;
(void)pUnused;
pCur = sqlite3_malloc64( sizeof(*pCur) );
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
*ppCursor = &pCur->base;
@@ -282,15 +332,7 @@ static int seriesClose(sqlite3_vtab_cursor *cur){
*/
static int seriesNext(sqlite3_vtab_cursor *cur){
series_cursor *pCur = (series_cursor*)cur;
if( pCur->iValue==pCur->iTerm ){
pCur->bDone = 1;
}else if( pCur->bDesc ){
pCur->iValue = sub64(pCur->iValue, pCur->iStep);
assert( pCur->iValue>=pCur->iTerm );
}else{
pCur->iValue = add64(pCur->iValue, pCur->iStep);
assert( pCur->iValue<=pCur->iTerm );
}
progressSequence( & pCur->ss );
return SQLITE_OK;
}
@@ -306,19 +348,19 @@ static int seriesColumn(
series_cursor *pCur = (series_cursor*)cur;
sqlite3_int64 x = 0;
switch( i ){
case SERIES_COLUMN_START: x = pCur->iOBase; break;
case SERIES_COLUMN_STOP: x = pCur->iOTerm; break;
case SERIES_COLUMN_STEP: x = pCur->iOStep; break;
default: x = pCur->iValue; break;
case SERIES_COLUMN_START: x = pCur->ss.iOBase; break;
case SERIES_COLUMN_STOP: x = pCur->ss.iOTerm; break;
case SERIES_COLUMN_STEP: x = pCur->ss.iStep; break;
default: x = pCur->ss.iValueNow; break;
}
sqlite3_result_int64(ctx, x);
return SQLITE_OK;
}
#ifndef LARGEST_UINT64
#define LARGEST_INT64 ((sqlite3_int64)0x7fffffffffffffffLL)
#define LARGEST_UINT64 ((sqlite3_uint64)0xffffffffffffffffULL)
#define SMALLEST_INT64 ((sqlite3_int64)0x8000000000000000LL)
#define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
#define LARGEST_UINT64 (0xffffffff|(((sqlite3_uint64)0xffffffff)<<32))
#define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
#endif
/*
@@ -326,7 +368,7 @@ static int seriesColumn(
*/
static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
series_cursor *pCur = (series_cursor*)cur;
*pRowid = pCur->iValue;
*pRowid = pCur->ss.iValueNow;
return SQLITE_OK;
}
@@ -336,7 +378,7 @@ static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
*/
static int seriesEof(sqlite3_vtab_cursor *cur){
series_cursor *pCur = (series_cursor*)cur;
return pCur->bDone;
return !pCur->ss.isNotEOF;
}
/* True to cause run-time checking of the start=, stop=, and/or step=
@@ -347,59 +389,6 @@ static int seriesEof(sqlite3_vtab_cursor *cur){
# define SQLITE_SERIES_CONSTRAINT_VERIFY 0
#endif
/*
** Return the number of steps between pCur->iBase and pCur->iTerm if
** the step width is pCur->iStep.
*/
static sqlite3_uint64 seriesSteps(series_cursor *pCur){
if( pCur->bDesc ){
assert( pCur->iBase >= pCur->iTerm );
return span64(pCur->iBase, pCur->iTerm)/pCur->iStep;
}else{
assert( pCur->iBase <= pCur->iTerm );
return span64(pCur->iTerm, pCur->iBase)/pCur->iStep;
}
}
#if defined(SQLITE_ENABLE_MATH_FUNCTIONS) || defined(_WIN32)
/*
** Case 1 (the most common case):
** The standard math library is available so use ceil() and floor() from there.
*/
static double seriesCeil(double r){ return ceil(r); }
static double seriesFloor(double r){ return floor(r); }
#elif defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC)
/*
** Case 2 (2nd most common): Use GCC/Clang builtins
*/
static double seriesCeil(double r){ return __builtin_ceil(r); }
static double seriesFloor(double r){ return __builtin_floor(r); }
#else
/*
** Case 3 (rarely happens): Use home-grown ceil() and floor() routines.
*/
static double seriesCeil(double r){
sqlite3_int64 x;
if( r!=r ) return r;
if( r<=(-4503599627370496.0) ) return r;
if( r>=(+4503599627370496.0) ) return r;
x = (sqlite3_int64)r;
if( r==(double)x ) return r;
if( r>(double)x ) x++;
return (double)x;
}
static double seriesFloor(double r){
sqlite3_int64 x;
if( r!=r ) return r;
if( r<=(-4503599627370496.0) ) return r;
if( r>=(+4503599627370496.0) ) return r;
x = (sqlite3_int64)r;
if( r==(double)x ) return r;
if( r<(double)x ) x--;
return (double)x;
}
#endif
/*
** This method is called to "rewind" the series_cursor object back
** to the first row of output. This method is always called at least
@@ -433,42 +422,33 @@ static int seriesFilter(
int argc, sqlite3_value **argv
){
series_cursor *pCur = (series_cursor *)pVtabCursor;
int iArg = 0; /* Arguments used so far */
int i; /* Loop counter */
sqlite3_int64 iMin = SMALLEST_INT64; /* Smallest allowed output value */
sqlite3_int64 iMax = LARGEST_INT64; /* Largest allowed output value */
sqlite3_int64 iLimit = 0; /* if >0, the value of the LIMIT */
sqlite3_int64 iOffset = 0; /* if >0, the value of the OFFSET */
int i = 0;
int returnNoRows = 0;
sqlite3_int64 iMin = SMALLEST_INT64;
sqlite3_int64 iMax = LARGEST_INT64;
sqlite3_int64 iLimit = 0;
sqlite3_int64 iOffset = 0;
(void)idxStrUnused;
/* If any constraints have a NULL value, then return no rows.
** See ticket https://sqlite.org/src/info/fac496b61722daf2
*/
for(i=0; i<argc; i++){
if( sqlite3_value_type(argv[i])==SQLITE_NULL ){
goto series_no_rows;
}
}
/* Capture the three HIDDEN parameters to the virtual table and insert
** default values for any parameters that are omitted.
*/
if( idxNum & 0x01 ){
pCur->iOBase = sqlite3_value_int64(argv[iArg++]);
pCur->ss.iBase = sqlite3_value_int64(argv[i++]);
}else{
pCur->iOBase = 0;
pCur->ss.iBase = 0;
}
if( idxNum & 0x02 ){
pCur->iOTerm = sqlite3_value_int64(argv[iArg++]);
pCur->ss.iTerm = sqlite3_value_int64(argv[i++]);
}else{
pCur->iOTerm = 0xffffffff;
pCur->ss.iTerm = 0xffffffff;
}
if( idxNum & 0x04 ){
pCur->iOStep = sqlite3_value_int64(argv[iArg++]);
if( pCur->iOStep==0 ) pCur->iOStep = 1;
pCur->ss.iStep = sqlite3_value_int64(argv[i++]);
if( pCur->ss.iStep==0 ){
pCur->ss.iStep = 1;
}else if( pCur->ss.iStep<0 ){
if( (idxNum & 0x10)==0 ) idxNum |= 0x08;
}
}else{
pCur->iOStep = 1;
pCur->ss.iStep = 1;
}
/* If there are constraints on the value column but there are
@@ -478,94 +458,72 @@ static int seriesFilter(
** further below.
*/
if( (idxNum & 0x05)==0 && (idxNum & 0x0380)!=0 ){
pCur->iOBase = SMALLEST_INT64;
pCur->ss.iBase = SMALLEST_INT64;
}
if( (idxNum & 0x06)==0 && (idxNum & 0x3080)!=0 ){
pCur->iOTerm = LARGEST_INT64;
}
pCur->iBase = pCur->iOBase;
pCur->iTerm = pCur->iOTerm;
if( pCur->iOStep>0 ){
pCur->iStep = pCur->iOStep;
}else if( pCur->iOStep>SMALLEST_INT64 ){
pCur->iStep = -pCur->iOStep;
}else{
pCur->iStep = LARGEST_INT64;
pCur->iStep++;
}
pCur->bDesc = pCur->iOStep<0;
if( pCur->bDesc==0 && pCur->iBase>pCur->iTerm ){
goto series_no_rows;
}
if( pCur->bDesc!=0 && pCur->iBase<pCur->iTerm ){
goto series_no_rows;
pCur->ss.iTerm = LARGEST_INT64;
}
pCur->ss.iOBase = pCur->ss.iBase;
pCur->ss.iOTerm = pCur->ss.iTerm;
/* Extract the LIMIT and OFFSET values, but do not apply them yet.
** The range must first be constrained by the limits on value.
*/
if( idxNum & 0x20 ){
iLimit = sqlite3_value_int64(argv[iArg++]);
iLimit = sqlite3_value_int64(argv[i++]);
if( idxNum & 0x40 ){
iOffset = sqlite3_value_int64(argv[iArg++]);
iOffset = sqlite3_value_int64(argv[i++]);
}
}
/* Narrow the range of iMin and iMax (the minimum and maximum outputs)
** based on equality and inequality constraints on the "value" column.
*/
if( idxNum & 0x3380 ){
if( idxNum & 0x0080 ){ /* value=X */
if( sqlite3_value_numeric_type(argv[iArg])==SQLITE_FLOAT ){
double r = sqlite3_value_double(argv[iArg++]);
if( r==seriesCeil(r)
&& r>=(double)SMALLEST_INT64
&& r<=(double)LARGEST_INT64
){
/* Extract the maximum range of output values determined by
** constraints on the "value" column.
*/
if( idxNum & 0x0080 ){
if( sqlite3_value_numeric_type(argv[i])==SQLITE_FLOAT ){
double r = sqlite3_value_double(argv[i++]);
if( r==ceil(r) ){
iMin = iMax = (sqlite3_int64)r;
}else{
goto series_no_rows;
returnNoRows = 1;
}
}else{
iMin = iMax = sqlite3_value_int64(argv[iArg++]);
iMin = iMax = sqlite3_value_int64(argv[i++]);
}
}else{
if( idxNum & 0x0300 ){ /* value>X or value>=X */
if( sqlite3_value_numeric_type(argv[iArg])==SQLITE_FLOAT ){
double r = sqlite3_value_double(argv[iArg++]);
if( r<(double)SMALLEST_INT64 ){
iMin = SMALLEST_INT64;
}else if( (idxNum & 0x0200)!=0 && r==seriesCeil(r) ){
iMin = (sqlite3_int64)seriesCeil(r+1.0);
if( idxNum & 0x0300 ){
if( sqlite3_value_numeric_type(argv[i])==SQLITE_FLOAT ){
double r = sqlite3_value_double(argv[i++]);
if( idxNum & 0x0200 && r==ceil(r) ){
iMin = (sqlite3_int64)ceil(r+1.0);
}else{
iMin = (sqlite3_int64)seriesCeil(r);
iMin = (sqlite3_int64)ceil(r);
}
}else{
iMin = sqlite3_value_int64(argv[iArg++]);
if( (idxNum & 0x0200)!=0 ){
iMin = sqlite3_value_int64(argv[i++]);
if( idxNum & 0x0200 ){
if( iMin==LARGEST_INT64 ){
goto series_no_rows;
returnNoRows = 1;
}else{
iMin++;
}
}
}
}
if( idxNum & 0x3000 ){ /* value<X or value<=X */
if( sqlite3_value_numeric_type(argv[iArg])==SQLITE_FLOAT ){
double r = sqlite3_value_double(argv[iArg++]);
if( r>(double)LARGEST_INT64 ){
iMax = LARGEST_INT64;
}else if( (idxNum & 0x2000)!=0 && r==seriesFloor(r) ){
if( idxNum & 0x3000 ){
if( sqlite3_value_numeric_type(argv[i])==SQLITE_FLOAT ){
double r = sqlite3_value_double(argv[i++]);
if( (idxNum & 0x2000)!=0 && r==floor(r) ){
iMax = (sqlite3_int64)(r-1.0);
}else{
iMax = (sqlite3_int64)seriesFloor(r);
iMax = (sqlite3_int64)floor(r);
}
}else{
iMax = sqlite3_value_int64(argv[iArg++]);
iMax = sqlite3_value_int64(argv[i++]);
if( idxNum & 0x2000 ){
if( iMax==SMALLEST_INT64 ){
goto series_no_rows;
returnNoRows = 1;
}else{
iMax--;
}
@@ -573,99 +531,72 @@ static int seriesFilter(
}
}
if( iMin>iMax ){
goto series_no_rows;
returnNoRows = 1;
}
}
/* Try to reduce the range of values to be generated based on
** constraints on the "value" column.
*/
if( pCur->bDesc==0 ){
if( pCur->iBase<iMin ){
sqlite3_uint64 span = span64(iMin,pCur->iBase);
pCur->iBase = add64(pCur->iBase, (span/pCur->iStep)*pCur->iStep);
if( pCur->iBase<iMin ){
if( pCur->iBase > sub64(LARGEST_INT64, pCur->iStep) ){
goto series_no_rows;
}
pCur->iBase = add64(pCur->iBase, pCur->iStep);
}
if( pCur->ss.iStep>0 ){
sqlite3_int64 szStep = pCur->ss.iStep;
if( pCur->ss.iBase<iMin ){
sqlite3_uint64 d = iMin - pCur->ss.iBase;
pCur->ss.iBase += ((d+szStep-1)/szStep)*szStep;
}
if( pCur->iTerm>iMax ){
pCur->iTerm = iMax;
if( pCur->ss.iTerm>iMax ){
pCur->ss.iTerm = iMax;
}
}else{
if( pCur->iBase>iMax ){
sqlite3_uint64 span = span64(pCur->iBase,iMax);
pCur->iBase = sub64(pCur->iBase, (span/pCur->iStep)*pCur->iStep);
if( pCur->iBase>iMax ){
if( pCur->iBase < add64(SMALLEST_INT64, pCur->iStep) ){
goto series_no_rows;
}
pCur->iBase = sub64(pCur->iBase, pCur->iStep);
}
sqlite3_int64 szStep = -pCur->ss.iStep;
assert( szStep>0 );
if( pCur->ss.iBase>iMax ){
sqlite3_uint64 d = pCur->ss.iBase - iMax;
pCur->ss.iBase -= ((d+szStep-1)/szStep)*szStep;
}
if( pCur->iTerm<iMin ){
pCur->iTerm = iMin;
if( pCur->ss.iTerm<iMin ){
pCur->ss.iTerm = iMin;
}
}
}
/* Adjust iTerm so that it is exactly the last value of the series.
*/
if( pCur->bDesc==0 ){
if( pCur->iBase>pCur->iTerm ){
goto series_no_rows;
}
pCur->iTerm = sub64(pCur->iTerm,
span64(pCur->iTerm,pCur->iBase) % pCur->iStep);
}else{
if( pCur->iBase<pCur->iTerm ){
goto series_no_rows;
}
pCur->iTerm = add64(pCur->iTerm,
span64(pCur->iBase,pCur->iTerm) % pCur->iStep);
}
/* Transform the series generator to output values in the requested
** order.
*/
if( ((idxNum & 0x0008)!=0 && pCur->bDesc==0)
|| ((idxNum & 0x0010)!=0 && pCur->bDesc!=0)
){
sqlite3_int64 tmp = pCur->iBase;
pCur->iBase = pCur->iTerm;
pCur->iTerm = tmp;
pCur->bDesc = !pCur->bDesc;
}
/* Apply LIMIT and OFFSET constraints, if any */
assert( pCur->iStep!=0 );
if( idxNum & 0x20 ){
if( iOffset>0 ){
if( seriesSteps(pCur) < (sqlite3_uint64)iOffset ){
goto series_no_rows;
}else if( pCur->bDesc ){
pCur->iBase = sub64(pCur->iBase, pCur->iStep*iOffset);
pCur->ss.iBase += pCur->ss.iStep*iOffset;
}
if( iLimit>=0 ){
sqlite3_int64 iTerm;
iTerm = pCur->ss.iBase + (iLimit - 1)*pCur->ss.iStep;
if( pCur->ss.iStep<0 ){
if( iTerm>pCur->ss.iTerm ) pCur->ss.iTerm = iTerm;
}else{
pCur->iBase = add64(pCur->iBase, pCur->iStep*iOffset);
if( iTerm<pCur->ss.iTerm ) pCur->ss.iTerm = iTerm;
}
}
if( iLimit>=0 && seriesSteps(pCur) > (sqlite3_uint64)iLimit ){
pCur->iTerm = add64(pCur->iBase, (iLimit - 1)*pCur->iStep);
}
for(i=0; i<argc; i++){
if( sqlite3_value_type(argv[i])==SQLITE_NULL ){
/* If any of the constraints have a NULL value, then return no rows.
** See ticket https://sqlite.org/src/info/fac496b61722daf2 */
returnNoRows = 1;
break;
}
}
pCur->iValue = pCur->iBase;
pCur->bDone = 0;
if( returnNoRows ){
pCur->ss.iBase = 1;
pCur->ss.iTerm = 0;
pCur->ss.iStep = 1;
}
if( idxNum & 0x08 ){
pCur->ss.isReversing = pCur->ss.iStep > 0;
}else{
pCur->ss.isReversing = pCur->ss.iStep < 0;
}
setupSequence( &pCur->ss );
return SQLITE_OK;
series_no_rows:
pCur->iBase = 0;
pCur->iTerm = 0;
pCur->iStep = 1;
pCur->bDesc = 0;
pCur->bDone = 1;
return SQLITE_OK;
}
/*
+7 -16
View File
@@ -230,16 +230,13 @@ static void hash_finish(
*****************************************************************************/
/*
** Two SQL functions: sha1(X) and sha1b(X).
** Implementation of the sha1(X) function.
**
** sha1(X) returns a lower-case hexadecimal rendering of the SHA1 hash
** of the argument X. If X is a BLOB, it is hashed as is. For all other
** Return a lower-case hexadecimal rendering of the SHA1 hash of the
** argument X. If X is a BLOB, it is hashed as is. For all other
** types of input, X is converted into a UTF-8 string and the string
** is hashed without the trailing 0x00 terminator. The hash of a NULL
** is hash without the trailing 0x00 terminator. The hash of a NULL
** value is NULL.
**
** sha1b(X) is the same except that it returns a 20-byte BLOB containing
** the binary hash instead of a hexadecimal string.
*/
static void sha1Func(
sqlite3_context *context,
@@ -249,27 +246,22 @@ static void sha1Func(
SHA1Context cx;
int eType = sqlite3_value_type(argv[0]);
int nByte = sqlite3_value_bytes(argv[0]);
const unsigned char *pData;
char zOut[44];
assert( argc==1 );
if( eType==SQLITE_NULL ) return;
hash_init(&cx);
if( eType==SQLITE_BLOB ){
pData = (const unsigned char*)sqlite3_value_blob(argv[0]);
hash_step(&cx, sqlite3_value_blob(argv[0]), nByte);
}else{
pData = (const unsigned char*)sqlite3_value_text(argv[0]);
hash_step(&cx, sqlite3_value_text(argv[0]), nByte);
}
if( pData==0 ) return;
hash_step(&cx, pData, nByte);
if( sqlite3_user_data(context)!=0 ){
/* sha1b() - binary result */
hash_finish(&cx, zOut, 1);
sqlite3_result_blob(context, zOut, 20, SQLITE_TRANSIENT);
}else{
/* sha1() - hexadecimal text result */
hash_finish(&cx, zOut, 0);
sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT);
sqlite3_result_blob(context, zOut, 40, SQLITE_TRANSIENT);
}
}
@@ -323,7 +315,6 @@ static void sha1QueryFunc(
}
nCol = sqlite3_column_count(pStmt);
z = sqlite3_sql(pStmt);
if( z==0 ) z = "";
n = (int)strlen(z);
hash_step_vformat(&cx,"S%d:",n);
hash_step(&cx,(unsigned char*)z,n);
+3 -3
View File
@@ -46,7 +46,7 @@ static void sqlarCompressFunc(
uLongf nOut = compressBound(nData);
Bytef *pOut;
pOut = (Bytef*)sqlite3_malloc64(nOut);
pOut = (Bytef*)sqlite3_malloc(nOut);
if( pOut==0 ){
sqlite3_result_error_nomem(context);
return;
@@ -84,14 +84,14 @@ static void sqlarUncompressFunc(
sqlite3_int64 sz;
assert( argc==2 );
sz = sqlite3_value_int64(argv[1]);
sz = sqlite3_value_int(argv[1]);
if( sz<=0 || sz==(nData = sqlite3_value_bytes(argv[0])) ){
sqlite3_result_value(context, argv[0]);
}else{
uLongf szf = sz;
const Bytef *pData= sqlite3_value_blob(argv[0]);
Bytef *pOut = sqlite3_malloc64(sz);
Bytef *pOut = sqlite3_malloc(sz);
if( pOut==0 ){
sqlite3_result_error_nomem(context);
}else if( Z_OK!=uncompress(pOut, &szf, pData, nData) ){
+7 -25
View File
@@ -101,8 +101,8 @@ FILE *sqlite3_fopen(const char *zFilename, const char *zMode){
sz1 = (int)strlen(zFilename);
sz2 = (int)strlen(zMode);
b1 = sqlite3_malloc64( (sz1+1)*sizeof(b1[0]) );
b2 = sqlite3_malloc64( (sz2+1)*sizeof(b1[0]) );
b1 = sqlite3_malloc( (sz1+1)*sizeof(b1[0]) );
b2 = sqlite3_malloc( (sz2+1)*sizeof(b1[0]) );
if( b1 && b2 ){
sz1 = MultiByteToWideChar(CP_UTF8, 0, zFilename, sz1, b1, sz1);
b1[sz1] = 0;
@@ -127,8 +127,8 @@ FILE *sqlite3_popen(const char *zCommand, const char *zMode){
sz1 = (int)strlen(zCommand);
sz2 = (int)strlen(zMode);
b1 = sqlite3_malloc64( (sz1+1)*sizeof(b1[0]) );
b2 = sqlite3_malloc64( (sz2+1)*sizeof(b1[0]) );
b1 = sqlite3_malloc( (sz1+1)*sizeof(b1[0]) );
b2 = sqlite3_malloc( (sz2+1)*sizeof(b1[0]) );
if( b1 && b2 ){
sz1 = MultiByteToWideChar(CP_UTF8, 0, zCommand, sz1, b1, sz1);
b1[sz1] = 0;
@@ -151,7 +151,7 @@ char *sqlite3_fgets(char *buf, int sz, FILE *in){
** that into UTF-8. Otherwise, non-ASCII characters all get translated
** into '?'.
*/
wchar_t *b1 = sqlite3_malloc64( sz*sizeof(wchar_t) );
wchar_t *b1 = sqlite3_malloc( sz*sizeof(wchar_t) );
if( b1==0 ) return 0;
#ifdef SQLITE_USE_W32_FOR_CONSOLE_IO
DWORD nRead = 0;
@@ -226,7 +226,7 @@ int sqlite3_fputs(const char *z, FILE *out){
** to the console on Windows.
*/
int sz = (int)strlen(z);
wchar_t *b1 = sqlite3_malloc64( (sz+1)*sizeof(wchar_t) );
wchar_t *b1 = sqlite3_malloc( (sz+1)*sizeof(wchar_t) );
if( b1==0 ) return 0;
sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz);
b1[sz] = 0;
@@ -258,7 +258,7 @@ int sqlite3_fputs(const char *z, FILE *out){
/*
** Work-alikes for fprintf() and vfprintf() from the standard C library.
** Work-alike for fprintf() from the standard C library.
*/
int sqlite3_fprintf(FILE *out, const char *zFormat, ...){
int rc;
@@ -285,24 +285,6 @@ int sqlite3_fprintf(FILE *out, const char *zFormat, ...){
}
return rc;
}
int sqlite3_vfprintf(FILE *out, const char *zFormat, va_list ap){
int rc;
if( UseWtextForOutput(out) ){
/* When writing to the command-prompt in Windows, it is necessary
** to use _O_WTEXT input mode and write UTF-16 characters.
*/
char *z;
z = sqlite3_vmprintf(zFormat, ap);
sqlite3_fputs(z, out);
rc = (int)strlen(z);
sqlite3_free(z);
}else{
/* Writing to a file or other destination, just write bytes without
** any translation. */
rc = vfprintf(out, zFormat, ap);
}
return rc;
}
/*
** Set the mode for an output stream. mode argument is typically _O_BINARY or
-3
View File
@@ -31,7 +31,6 @@
#ifdef _WIN32
/**** Definitions For Windows ****/
#include <stdio.h>
#include <stdarg.h>
#include <windows.h>
FILE *sqlite3_fopen(const char *zFilename, const char *zMode);
@@ -39,7 +38,6 @@ FILE *sqlite3_popen(const char *zCommand, const char *type);
char *sqlite3_fgets(char *s, int size, FILE *stream);
int sqlite3_fputs(const char *s, FILE *stream);
int sqlite3_fprintf(FILE *stream, const char *format, ...);
int sqlite3_vfprintf(FILE *stream, const char *format, va_list);
void sqlite3_fsetmode(FILE *stream, int mode);
@@ -51,7 +49,6 @@ void sqlite3_fsetmode(FILE *stream, int mode);
#define sqlite3_fgets fgets
#define sqlite3_fputs fputs
#define sqlite3_fprintf fprintf
#define sqlite3_vfprintf vfprintf
#define sqlite3_fsetmode(F,X) /*no-op*/
#endif
+1 -1
View File
@@ -52,7 +52,7 @@ static void stmtrandFunc(
p = (Stmtrand*)sqlite3_get_auxdata(context, STMTRAND_KEY);
if( p==0 ){
unsigned int seed;
p = sqlite3_malloc64( sizeof(*p) );
p = sqlite3_malloc( sizeof(*p) );
if( p==0 ){
sqlite3_result_error_nomem(context);
return;
+2 -2
View File
@@ -101,7 +101,7 @@ static int templatevtabConnect(
#define TEMPLATEVTAB_A 0
#define TEMPLATEVTAB_B 1
if( rc==SQLITE_OK ){
pNew = sqlite3_malloc64( sizeof(*pNew) );
pNew = sqlite3_malloc( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
@@ -123,7 +123,7 @@ static int templatevtabDisconnect(sqlite3_vtab *pVtab){
*/
static int templatevtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
templatevtab_cursor *pCur;
pCur = sqlite3_malloc64( sizeof(*pCur) );
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
*ppCursor = &pCur->base;
-1042
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -613,7 +613,7 @@ static int vstattabConnect(
rc = sqlite3_declare_vtab(db,"CREATE TABLE x(file,stat,count)");
if( rc==SQLITE_OK ){
pNew = *ppVtab = sqlite3_malloc64( sizeof(*pNew) );
pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
}
@@ -633,7 +633,7 @@ static int vstattabDisconnect(sqlite3_vtab *pVtab){
*/
static int vstattabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
VfsStatCursor *pCur;
pCur = sqlite3_malloc64( sizeof(*pCur) );
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
*ppCursor = &pCur->base;
+1 -1
View File
@@ -892,7 +892,7 @@ static int vfstraceOpen(
vfstrace_printf(pInfo, "%s.xOpen(%s,flags=0x%x)",
pInfo->zVfsName, p->zFName, flags);
if( p->pReal->pMethods ){
sqlite3_io_methods *pNew = sqlite3_malloc64( sizeof(*pNew) );
sqlite3_io_methods *pNew = sqlite3_malloc( sizeof(*pNew) );
const sqlite3_io_methods *pSub = p->pReal->pMethods;
memset(pNew, 0, sizeof(*pNew));
pNew->iVersion = pSub->iVersion;
+8 -54
View File
@@ -14,8 +14,6 @@
** on stdout when its key interfaces are called. This is intended for
** interactive analysis and debugging of virtual table interfaces.
**
** HOW TO COMPILE:
**
** To build this extension as a separately loaded shared library or
** DLL, use compiler command-lines similar to the following:
**
@@ -23,7 +21,7 @@
** (mac) clang -fPIC -dynamiclib vtablog.c -o vtablog.dylib
** (windows) cl vtablog.c -link -dll -out:vtablog.dll
**
** USAGE EXAMPLE:
** Usage example:
**
** .load ./vtablog
** CREATE VIRTUAL TABLE temp.log USING vtablog(
@@ -31,23 +29,6 @@
** rows=25
** );
** SELECT * FROM log;
**
** ARGUMENTS TO CREATE VIRTUAL TABLE:
**
** In "CREATE VIRTUAL TABLE temp.log AS vtablog(ARGS....)" statement, the
** ARGS argument is a list of key-value pairs that can be any of the
** following.
**
** schema=TEXT Text is a CREATE TABLE statement that defines
** the schema of the new virtual table.
**
** rows=N The table as N rows.
**
** consume_order_by=N If the left-most ORDER BY terms is ASC and
** against column N (where the leftmost column
** is #1) then set the orderByConsumed=1 flag in
** xBestIndex. Or if the left-most ORDER BY is
** DESC and against column -N, do likewise.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
@@ -68,8 +49,6 @@ struct vtablog_vtab {
char *zName; /* Table name. argv[2] of xConnect/xCreate */
int nRow; /* Number of rows in the table */
int nCursor; /* Number of cursors created */
int iConsumeOB; /* Consume the ORDER BY clause if on column N-th
** and consumeOB=N or consumeOB=(-N) and DESC */
};
/* vtablog_cursor is a subclass of sqlite3_vtab_cursor which will
@@ -201,7 +180,6 @@ static int vtablogConnectCreate(
int rc;
char *zSchema = 0;
char *zNRow = 0;
char *zConsumeOB = 0;
printf("%s.%s.%s():\n", argv[1], argv[2],
isCreate ? "xCreate" : "xConnect");
@@ -225,32 +203,20 @@ static int vtablogConnectCreate(
rc = SQLITE_ERROR;
goto vtablog_end_connect;
}
if( vtablog_string_parameter(pzErr, "consume_order_by", z, &zConsumeOB) ){
rc = SQLITE_ERROR;
goto vtablog_end_connect;
}
}
if( zSchema==0 ){
zSchema = sqlite3_mprintf("%s","CREATE TABLE x(a,b);");
if( zSchema==0 ){
rc = SQLITE_NOMEM;
goto vtablog_end_connect;
}
}
printf(" schema = '%s'\n", zSchema);
rc = sqlite3_declare_vtab(db, zSchema);
if( rc==SQLITE_OK ){
pNew = sqlite3_malloc64( sizeof(*pNew) );
pNew = sqlite3_malloc( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
pNew->nRow = 10;
if( zNRow ) pNew->nRow = atoi(zNRow);
printf(" nrow = %d\n", pNew->nRow);
if( zConsumeOB ) pNew->iConsumeOB = atoi(zConsumeOB);
if( pNew->iConsumeOB ){
printf(" consume_order_by = %d\n", pNew->iConsumeOB);
}
pNew->zDb = sqlite3_mprintf("%s", argv[1]);
pNew->zName = sqlite3_mprintf("%s", argv[2]);
}
@@ -258,7 +224,6 @@ static int vtablogConnectCreate(
vtablog_end_connect:
sqlite3_free(zSchema);
sqlite3_free(zNRow);
sqlite3_free(zConsumeOB);
return rc;
}
static int vtablogCreate(
@@ -313,7 +278,7 @@ static int vtablogOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
vtablog_cursor *pCur;
printf("%s.%s.xOpen(cursor=%d)\n", pTab->zDb, pTab->zName,
++pTab->nCursor);
pCur = sqlite3_malloc64( sizeof(*pCur) );
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
pCur->iCursor = pTab->nCursor;
@@ -545,27 +510,16 @@ static int vtablogBestIndex(
}
}
printf(" nOrderBy: %d\n", p->nOrderBy);
if( p->nOrderBy ){
for(i=0; i<p->nOrderBy; i++){
printf(" orderby[%d]: col=%d desc=%d\n",
i,
p->aOrderBy[i].iColumn,
p->aOrderBy[i].desc);
}
if( pTab->iConsumeOB ){
int N = p->aOrderBy[0].iColumn+1;
if( (p->aOrderBy[0].desc && N==-pTab->iConsumeOB)
|| (!p->aOrderBy[0].desc && N==pTab->iConsumeOB)
){
p->orderByConsumed = 1;
}
}
for(i=0; i<p->nOrderBy; i++){
printf(" orderby[%d]: col=%d desc=%d\n",
i,
p->aOrderBy[i].iColumn,
p->aOrderBy[i].desc);
}
p->estimatedCost = (double)500;
p->estimatedRows = 500;
printf(" idxNum=%d\n", p->idxNum);
printf(" idxStr=NULL\n");
printf(" sqlite3_vtab_distinct()=%d\n", sqlite3_vtab_distinct(p));
printf(" orderByConsumed=%d\n", p->orderByConsumed);
printf(" estimatedCost=%g\n", p->estimatedCost);
printf(" estimatedRows=%lld\n", p->estimatedRows);
+5 -5
View File
@@ -86,7 +86,7 @@ static int vtshimCreate(
}
return SQLITE_ERROR;
}
pNew = sqlite3_malloc64( sizeof(*pNew) );
pNew = sqlite3_malloc( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
@@ -125,7 +125,7 @@ static int vtshimConnect(
}
return SQLITE_ERROR;
}
pNew = sqlite3_malloc64( sizeof(*pNew) );
pNew = sqlite3_malloc( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
@@ -192,7 +192,7 @@ static int vtshimOpen(sqlite3_vtab *pBase, sqlite3_vtab_cursor **ppCursor){
int rc;
*ppCursor = 0;
if( pAux->bDisposed ) return SQLITE_ERROR;
pCur = sqlite3_malloc64( sizeof(*pCur) );
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
rc = pAux->pMod->xOpen(pVtab->pChild, &pCur->pChild);
@@ -444,7 +444,7 @@ static int vtshimCopyModule(
){
sqlite3_module *p;
if( !pMod || !ppMod ) return SQLITE_ERROR;
p = sqlite3_malloc64( sizeof(*p) );
p = sqlite3_malloc( sizeof(*p) );
if( p==0 ) return SQLITE_NOMEM;
memcpy(p, pMod, sizeof(*p));
*ppMod = p;
@@ -464,7 +464,7 @@ void *sqlite3_create_disposable_module(
vtshim_aux *pAux;
sqlite3_module *pMod;
int rc;
pAux = sqlite3_malloc64( sizeof(*pAux) );
pAux = sqlite3_malloc( sizeof(*pAux) );
if( pAux==0 ){
if( xDestroy ) xDestroy(pClientData);
return 0;
+2 -2
View File
@@ -47,7 +47,7 @@ static int wholenumberConnect(
char **pzErr
){
sqlite3_vtab *pNew;
pNew = *ppVtab = sqlite3_malloc64( sizeof(*pNew) );
pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
if( pNew==0 ) return SQLITE_NOMEM;
sqlite3_declare_vtab(db, "CREATE TABLE x(value)");
sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
@@ -69,7 +69,7 @@ static int wholenumberDisconnect(sqlite3_vtab *pVtab){
*/
static int wholenumberOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
wholenumber_cursor *pCur;
pCur = sqlite3_malloc64( sizeof(*pCur) );
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
*ppCursor = &pCur->base;
+32 -61
View File
@@ -115,14 +115,9 @@ static const char ZIPFILE_SCHEMA[] =
") WITHOUT ROWID;";
#define ZIPFILE_F_COLUMN_IDX 7 /* Index of column "file" in the above */
#define ZIPFILE_BUFFER_SIZE (64*1024)
#define ZIPFILE_MX_NAME (250) /* Windows limitation on filename size */
/*
** The buffer should be large enough to contain 3 65536 byte strings - the
** filename, the extra field and the file comment.
*/
#define ZIPFILE_BUFFER_SIZE (200*1024)
/*
** Magic numbers used to read and write zip files.
@@ -393,7 +388,7 @@ static int zipfileConnect(
rc = sqlite3_declare_vtab(db, ZIPFILE_SCHEMA);
if( rc==SQLITE_OK ){
pNew = (ZipfileTab*)sqlite3_malloc64((i64)nByte+nFile);
pNew = (ZipfileTab*)sqlite3_malloc64((sqlite3_int64)nByte+nFile);
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, nByte+nFile);
pNew->db = db;
@@ -456,7 +451,7 @@ static int zipfileDisconnect(sqlite3_vtab *pVtab){
static int zipfileOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCsr){
ZipfileTab *pTab = (ZipfileTab*)p;
ZipfileCsr *pCsr;
pCsr = sqlite3_malloc64(sizeof(*pCsr));
pCsr = sqlite3_malloc(sizeof(*pCsr));
*ppCsr = (sqlite3_vtab_cursor*)pCsr;
if( pCsr==0 ){
return SQLITE_NOMEM;
@@ -539,15 +534,14 @@ static void zipfileCursorErr(ZipfileCsr *pCsr, const char *zFmt, ...){
static int zipfileReadData(
FILE *pFile, /* Read from this file */
u8 *aRead, /* Read into this buffer */
i64 nRead, /* Number of bytes to read */
int nRead, /* Number of bytes to read */
i64 iOff, /* Offset to read from */
char **pzErrmsg /* OUT: Error message (from sqlite3_malloc) */
){
size_t n;
fseek(pFile, (long)iOff, SEEK_SET);
n = fread(aRead, 1, (long)nRead, pFile);
if( n!=(size_t)nRead ){
sqlite3_free(*pzErrmsg);
n = fread(aRead, 1, nRead, pFile);
if( (int)n!=nRead ){
*pzErrmsg = sqlite3_mprintf("error in fread()");
return SQLITE_ERROR;
}
@@ -564,7 +558,7 @@ static int zipfileAppendData(
fseek(pTab->pWriteFd, (long)pTab->szCurrent, SEEK_SET);
n = fwrite(aWrite, 1, nWrite, pTab->pWriteFd);
if( (int)n!=nWrite ){
zipfileTableErr(pTab,"error in fwrite()");
pTab->base.zErrMsg = sqlite3_mprintf("error in fwrite()");
return SQLITE_ERROR;
}
pTab->szCurrent += nWrite;
@@ -705,12 +699,7 @@ static int zipfileScanExtra(u8 *aExtra, int nExtra, u32 *pmTime){
u8 *p = aExtra;
u8 *pEnd = &aExtra[nExtra];
/* Stop when there are less than 9 bytes left to scan in the buffer. This
** is because the timestamp field requires exactly 9 bytes - 4 bytes of
** header fields and 5 bytes of data. If there are less than 9 bytes
** remaining, either it is some other field or else the extra data
** is corrupt. Either way, do not process it. */
while( p+(2*sizeof(u16) + 1 + sizeof(u32))<=pEnd ){
while( p<pEnd ){
u16 id = zipfileRead16(p);
u16 nByte = zipfileRead16(p);
@@ -811,16 +800,6 @@ static void zipfileMtimeToDos(ZipfileCDS *pCds, u32 mUnixTime){
);
}
/*
** Set (*pzErr) to point to a buffer from sqlite3_malloc() containing a
** generic corruption message and return SQLITE_CORRUPT;
*/
static int zipfileCorrupt(char **pzErr){
sqlite3_free(*pzErr);
*pzErr = sqlite3_mprintf("zip archive is corrupt");
return SQLITE_CORRUPT;
}
/*
** If aBlob is not NULL, then it is a pointer to a buffer (nBlob bytes in
** size) containing an entire zip archive image. Or, if aBlob is NULL,
@@ -835,7 +814,7 @@ static int zipfileCorrupt(char **pzErr){
static int zipfileGetEntry(
ZipfileTab *pTab, /* Store any error message here */
const u8 *aBlob, /* Pointer to in-memory file image */
i64 nBlob, /* Size of aBlob[] in bytes */
int nBlob, /* Size of aBlob[] in bytes */
FILE *pFile, /* If aBlob==0, read from this file */
i64 iOff, /* Offset of CDS record */
ZipfileEntry **ppEntry /* OUT: Pointer to new object */
@@ -843,15 +822,12 @@ static int zipfileGetEntry(
u8 *aRead;
char **pzErr = &pTab->base.zErrMsg;
int rc = SQLITE_OK;
(void)nBlob;
if( aBlob==0 ){
aRead = pTab->aBuffer;
rc = zipfileReadData(pFile, aRead, ZIPFILE_CDS_FIXED_SZ, iOff, pzErr);
}else{
if( (iOff+ZIPFILE_CDS_FIXED_SZ)>nBlob ){
/* Not enough data for the CDS structure. Corruption. */
return zipfileCorrupt(pzErr);
}
aRead = (u8*)&aBlob[iOff];
}
@@ -875,16 +851,13 @@ static int zipfileGetEntry(
memset(pNew, 0, sizeof(ZipfileEntry));
rc = zipfileReadCDS(aRead, &pNew->cds);
if( rc!=SQLITE_OK ){
zipfileTableErr(pTab, "failed to read CDS at offset %lld", iOff);
*pzErr = sqlite3_mprintf("failed to read CDS at offset %lld", iOff);
}else if( aBlob==0 ){
rc = zipfileReadData(
pFile, aRead, nExtra+nFile, iOff+ZIPFILE_CDS_FIXED_SZ, pzErr
);
}else{
aRead = (u8*)&aBlob[iOff + ZIPFILE_CDS_FIXED_SZ];
if( (iOff + ZIPFILE_CDS_FIXED_SZ + nFile + nExtra)>nBlob ){
rc = zipfileCorrupt(pzErr);
}
}
}
@@ -907,26 +880,22 @@ static int zipfileGetEntry(
rc = zipfileReadData(pFile, aRead, szFix, pNew->cds.iOffset, pzErr);
}else{
aRead = (u8*)&aBlob[pNew->cds.iOffset];
if( ((i64)pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ)>nBlob ){
rc = zipfileCorrupt(pzErr);
}
}
memset(&lfh, 0, sizeof(lfh));
if( rc==SQLITE_OK ) rc = zipfileReadLFH(aRead, &lfh);
if( rc==SQLITE_OK ){
pNew->iDataOff = (i64)pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ;
pNew->iDataOff = pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ;
pNew->iDataOff += lfh.nFile + lfh.nExtra;
if( aBlob && pNew->cds.szCompressed ){
if( pNew->iDataOff + pNew->cds.szCompressed > nBlob ){
rc = zipfileCorrupt(pzErr);
rc = SQLITE_CORRUPT;
}else{
pNew->aData = &pNew->aExtra[nExtra];
memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed);
}
}
}else{
zipfileTableErr(pTab, "failed to read LFH at offset %d",
*pzErr = sqlite3_mprintf("failed to read LFH at offset %d",
(int)pNew->cds.iOffset
);
}
@@ -950,7 +919,7 @@ static int zipfileNext(sqlite3_vtab_cursor *cur){
int rc = SQLITE_OK;
if( pCsr->pFile ){
i64 iEof = (i64)pCsr->eocd.iOffset + (i64)pCsr->eocd.nSize;
i64 iEof = pCsr->eocd.iOffset + pCsr->eocd.nSize;
zipfileEntryFree(pCsr->pCurrent);
pCsr->pCurrent = 0;
if( pCsr->iNextOff>=iEof ){
@@ -995,7 +964,7 @@ static void zipfileInflate(
int nIn, /* Size of buffer aIn[] in bytes */
int nOut /* Expected output size */
){
u8 *aRes = sqlite3_malloc64(nOut);
u8 *aRes = sqlite3_malloc(nOut);
if( aRes==0 ){
sqlite3_result_error_nomem(pCtx);
}else{
@@ -1016,7 +985,7 @@ static void zipfileInflate(
if( err!=Z_STREAM_END ){
zipfileCtxErrorMsg(pCtx, "inflate() failed (%d)", err);
}else{
sqlite3_result_blob(pCtx, aRes, (int)str.total_out, zipfileFree);
sqlite3_result_blob(pCtx, aRes, nOut, zipfileFree);
aRes = 0;
}
}
@@ -1188,12 +1157,12 @@ static int zipfileEof(sqlite3_vtab_cursor *cur){
static int zipfileReadEOCD(
ZipfileTab *pTab, /* Return errors here */
const u8 *aBlob, /* Pointer to in-memory file image */
i64 nBlob, /* Size of aBlob[] in bytes */
int nBlob, /* Size of aBlob[] in bytes */
FILE *pFile, /* Read from this file if aBlob==0 */
ZipfileEOCD *pEOCD /* Object to populate */
){
u8 *aRead = pTab->aBuffer; /* Temporary buffer */
i64 nRead; /* Bytes to read from file */
int nRead; /* Bytes to read from file */
int rc = SQLITE_OK;
memset(pEOCD, 0, sizeof(ZipfileEOCD));
@@ -1214,7 +1183,7 @@ static int zipfileReadEOCD(
}
if( rc==SQLITE_OK ){
i64 i;
int i;
/* Scan backwards looking for the signature bytes */
for(i=nRead-20; i>=0; i--){
@@ -1225,7 +1194,9 @@ static int zipfileReadEOCD(
}
}
if( i<0 ){
zipfileTableErr(pTab, "cannot find end of central directory record");
pTab->base.zErrMsg = sqlite3_mprintf(
"cannot find end of central directory record"
);
return SQLITE_ERROR;
}
@@ -1270,7 +1241,7 @@ static void zipfileAddEntry(
}
}
static int zipfileLoadDirectory(ZipfileTab *pTab, const u8 *aBlob, i64 nBlob){
static int zipfileLoadDirectory(ZipfileTab *pTab, const u8 *aBlob, int nBlob){
ZipfileEOCD eocd;
int rc;
int i;
@@ -1318,7 +1289,7 @@ static int zipfileFilter(
}else if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
static const u8 aEmptyBlob = 0;
const u8 *aBlob = (const u8*)sqlite3_value_blob(argv[0]);
i64 nBlob = sqlite3_value_bytes(argv[0]);
int nBlob = sqlite3_value_bytes(argv[0]);
assert( pTab->pFirstEntry==0 );
if( aBlob==0 ){
aBlob = &aEmptyBlob;
@@ -1392,7 +1363,7 @@ static int zipfileBestIndex(
static ZipfileEntry *zipfileNewEntry(const char *zPath){
ZipfileEntry *pNew;
pNew = sqlite3_malloc64(sizeof(ZipfileEntry));
pNew = sqlite3_malloc(sizeof(ZipfileEntry));
if( pNew ){
memset(pNew, 0, sizeof(ZipfileEntry));
pNew->cds.zFile = sqlite3_mprintf("%s", zPath);
@@ -1516,7 +1487,7 @@ static int zipfileBegin(sqlite3_vtab *pVtab){
assert( pTab->pWriteFd==0 );
if( pTab->zFile==0 || pTab->zFile[0]==0 ){
zipfileTableErr(pTab, "zipfile: missing filename");
pTab->base.zErrMsg = sqlite3_mprintf("zipfile: missing filename");
return SQLITE_ERROR;
}
@@ -1526,9 +1497,9 @@ static int zipfileBegin(sqlite3_vtab *pVtab){
** in main-memory until the transaction is committed. */
pTab->pWriteFd = sqlite3_fopen(pTab->zFile, "ab+");
if( pTab->pWriteFd==0 ){
zipfileTableErr(pTab,
"zipfile: failed to open file %s for writing", pTab->zFile
);
pTab->base.zErrMsg = sqlite3_mprintf(
"zipfile: failed to open file %s for writing", pTab->zFile
);
rc = SQLITE_ERROR;
}else{
fseek(pTab->pWriteFd, 0, SEEK_END);
@@ -1993,7 +1964,7 @@ struct ZipfileCtx {
ZipfileBuffer cds;
};
static int zipfileBufferGrow(ZipfileBuffer *pBuf, i64 nByte){
static int zipfileBufferGrow(ZipfileBuffer *pBuf, int nByte){
if( pBuf->n+nByte>pBuf->nAlloc ){
u8 *aNew;
sqlite3_int64 nNew = pBuf->n ? pBuf->n*2 : 512;
@@ -2042,7 +2013,7 @@ static void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
char *zName = 0; /* Path (name) of new entry */
int nName = 0; /* Size of zName in bytes */
char *zFree = 0; /* Free this before returning */
i64 nByte;
int nByte;
memset(&e, 0, sizeof(e));
p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx));

Some files were not shown because too many files have changed in this diff Show More