mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Merge latest changes from the wal2 branch into this one.
FossilOrigin-Name: 4d8df0c426b8ce3db6cfb71e23f752026ef886b9bb833dc4be9717db9955b1db
This commit is contained in:
@@ -1316,6 +1316,9 @@ testrunner: testfixture$(TEXE)
|
||||
#
|
||||
devtest: testfixture$(TEXE) fuzztest testrunner
|
||||
|
||||
mdevtest:
|
||||
$(TCLSH_CMD) $(TOP)/test/testrunner.tcl mdevtest
|
||||
|
||||
# Testing for a release
|
||||
#
|
||||
releasetest: testfixture$(TEXE)
|
||||
|
18
Makefile.msc
18
Makefile.msc
@@ -56,7 +56,7 @@ USE_STDCALL = 0
|
||||
# in the core library.
|
||||
#
|
||||
!IFNDEF USE_SEH
|
||||
USE_SEH = 0
|
||||
USE_SEH = 1
|
||||
!ENDIF
|
||||
|
||||
# Set this non-0 to have the shell executable link against the core dynamic
|
||||
@@ -225,6 +225,12 @@ WIN32HEAP = 0
|
||||
OSTRACE = 0
|
||||
!ENDIF
|
||||
|
||||
# enable address sanitizer using ASAN=1 on the command-line.
|
||||
#
|
||||
!IFNDEF ASAN
|
||||
ASAN = 0
|
||||
!ENDIF
|
||||
|
||||
# Set this to one of the following values to enable various debugging
|
||||
# features. Each level includes the debugging options from the previous
|
||||
# levels. Currently, the recognized values for DEBUG are:
|
||||
@@ -891,6 +897,13 @@ RCC = $(RCC) -DSQLITE_WIN32_MALLOC_VALIDATE=1
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
|
||||
# Address sanitizer if ASAN=1
|
||||
#
|
||||
!IF $(ASAN)>0
|
||||
TCC = $(TCC) /fsanitize=address
|
||||
!ENDIF
|
||||
|
||||
# <<mark>>
|
||||
# The locations of the Tcl header and library files. Also, the library that
|
||||
# non-stubs enabled programs using Tcl must link against. These variables
|
||||
@@ -2506,6 +2519,9 @@ testrunner: testfixture.exe
|
||||
#
|
||||
devtest: testfixture.exe fuzztest testrunner
|
||||
|
||||
mdevtest:
|
||||
$(TCLSH_CMD) $(TOP)\test\testrunner.tcl mdevtest
|
||||
|
||||
# Testing for a release
|
||||
#
|
||||
releasetest: testfixture.exe fuzztest
|
||||
|
43
README.md
43
README.md
@@ -104,9 +104,9 @@ For example:
|
||||
mkdir bld ;# Build will occur in a sibling directory
|
||||
cd bld ;# Change to the build directory
|
||||
../sqlite/configure ;# Run the configure script
|
||||
make ;# Run the makefile.
|
||||
make ;# Builds the "sqlite3" command-line tool
|
||||
make sqlite3.c ;# Build the "amalgamation" source file
|
||||
make test ;# Run some tests (requires Tcl)
|
||||
make devtest ;# Run some tests (requires Tcl)
|
||||
|
||||
See the makefile for additional targets.
|
||||
|
||||
@@ -119,29 +119,30 @@ show what changes are needed.
|
||||
## Using MSVC for Windows systems
|
||||
|
||||
On Windows, all applicable build products can be compiled with MSVC.
|
||||
First open the command prompt window associated with the desired compiler
|
||||
version (e.g. "Developer Command Prompt for VS2013"). Next, use NMAKE
|
||||
with the provided "Makefile.msc" to build one of the supported targets.
|
||||
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.
|
||||
|
||||
For example, from the parent directory of the source subtree named "sqlite":
|
||||
If you want to run tests, you need to let SQLite know the location of your
|
||||
TCL library, using a command like this:
|
||||
|
||||
mkdir bld
|
||||
cd bld
|
||||
nmake /f ..\sqlite\Makefile.msc TOP=..\sqlite
|
||||
nmake /f ..\sqlite\Makefile.msc sqlite3.c TOP=..\sqlite
|
||||
nmake /f ..\sqlite\Makefile.msc sqlite3.dll TOP=..\sqlite
|
||||
nmake /f ..\sqlite\Makefile.msc sqlite3.exe TOP=..\sqlite
|
||||
nmake /f ..\sqlite\Makefile.msc test TOP=..\sqlite
|
||||
set TCLDIR=c:\Tcl
|
||||
|
||||
There are several build options that can be set via the NMAKE command
|
||||
line. For example, to build for WinRT, simply add "FOR_WINRT=1" argument
|
||||
to the "sqlite3.dll" command line above. When debugging into the SQLite
|
||||
code, adding the "DEBUG=1" argument to one of the above command lines is
|
||||
recommended.
|
||||
SQLite uses "tclsh.exe" as part of the build process, and so that utility
|
||||
program will need to be somewhere on your %PATH%. The finished SQLite library
|
||||
does not contain any TCL code, but it does use TCL to help with the build process
|
||||
and to run tests.
|
||||
|
||||
SQLite does not require [Tcl](http://www.tcl.tk/) to run, but a Tcl installation
|
||||
is required by the makefiles (including those for MSVC). SQLite contains
|
||||
a lot of generated code and Tcl is used to do much of that code generation.
|
||||
Build using Makefile.msc. Example:
|
||||
|
||||
nmake /f Makefile.msc
|
||||
nmake /f Makefile.msc sqlite3.c
|
||||
nmake /f Makefile.msc devtest
|
||||
nmake /f Makefile.msc releasetest
|
||||
|
||||
There are many other makefile targets. See comments in Makefile.msc for
|
||||
details.
|
||||
|
||||
## Source Code Tour
|
||||
|
||||
|
@@ -9,7 +9,7 @@ sqlite3_SOURCES = shell.c sqlite3.h
|
||||
EXTRA_sqlite3_SOURCES = sqlite3.c
|
||||
sqlite3_LDADD = @EXTRA_SHELL_OBJ@ @READLINE_LIBS@
|
||||
sqlite3_DEPENDENCIES = @EXTRA_SHELL_OBJ@
|
||||
sqlite3_CFLAGS = $(AM_CFLAGS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_STMTVTAB -DSQLITE_ENABLE_DBSTAT_VTAB $(SHELL_CFLAGS)
|
||||
sqlite3_CFLAGS = $(AM_CFLAGS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_DQS=0 -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_STMTVTAB -DSQLITE_ENABLE_DBSTAT_VTAB $(SHELL_CFLAGS)
|
||||
|
||||
include_HEADERS = sqlite3.h sqlite3ext.h
|
||||
|
||||
|
@@ -56,7 +56,7 @@ USE_STDCALL = 0
|
||||
# in the core library.
|
||||
#
|
||||
!IFNDEF USE_SEH
|
||||
USE_SEH = 0
|
||||
USE_SEH = 1
|
||||
!ENDIF
|
||||
|
||||
# Set this non-0 to have the shell executable link against the core dynamic
|
||||
|
85
doc/compile-for-windows.md
Normal file
85
doc/compile-for-windows.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# Notes On Compiling SQLite On Windows 11
|
||||
|
||||
Here are step-by-step instructions on how to build SQLite from
|
||||
canonical source on a new Windows 11 PC, as of 2023-08-16:
|
||||
|
||||
1. Install Microsoft Visual Studio. The free "community edition"
|
||||
will work fine. Do a standard install for C++ development.
|
||||
SQLite only needs the
|
||||
"cl" compiler and the "nmake" build tool.
|
||||
|
||||
2. Under the "Start" menu, find "All Apps" then go to "Visual Studio 20XX"
|
||||
and find "x64 Native Tools Command Prompt for VS 20XX". Pin that
|
||||
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.) The subsequent steps will not work in a vanilla
|
||||
DOS prompt. Nor will they work in PowerShell.
|
||||
|
||||
3. Install TCL development libraries. This note assumes that you wil
|
||||
install the TCL development libraries in the "`c:\Tcl`" directory.
|
||||
Make adjustments
|
||||
if you want TCL installed somewhere else. SQLite needs both the
|
||||
"tclsh.exe" command-line tool as part of the build process, and
|
||||
the "tcl86.lib" library in order to run tests. You will need
|
||||
TCL version 8.6 or later.
|
||||
<ol type="a">
|
||||
<li>Get the TCL source archive, perhaps from
|
||||
<https://www.tcl.tk/software/tcltk/download.html>.
|
||||
<li>Untar or unzip the source archive. CD into the "win/" subfolder
|
||||
of the source tree.
|
||||
<li>Run: `nmake /f makefile.vc release`
|
||||
<li>Run: `nmake /f makefile.vc INSTALLDIR=c:\Tcl install`
|
||||
<li>CD to c:\\Tcl\\lib. In that subfolder make a copy of the
|
||||
"`tcl86t.lib`" file to the alternative name "`tcl86.lib`"
|
||||
(omitting the second 't'). Leave the copy in the same directory
|
||||
as the original.
|
||||
<li>CD to c:\\Tcl\\bin. Make a copy of the "`tclsh86t.exe`"
|
||||
file into "`tclsh.exe`" (without the "86t") in the same directory.
|
||||
<li>Add c:\\Tcl\\bin to your %PATH%. To do this, go to Settings
|
||||
and search for "path". Select "edit environment variables for
|
||||
your account" and modify your default PATH accordingly.
|
||||
You will need to close and reopen your command prompts after
|
||||
making this change.
|
||||
</ol>
|
||||
|
||||
4. Download the SQLite source tree and unpack it. CD into the
|
||||
toplevel directory of the source tree.
|
||||
|
||||
5. Set the TCLDIR environment variable to point to your TCL installation.
|
||||
Like this:
|
||||
<ul>
|
||||
<li> `set TCLDIR=c:\Tcl`
|
||||
</ul>
|
||||
|
||||
6. Run the "`Makefile.msc`" makefile with an appropriate target.
|
||||
Examples:
|
||||
<ul>
|
||||
<li> `nmake /f makefile.msc`
|
||||
<li> `nmake /f makefile.msc sqlite3.c`
|
||||
<li> `nmake /f makefile.msc devtest`
|
||||
<li> `nmake /f makefile.msc releasetest`
|
||||
</ul>
|
||||
|
||||
## 32-bit Builds
|
||||
|
||||
Doing a 32-bit build is just like doing a 64-bit build with the
|
||||
following minor changes:
|
||||
|
||||
1. Use the "x86 Native Tools Command Prompt" instead of
|
||||
"x64 Native Tools Command Prompt". "**x86**" instead of "**x64**".
|
||||
|
||||
2. Use a different installation directory for TCL.
|
||||
The recommended directory is `c:\tcl32`. Thus you end up
|
||||
with two TCL builds:
|
||||
<ul>
|
||||
<li> `c:\tcl` ← 64-bit (the default)
|
||||
<li> `c:\tcl32` ← 32-bit
|
||||
</ul>
|
||||
|
||||
3. Ensure that c:\\tcl32\\bin comes before c:\\tcl\\bin on
|
||||
your PATH environment variable. You can achieve this using
|
||||
a command like:
|
||||
<ul>
|
||||
<li> `set PATH=c:\tcl32\bin;%PATH%`
|
||||
</ul>
|
@@ -492,8 +492,8 @@ struct Fts5ExtensionApi {
|
||||
** as separate queries of the FTS index are required for each synonym.
|
||||
**
|
||||
** When using methods (2) or (3), it is important that the tokenizer only
|
||||
** provide synonyms when tokenizing document text (method (2)) or query
|
||||
** text (method (3)), not both. Doing so will not cause any errors, but is
|
||||
** provide synonyms when tokenizing document text (method (3)) or query
|
||||
** text (method (2)), not both. Doing so will not cause any errors, but is
|
||||
** inefficient.
|
||||
*/
|
||||
typedef struct Fts5Tokenizer Fts5Tokenizer;
|
||||
|
@@ -2583,6 +2583,8 @@ static char *fts5ExprPrintTcl(
|
||||
if( zRet==0 ) return 0;
|
||||
}
|
||||
|
||||
}else if( pExpr->eType==0 ){
|
||||
zRet = sqlite3_mprintf("{}");
|
||||
}else{
|
||||
char const *zOp = 0;
|
||||
int i;
|
||||
|
@@ -5421,7 +5421,8 @@ static void fts5FlushOneHash(Fts5Index *p){
|
||||
writer.bFirstRowidInPage = 0;
|
||||
fts5WriteDlidxAppend(p, &writer, iRowid);
|
||||
}else{
|
||||
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid-iPrev);
|
||||
u64 iDelta = (u64)iRowid - (u64)iPrev;
|
||||
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iDelta);
|
||||
}
|
||||
if( p->rc!=SQLITE_OK ) break;
|
||||
assert( pBuf->n<=pBuf->nSpace );
|
||||
@@ -7815,7 +7816,7 @@ static void fts5DecodeFunction(
|
||||
fts5DecodeRowidList(&rc, &s, &a[4], iTermOff-4);
|
||||
|
||||
iOff = iTermOff;
|
||||
while( iOff<szLeaf ){
|
||||
while( iOff<szLeaf && rc==SQLITE_OK ){
|
||||
int nAppend;
|
||||
|
||||
/* Read the term data for the next term*/
|
||||
@@ -7835,8 +7836,11 @@ static void fts5DecodeFunction(
|
||||
}else{
|
||||
iTermOff = szLeaf;
|
||||
}
|
||||
|
||||
fts5DecodeRowidList(&rc, &s, &a[iOff], iTermOff-iOff);
|
||||
if( iTermOff>szLeaf ){
|
||||
rc = FTS5_CORRUPT;
|
||||
}else{
|
||||
fts5DecodeRowidList(&rc, &s, &a[iOff], iTermOff-iOff);
|
||||
}
|
||||
iOff = iTermOff;
|
||||
if( iOff<szLeaf ){
|
||||
iOff += fts5GetVarint32(&a[iOff], nKeep);
|
||||
|
@@ -95,6 +95,9 @@ do_execsql_test 3.3 {
|
||||
SELECT rowid, bm25(e1) FROM e1 WHERE e1 MATCH '"/" OR "just"' ORDER BY rank;
|
||||
} {1 -1e-06}
|
||||
|
||||
do_execsql_test 3.4 "
|
||||
SELECT fts5_expr_tcl('e AND \" \"');
|
||||
" {{AND [nearset -- {e}] [{}]}}
|
||||
|
||||
|
||||
finish_test
|
||||
|
@@ -50,6 +50,25 @@ do_test 1.3 {
|
||||
expr $phc(1)*5 < $phc(2)
|
||||
} {1}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
|
||||
do_execsql_test 2.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(x);
|
||||
INSERT INTO t1(t1, rank) VALUES('secure-delete', $sd)
|
||||
}
|
||||
|
||||
do_execsql_test 2.1 {
|
||||
BEGIN;
|
||||
INSERT INTO t1(rowid, x) VALUES(-100000, 'abc def ghi');
|
||||
INSERT INTO t1(rowid, x) VALUES(-99999, 'abc def ghi');
|
||||
INSERT INTO t1(rowid, x) VALUES(9223372036854775800, 'abc def ghi');
|
||||
COMMIT;
|
||||
}
|
||||
|
||||
do_execsql_test 2.2 {
|
||||
SELECT rowid FROM t1('def')
|
||||
} {-100000 -99999 9223372036854775800}
|
||||
|
||||
finish_test
|
||||
|
||||
|
@@ -122,6 +122,9 @@ foreach {tn expr} {
|
||||
4.1 "NEAR(one two, 2)"
|
||||
4.2 "NEAR(one two three, 2)"
|
||||
4.3 "NEAR(eight nine, 1) OR NEAR(six seven, 1)"
|
||||
|
||||
5.1 "one + two"
|
||||
5.2 "1 + two"
|
||||
} {
|
||||
if {[fts5_expr_ok $expr ss]==0} {
|
||||
do_test 1.$tok.$tn.OMITTED { list } [list]
|
||||
|
346
ext/jni/GNUmakefile
Normal file
346
ext/jni/GNUmakefile
Normal file
@@ -0,0 +1,346 @@
|
||||
# Quick-and-dirty makefile to bootstrap the sqlite3-jni project. This
|
||||
# build assumes a Linux-like system.
|
||||
default: all
|
||||
|
||||
JAVA_HOME ?= $(HOME)/jdk/current
|
||||
# e.g. /usr/lib/jvm/default-javajava-19-openjdk-amd64
|
||||
JDK_HOME ?= $(JAVA_HOME)
|
||||
# ^^^ JDK_HOME is not as widely used as JAVA_HOME
|
||||
bin.javac := $(JDK_HOME)/bin/javac
|
||||
bin.java := $(JDK_HOME)/bin/java
|
||||
bin.jar := $(JDK_HOME)/bin/jar
|
||||
ifeq (,$(wildcard $(JDK_HOME)))
|
||||
$(error set JDK_HOME to the top-most dir of your JDK installation.)
|
||||
endif
|
||||
MAKEFILE := $(lastword $(MAKEFILE_LIST))
|
||||
$(MAKEFILE):
|
||||
|
||||
package.jar := sqlite3-jni.jar
|
||||
|
||||
dir.top := ../..
|
||||
dir.tool := ../../tool
|
||||
dir.jni := $(patsubst %/,%,$(dir $(MAKEFILE)))
|
||||
|
||||
dir.src := $(dir.jni)/src
|
||||
dir.src.c := $(dir.src)/c
|
||||
dir.bld := $(dir.jni)/bld
|
||||
dir.bld.c := $(dir.bld)
|
||||
dir.src.jni := $(dir.src)/org/sqlite/jni
|
||||
dir.src.jni.tester := $(dir.src.jni)/tester
|
||||
$(dir.bld.c):
|
||||
mkdir -p $@
|
||||
|
||||
classpath := $(dir.src)
|
||||
CLEAN_FILES := $(package.jar)
|
||||
DISTCLEAN_FILES := $(dir.jni)/*~ $(dir.src.c)/*~ $(dir.src.jni)/*~
|
||||
|
||||
sqlite3-jni.h := $(dir.src.c)/sqlite3-jni.h
|
||||
.NOTPARALLEL: $(sqlite3-jni.h)
|
||||
SQLite3Jni.java := src/org/sqlite/jni/SQLite3Jni.java
|
||||
SQLTester.java := src/org/sqlite/jni/tester/SQLTester.java
|
||||
SQLite3Jni.class := $(SQLite3Jni.java:.java=.class)
|
||||
SQLTester.class := $(SQLTester.java:.java=.class)
|
||||
|
||||
########################################################################
|
||||
# The future of FTS5 customization in this API is as yet unclear.
|
||||
# It would be a real doozy to bind to JNI.
|
||||
enable.fts5 ?= 1
|
||||
# If enable.tester is 0, the org/sqlite/jni/tester/* bits are elided.
|
||||
enable.tester ?= 1
|
||||
|
||||
# bin.version-info = binary to output various sqlite3 version info
|
||||
# building the distribution zip file.
|
||||
bin.version-info := $(dir.top)/version-info
|
||||
.NOTPARALLEL: $(bin.version-info)
|
||||
$(bin.version-info): $(dir.tool)/version-info.c $(sqlite3.h) $(dir.top)/Makefile
|
||||
$(MAKE) -C $(dir.top) version-info
|
||||
|
||||
# Be explicit about which Java files to compile so that we can work on
|
||||
# in-progress files without requiring them to be in a compilable statae.
|
||||
JAVA_FILES.main := $(patsubst %,$(dir.src.jni)/%,\
|
||||
BusyHandler.java \
|
||||
Collation.java \
|
||||
CollationNeeded.java \
|
||||
CommitHook.java \
|
||||
NativePointerHolder.java \
|
||||
OutputPointer.java \
|
||||
ProgressHandler.java \
|
||||
ResultCode.java \
|
||||
RollbackHook.java \
|
||||
SQLFunction.java \
|
||||
sqlite3_context.java \
|
||||
sqlite3.java \
|
||||
SQLite3Jni.java \
|
||||
sqlite3_stmt.java \
|
||||
sqlite3_value.java \
|
||||
Tester1.java \
|
||||
Tracer.java \
|
||||
UpdateHook.java \
|
||||
ValueHolder.java \
|
||||
)
|
||||
ifeq (1,$(enable.fts5))
|
||||
JAVA_FILES.main += $(patsubst %,$(dir.src.jni)/%,\
|
||||
fts5_api.java \
|
||||
fts5_extension_function.java \
|
||||
fts5_tokenizer.java \
|
||||
Fts5.java \
|
||||
Fts5Context.java \
|
||||
Fts5ExtensionApi.java \
|
||||
Fts5Function.java \
|
||||
Fts5PhraseIter.java \
|
||||
Fts5Tokenizer.java \
|
||||
TesterFts5.java \
|
||||
)
|
||||
endif
|
||||
JAVA_FILES.tester := $(dir.src.jni.tester)/SQLTester.java
|
||||
|
||||
CLASS_FILES.main := $(JAVA_FILES.main:.java=.class)
|
||||
CLASS_FILES.tester := $(JAVA_FILES.tester:.java=.class)
|
||||
|
||||
JAVA_FILES += $(JAVA_FILES.main)
|
||||
ifeq (1,$(enable.tester))
|
||||
JAVA_FILES += $(JAVA_FILES.tester)
|
||||
endif
|
||||
|
||||
CLASS_FILES :=
|
||||
define DOTCLASS_DEPS
|
||||
$(1).class: $(1).java $(MAKEFILE)
|
||||
all: $(1).class
|
||||
CLASS_FILES += $(1).class
|
||||
endef
|
||||
$(foreach B,$(basename $(JAVA_FILES)),$(eval $(call DOTCLASS_DEPS,$(B))))
|
||||
$(CLASS_FILES.tester): $(CLASS_FILES.main)
|
||||
javac.flags ?= -Xlint:unchecked -Xlint:deprecation
|
||||
java.flags ?=
|
||||
jnicheck ?= 1
|
||||
ifeq (1,$(jnicheck))
|
||||
java.flags += -Xcheck:jni
|
||||
endif
|
||||
$(SQLite3Jni.class): $(JAVA_FILES)
|
||||
$(bin.javac) $(javac.flags) -h $(dir.bld.c) -cp $(classpath) $(JAVA_FILES)
|
||||
all: $(SQLite3Jni.class)
|
||||
#.PHONY: classfiles
|
||||
|
||||
########################################################################
|
||||
# Set up sqlite3.c and sqlite3.h...
|
||||
#
|
||||
# To build with SEE (https://sqlite.org/see), either put sqlite3-see.c
|
||||
# in the top of this build tree or pass
|
||||
# sqlite3.c=PATH_TO_sqlite3-see.c to the build. Note that only
|
||||
# encryption modules with no 3rd-party dependencies will currently
|
||||
# work here: AES256-OFB, AES128-OFB, and AES128-CCM. Not
|
||||
# coincidentally, those 3 modules are included in the sqlite3-see.c
|
||||
# bundle.
|
||||
#
|
||||
# A custom sqlite3.c must not have any spaces in its name.
|
||||
# $(sqlite3.canonical.c) must point to the sqlite3.c in
|
||||
# the sqlite3 canonical source tree, as that source file
|
||||
# is required for certain utility and test code.
|
||||
sqlite3.canonical.c := $(firstword $(wildcard $(dir.src.c)/sqlite3.c) $(dir.top)/sqlite3.c)
|
||||
sqlite3.canonical.h := $(firstword $(wildcard $(dir.src.c)/sqlite3.h) $(dir.top)/sqlite3.h)
|
||||
sqlite3.c := $(sqlite3.canonical.c)
|
||||
sqlite3.h := $(sqlite3.canonical.h)
|
||||
#ifeq (,$(shell grep sqlite3_activate_see $(sqlite3.c) 2>/dev/null))
|
||||
# SQLITE_C_IS_SEE := 0
|
||||
#else
|
||||
# SQLITE_C_IS_SEE := 1
|
||||
# $(info This is an SEE build.)
|
||||
#endif
|
||||
|
||||
.NOTPARALLEL: $(sqlite3.h)
|
||||
$(sqlite3.h):
|
||||
$(MAKE) -C $(dir.top) sqlite3.c
|
||||
$(sqlite3.c): $(sqlite3.h)
|
||||
|
||||
SQLITE_OPT = \
|
||||
-DSQLITE_ENABLE_RTREE \
|
||||
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
|
||||
-DSQLITE_ENABLE_STMTVTAB \
|
||||
-DSQLITE_ENABLE_DBPAGE_VTAB \
|
||||
-DSQLITE_ENABLE_DBSTAT_VTAB \
|
||||
-DSQLITE_ENABLE_BYTECODE_VTAB \
|
||||
-DSQLITE_ENABLE_OFFSET_SQL_FUNC \
|
||||
-DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
-DSQLITE_OMIT_DEPRECATED \
|
||||
-DSQLITE_OMIT_SHARED_CACHE \
|
||||
-DSQLITE_THREADSAFE=0 \
|
||||
-DSQLITE_TEMP_STORE=2 \
|
||||
-DSQLITE_USE_URI=1 \
|
||||
-DSQLITE_C=$(sqlite3.c)
|
||||
# -DSQLITE_DEBUG
|
||||
# -DSQLITE_DEBUG is just to work around a -Wall warning
|
||||
# for a var which gets set in all builds but only read
|
||||
# via assert().
|
||||
|
||||
SQLITE_OPT += -g -DDEBUG -UNDEBUG
|
||||
|
||||
ifeq (1,$(enable.fts5))
|
||||
SQLITE_OPT += -DSQLITE_ENABLE_FTS5
|
||||
endif
|
||||
|
||||
sqlite3-jni.c := $(dir.src.c)/sqlite3-jni.c
|
||||
sqlite3-jni.o := $(dir.bld.c)/sqlite3-jni.o
|
||||
sqlite3-jni.h := $(dir.src.c)/sqlite3-jni.h
|
||||
sqlite3-jni.dll := $(dir.bld.c)/libsqlite3-jni.so
|
||||
# All javac-generated .h files must be listed in $(sqlite3-jni.h.in):
|
||||
sqlite3-jni.h.in :=
|
||||
define ADD_JNI_H
|
||||
sqlite3-jni.h.in += $$(dir.bld.c)/org_sqlite_jni_$(1).h
|
||||
$$(dir.bld.c)/org_sqlite_jni_$(1).h: $$(dir.src.jni)/$(1).java
|
||||
endef
|
||||
$(eval $(call ADD_JNI_H,SQLite3Jni))
|
||||
ifeq (1,$(enable.fts5))
|
||||
$(eval $(call ADD_JNI_H,Fts5ExtensionApi))
|
||||
$(eval $(call ADD_JNI_H,fts5_api))
|
||||
$(eval $(call ADD_JNI_H,fts5_tokenizer))
|
||||
endif
|
||||
ifeq (1,$(enable.tester))
|
||||
sqlite3-jni.h.in += $(dir.bld.c)/org_sqlite_jni_tester_SQLTester.h
|
||||
$(dir.bld.c)/org_sqlite_jni_tester_SQLTester.h: $(dir.src.jni.tester)/SQLTester.java
|
||||
endif
|
||||
#sqlite3-jni.dll.cfiles := $(dir.src.c)
|
||||
sqlite3-jni.dll.cflags = \
|
||||
-fPIC \
|
||||
-I. \
|
||||
-I$(dir $(sqlite3.h)) \
|
||||
-I$(dir.src.c) \
|
||||
-I$(JDK_HOME)/include \
|
||||
$(patsubst %,-I%,$(patsubst %.h,,$(wildcard $(JDK_HOME)/include/*))) \
|
||||
-Wall
|
||||
# Using (-Wall -Wextra) triggers an untennable number of
|
||||
# gcc warnings from sqlite3.c for mundane things like
|
||||
# unused parameters.
|
||||
#
|
||||
# The gross $(patsubst...) above is to include the platform-specific
|
||||
# subdir which lives under $(JDK_HOME)/include and is a required
|
||||
# include path for client-level code.
|
||||
########################################################################
|
||||
ifeq (1,$(enable.tester))
|
||||
sqlite3-jni.dll.cflags += -DS3JNI_ENABLE_SQLTester
|
||||
endif
|
||||
$(sqlite3-jni.h): $(sqlite3-jni.h.in) $(MAKEFILE)
|
||||
cat $(sqlite3-jni.h.in) > $@
|
||||
$(sqlite3-jni.dll): $(sqlite3-jni.h) $(sqlite3.c) $(sqlite3.h)
|
||||
$(sqlite3-jni.dll): $(dir.bld.c) $(sqlite3-jni.c) $(SQLite3Jni.java) $(MAKEFILE)
|
||||
$(CC) $(sqlite3-jni.dll.cflags) $(SQLITE_OPT) \
|
||||
$(sqlite3-jni.c) -shared -o $@
|
||||
all: $(sqlite3-jni.dll)
|
||||
|
||||
.PHONY: test
|
||||
test.flags ?= -v
|
||||
test: $(SQLite3Jni.class) $(sqlite3-jni.dll)
|
||||
$(bin.java) -ea -Djava.library.path=$(dir.bld.c) \
|
||||
$(java.flags) -cp $(classpath) \
|
||||
org.sqlite.jni.Tester1 $(if $(test.flags),-- $(test.flags),)
|
||||
|
||||
tester.scripts := $(sort $(wildcard $(dir.src)/tests/*.test))
|
||||
tester.flags ?= # --verbose
|
||||
.PHONY: tester tester-local tester-ext
|
||||
ifeq (1,$(enable.tester))
|
||||
tester-local: $(CLASS_FILES.tester) $(sqlite3-jni.dll)
|
||||
$(bin.java) -ea -Djava.library.path=$(dir.bld.c) \
|
||||
$(java.flags) -cp $(classpath) \
|
||||
org.sqlite.jni.tester.SQLTester $(tester.flags) $(tester.scripts)
|
||||
tester: tester-local
|
||||
else
|
||||
tester:
|
||||
@echo "SQLTester support is disabled. Build with enable.tester=1 to enable it."
|
||||
endif
|
||||
|
||||
tester.extdir.default := src/tests/ext
|
||||
tester.extdir ?= $(tester.extdir.default)
|
||||
tester.extern-scripts := $(wildcard $(tester.extdir)/*.test)
|
||||
ifneq (,$(tester.extern-scripts))
|
||||
tester-ext:
|
||||
$(bin.java) -ea -Djava.library.path=$(dir.bld.c) \
|
||||
$(java.flags) -cp $(classpath) \
|
||||
org.sqlite.jni.tester.SQLTester $(tester.flags) $(tester.extern-scripts)
|
||||
else
|
||||
tester-ext:
|
||||
@echo "******************************************************"; \
|
||||
echo "*** Include the out-of-tree test suite in the 'tester'"; \
|
||||
echo "*** target by either symlinking its directory to"; \
|
||||
echo "*** $(tester.extdir.default) or passing it to make"; \
|
||||
echo "*** as tester.extdir=/path/to/that/dir."; \
|
||||
echo "******************************************************";
|
||||
endif
|
||||
|
||||
tester-ext: tester-local
|
||||
tester: tester-ext
|
||||
tests: test tester
|
||||
package.jar.in := $(abspath $(dir.src)/jar.in)
|
||||
CLEAN_FILES += $(package.jar.in)
|
||||
$(package.jar.in): $(MAKEFILE) $(CLASS_FILES.main)
|
||||
cd $(dir.src); ls -1 org/sqlite/jni/*.java org/sqlite/jni/*.class > $@
|
||||
@ls -la $@
|
||||
@echo "To use this jar you will need the -Djava.library.path=DIR/WITH/libsqlite3-jni.so flag."
|
||||
@echo "e.g. java -jar $@ -Djava.library.path=bld"
|
||||
|
||||
$(package.jar): $(CLASS_FILES) $(MAKEFILE) $(package.jar.in)
|
||||
rm -f $(dir.src)/c/*~ $(dir.src.jni)/*~
|
||||
cd $(dir.src); $(bin.jar) -cfe ../$@ org.sqlite.jni.Tester1 @$(package.jar.in)
|
||||
|
||||
jar: $(package.jar)
|
||||
|
||||
CLEAN_FILES += $(dir.bld.c)/* \
|
||||
$(dir.src.jni)/*.class \
|
||||
$(dir.src.jni.tester)/*.class \
|
||||
$(sqlite3-jni.dll) \
|
||||
hs_err_pid*.log
|
||||
|
||||
.PHONY: clean distclean
|
||||
clean:
|
||||
-rm -f $(CLEAN_FILES)
|
||||
distclean: clean
|
||||
-rm -f $(DISTCLEAN_FILES)
|
||||
-rm -fr $(dir.bld.c)
|
||||
|
||||
########################################################################
|
||||
# disttribution bundle rules...
|
||||
|
||||
ifeq (,$(filter snapshot,$(MAKECMDGOALS)))
|
||||
dist-name-prefix := sqlite-jni
|
||||
else
|
||||
dist-name-prefix := sqlite-jni-snapshot-$(shell /usr/bin/date +%Y%m%d)
|
||||
endif
|
||||
dist-name := $(dist-name-prefix)-TEMP
|
||||
|
||||
|
||||
dist-dir.top := $(dist-name)
|
||||
dist-dir.src := $(dist-dir.top)/src
|
||||
dist.top.extras := \
|
||||
README.md
|
||||
|
||||
.PHONY: dist snapshot
|
||||
|
||||
dist: \
|
||||
$(bin.version-info) $(sqlite3.canonical.c) \
|
||||
$(package.jar) $(MAKEFILE)
|
||||
@echo "Making end-user deliverables..."
|
||||
@rm -fr $(dist-dir.top)
|
||||
@mkdir -p $(dist-dir.src)
|
||||
@cp -p $(dist.top.extras) $(dist-dir.top)/.
|
||||
@cp -p jar-dist.make $(dist-dir.top)/Makefile
|
||||
@cp -p $(dir.src.c)/*.[ch] $(dist-dir.src)/.
|
||||
@cp -p $(sqlite3.canonical.c) $(sqlite3.canonical.h) $(dist-dir.src)/.
|
||||
@set -e; \
|
||||
vnum=$$($(bin.version-info) --download-version); \
|
||||
vjar=$$($(bin.version-info) --version); \
|
||||
vdir=$(dist-name-prefix)-$$vnum; \
|
||||
arczip=$$vdir.zip; \
|
||||
cp -p $(package.jar) $(dist-dir.top)/sqlite3-jni-$${vjar}.jar; \
|
||||
echo "Making $$arczip ..."; \
|
||||
rm -fr $$arczip $$vdir; \
|
||||
mv $(dist-dir.top) $$vdir; \
|
||||
zip -qr $$arczip $$vdir; \
|
||||
rm -fr $$vdir; \
|
||||
ls -la $$arczip; \
|
||||
set +e; \
|
||||
unzip -lv $$arczip || echo "Missing unzip app? Not fatal."
|
||||
|
||||
snapshot: dist
|
||||
|
||||
.PHONY: dist-clean
|
||||
clean: dist-clean
|
||||
dist-clean:
|
||||
rm -fr $(dist-name) $(wildcard sqlite-jni-*.zip)
|
234
ext/jni/README.md
Normal file
234
ext/jni/README.md
Normal file
@@ -0,0 +1,234 @@
|
||||
SQLite3 via JNI
|
||||
========================================================================
|
||||
|
||||
This directory houses a Java Native Interface (JNI) binding for the
|
||||
sqlite3 API. If you are reading this from the distribution ZIP file,
|
||||
links to resources in the canonical source tree will note work. The
|
||||
canonical copy of this file can be browsed at:
|
||||
|
||||
<https://sqlite.org/src/doc/trunk/ext/jni/README.md>
|
||||
|
||||
Technical support is available in the forum:
|
||||
|
||||
<https://sqlite.org/forum>
|
||||
|
||||
|
||||
> **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.
|
||||
|
||||
Project goals/requirements:
|
||||
|
||||
- A [1-to-1(-ish) mapping of the C API](#1to1ish) to Java via JNI,
|
||||
insofar as cross-language semantics allow for. A closely-related
|
||||
goal is that [the C documentation](https://sqlite.org/c3ref/intro.html)
|
||||
should be usable as-is, insofar as possible, for the JNI binding.
|
||||
|
||||
- Support Java as far back as version 8 (2014).
|
||||
|
||||
- Environment-independent. Should work everywhere both Java
|
||||
and SQLite3 do.
|
||||
|
||||
- No 3rd-party dependencies beyond the JDK. That includes no
|
||||
build-level dependencies for specific IDEs and toolchains. We
|
||||
welcome the addition of build files for arbitrary environments
|
||||
insofar as they neither interfere with each other nor become
|
||||
a maintenance burden for the sqlite developers.
|
||||
|
||||
Non-goals:
|
||||
|
||||
- Creation of high-level OO wrapper APIs. Clients are free to create
|
||||
them off of the C-style API.
|
||||
|
||||
|
||||
Significant TODOs
|
||||
========================================================================
|
||||
|
||||
- The initial beta release with version 3.43 has severe threading
|
||||
limitations. Namely, two threads cannot call into the JNI-bound API
|
||||
at once. This limitation will be remove in a subsequent release.
|
||||
|
||||
|
||||
Building
|
||||
========================================================================
|
||||
|
||||
The canonical builds assumes a Linux-like environment and requires:
|
||||
|
||||
- GNU Make
|
||||
- A JDK supporting Java 8 or higher
|
||||
- A modern C compiler. gcc and clang should both work.
|
||||
|
||||
Put simply:
|
||||
|
||||
```
|
||||
$ export JAVA_HOME=/path/to/jdk/root
|
||||
$ make
|
||||
$ make test
|
||||
$ make clean
|
||||
```
|
||||
|
||||
<a id='1to1ish'></a>
|
||||
One-to-One(-ish) Mapping to C
|
||||
========================================================================
|
||||
|
||||
This JNI binding aims to provide as close to a 1-to-1 experience with
|
||||
the C API as cross-language semantics allow. Exceptions are
|
||||
necessarily made where cross-language semantics do not allow a 1-to-1,
|
||||
and judiciously made where a 1-to-1 mapping would be unduly cumbersome
|
||||
to use in Java.
|
||||
|
||||
Golden Rule: _Never_ Throw from Callbacks
|
||||
------------------------------------------------------------------------
|
||||
|
||||
JNI bindings which accept client-defined functions _must never throw
|
||||
exceptions_ unless _very explicitly documented_ as being
|
||||
throw-safe. Exceptions are generally reserved for higher-level
|
||||
bindings which are constructed to specifically deal with them and
|
||||
ensure that they do not leak C-level resources. Some of the JNI
|
||||
bindings are provided as Java functions which expect this rule to
|
||||
always hold.
|
||||
|
||||
UTF-8(-ish)
|
||||
------------------------------------------------------------------------
|
||||
|
||||
SQLite internally uses UTF-8 encoding, whereas Java natively uses
|
||||
UTF-16. Java JNI has routines for converting to and from UTF-8, _but_
|
||||
Java uses what its docs call "[modified UTF-8][modutf8]." Care must be
|
||||
taken when converting Java strings to UTF-8 to ensure that the proper
|
||||
conversion is performed. In short,
|
||||
`String.getBytes(StandardCharsets.UTF_8)` performs the proper
|
||||
conversion in Java, and there is no JNI C API for that conversion
|
||||
(JNI's `NewStringUTF()` returns MUTF-8).
|
||||
|
||||
Known consequences and limitations of this discrepancy include:
|
||||
|
||||
- Names of databases, tables, and collations must not contain
|
||||
characters which differ in MUTF-8 and UTF-8, or certain APIs will
|
||||
mis-translate them on their way between languages. APIs which
|
||||
transfer other client-side data to Java take extra care to
|
||||
convert the data at the cost of performance.
|
||||
|
||||
[modutf8]: https://docs.oracle.com/javase/8/docs/api/java/io/DataInput.html#modified-utf-8
|
||||
|
||||
|
||||
Unwieldy Constructs are Re-mapped
|
||||
------------------------------------------------------------------------
|
||||
|
||||
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"...
|
||||
|
||||
### Custom Collations
|
||||
|
||||
A prime example of where interface changes for Java are necessary for
|
||||
usability is [registration of a custom
|
||||
collation](https://sqlite.org/c3ref/create_collation.html):
|
||||
|
||||
```
|
||||
// C:
|
||||
int sqlite3_create_collation(sqlite3 * db, const char * name, int eTextRep,
|
||||
void *pUserData,
|
||||
int (*xCompare)(void*,int,void const *,int,void const *));
|
||||
|
||||
int sqlite3_create_collation_v2(sqlite3 * db, const char * name, int eTextRep,
|
||||
void *pUserData,
|
||||
int (*xCompare)(void*,int,void const *,int,void const *),
|
||||
void (*xDestroy)(void*));
|
||||
```
|
||||
|
||||
The `pUserData` object is optional client-defined state for the
|
||||
`xCompare()` and/or `xDestroy()` callback functions, both of which are
|
||||
passed that object as their first argument. That data is passed around
|
||||
"externally" in C because that's how C models the world. If we were to
|
||||
bind that part as-is to Java, the result would be awkward to use (^Yes,
|
||||
we tried this.):
|
||||
|
||||
```
|
||||
// Java:
|
||||
int sqlite3_create_collation(sqlite3 db, String name, int eTextRep,
|
||||
Object pUserData, xCompareType xCompare);
|
||||
|
||||
int sqlite3_create_collation_v2(sqlite3 db, String name, int eTextRep,
|
||||
Object pUserData,
|
||||
xCompareType xCompare, xDestroyType xDestroy);
|
||||
```
|
||||
|
||||
The awkwardness comes from (A) having two distinctly different objects
|
||||
for callbacks and (B) having their internal state provided separately,
|
||||
which is ill-fitting in Java. For the sake of usability, C APIs which
|
||||
follow that pattern use a slightly different Java interface:
|
||||
|
||||
```
|
||||
int sqlite3_create_collation(sqlite3 db, String name, int eTextRep,
|
||||
Collation collation);
|
||||
```
|
||||
|
||||
Where the `Collation` class has an abstract `xCompare()` method and
|
||||
no-op `xDestroy()` method which can be overridden if needed, leading to
|
||||
a much more Java-esque usage:
|
||||
|
||||
```
|
||||
int rc = sqlite3_create_collation(db, "mycollation", SQLITE_UTF8, new Collation(){
|
||||
|
||||
// Required comparison function:
|
||||
@Override public int xCompare(byte[] lhs, byte[] rhs){ ... }
|
||||
|
||||
// Optional finalizer function:
|
||||
@Override public void xDestroy(){ ... }
|
||||
|
||||
// Optional local state:
|
||||
private String localState1 =
|
||||
"This is local state. There are many like it, but this one is mine.";
|
||||
private MyStateType localState2 = new MyStateType();
|
||||
...
|
||||
});
|
||||
```
|
||||
|
||||
Noting that:
|
||||
|
||||
- It is still possible to bind in call-scope-local state via closures,
|
||||
if desired.
|
||||
|
||||
- No capabilities of the C API are lost or unduly obscured via the
|
||||
above API reshaping, so power users need not make any compromises.
|
||||
|
||||
- In the specific example above, `sqlite3_create_collation_v2()`
|
||||
becomes superfluous because the provided interface effectively
|
||||
provides both the v1 and v2 interfaces, the difference being that
|
||||
overriding the `xDestroy()` method effectively gives it v2
|
||||
semantics.
|
||||
|
||||
### User-defined SQL Functions (a.k.a. UDFs)
|
||||
|
||||
The [`sqlite3_create_function()`](https://sqlite.org/c3ref/create_function.html)
|
||||
family of APIs make heavy use of function pointers to provide
|
||||
client-defined callbacks, necessitating interface changes in the JNI
|
||||
binding. The Java API has only one core function-registration function:
|
||||
|
||||
```
|
||||
int sqlite3_create_function(sqlite3 db, String funcName, int nArgs,
|
||||
int encoding, SQLFunction func);
|
||||
```
|
||||
|
||||
> Design question: does the encoding argument serve any purpose in JS?
|
||||
|
||||
`SQLFunction` is not used directly, but is instead instantiated via
|
||||
one of its three subclasses:
|
||||
|
||||
- `SQLFunction.Scalar` implements simple scalar functions using but a
|
||||
single callback.
|
||||
- `SQLFunction.Aggregate` implements aggregate functions using two
|
||||
callbacks.
|
||||
- `SQLFunction.Window` implements window functions using four
|
||||
callbacks.
|
||||
|
||||
Search [`Tester1.java`](/file/ext/jni/src/org/sqlite/jni/Tester1.java) for
|
||||
`SQLFunction` for how it's used.
|
||||
|
||||
Reminder: see the disclaimer at the top of this document regarding the
|
||||
in-flux nature of this API.
|
||||
|
||||
[jsrc]: /file/
|
||||
[www]: https://sqlite.org
|
55
ext/jni/jar-dist.make
Normal file
55
ext/jni/jar-dist.make
Normal file
@@ -0,0 +1,55 @@
|
||||
#!/this/is/make
|
||||
#^^^^ help emacs out
|
||||
#
|
||||
# This is a POSIX-make-compatible makefile for building the sqlite3
|
||||
# JNI library from "dist" zip file. It must be edited to set the
|
||||
# proper top-level JDK directory and, depending on the platform, add a
|
||||
# platform-specific -I directory. It should build as-is with any
|
||||
# 2020s-era version of gcc or clang. It requires JDK version 8 or
|
||||
# higher.
|
||||
|
||||
default: all
|
||||
|
||||
JAVA_HOME = /usr/lib/jvm/java-1.8.0-openjdk-amd64
|
||||
CFLAGS = \
|
||||
-fPIC \
|
||||
-Isrc \
|
||||
-I$(JAVA_HOME)/include \
|
||||
-I$(JAVA_HOME)/include/linux \
|
||||
-I$(JAVA_HOME)/include/apple \
|
||||
-I$(JAVA_HOME)/include/bsd \
|
||||
-Wall
|
||||
|
||||
SQLITE_OPT = \
|
||||
-DSQLITE_ENABLE_RTREE \
|
||||
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
|
||||
-DSQLITE_ENABLE_STMTVTAB \
|
||||
-DSQLITE_ENABLE_DBPAGE_VTAB \
|
||||
-DSQLITE_ENABLE_DBSTAT_VTAB \
|
||||
-DSQLITE_ENABLE_BYTECODE_VTAB \
|
||||
-DSQLITE_ENABLE_OFFSET_SQL_FUNC \
|
||||
-DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
-DSQLITE_OMIT_DEPRECATED \
|
||||
-DSQLITE_OMIT_SHARED_CACHE \
|
||||
-DSQLITE_THREADSAFE=0 \
|
||||
-DSQLITE_TEMP_STORE=2 \
|
||||
-DSQLITE_USE_URI=1 \
|
||||
-DSQLITE_ENABLE_FTS5
|
||||
|
||||
sqlite3-jni.dll = libsqlite3-jni.so
|
||||
$(sqlite3-jni.dll):
|
||||
@echo "************************************************************************"; \
|
||||
echo "*** If this fails to build, be sure to edit this makefile ***"; \
|
||||
echo "*** to configure it for your system. ***"; \
|
||||
echo "************************************************************************"
|
||||
$(CC) $(CFLAGS) $(SQLITE_OPT) \
|
||||
src/sqlite3-jni.c -shared -o $@
|
||||
@echo "Now try running it with: make test"
|
||||
|
||||
test: $(sqlite3-jni.dll)
|
||||
java -jar -Djava.library.path=. sqlite3-jni-*.jar
|
||||
|
||||
clean:
|
||||
-rm -f $(sqlite3-jni.dll)
|
||||
|
||||
all: $(sqlite3-jni.dll)
|
4420
ext/jni/src/c/sqlite3-jni.c
Normal file
4420
ext/jni/src/c/sqlite3-jni.c
Normal file
File diff suppressed because it is too large
Load Diff
1989
ext/jni/src/c/sqlite3-jni.h
Normal file
1989
ext/jni/src/c/sqlite3-jni.h
Normal file
File diff suppressed because it is too large
Load Diff
32
ext/jni/src/org/sqlite/jni/Authorizer.java
Normal file
32
ext/jni/src/org/sqlite/jni/Authorizer.java
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
** 2023-08-05
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This file is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
A callback for use with sqlite3_set_authorizer().
|
||||
*/
|
||||
public interface Authorizer {
|
||||
/**
|
||||
Must functions as described for the sqlite3_set_authorizer()
|
||||
callback, with one caveat: the string values passed here were
|
||||
initially (at the C level) encoded in standard UTF-8. If they
|
||||
contained any constructs which are not compatible with MUTF-8,
|
||||
these strings will not have the expected values. For further
|
||||
details, see the documentation for the SQLite3Jni class.
|
||||
|
||||
Must not throw.
|
||||
*/
|
||||
int xAuth(int opId, @Nullable String s1, @Nullable String s2,
|
||||
@Nullable String s3, @Nullable String s4);
|
||||
}
|
31
ext/jni/src/org/sqlite/jni/AutoExtension.java
Normal file
31
ext/jni/src/org/sqlite/jni/AutoExtension.java
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
** 2023-08-05
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This file is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
A callback for use with sqlite3_auto_extension().
|
||||
*/
|
||||
public interface AutoExtension {
|
||||
/**
|
||||
Must function as described for the sqlite3_auto_extension(),
|
||||
with the caveat that the signature is more limited.
|
||||
|
||||
As an exception (as it were) to the callbacks-must-not-throw
|
||||
rule, AutoExtensions may do so and the exception's error message
|
||||
will be set as the db's error string.
|
||||
|
||||
Results are undefined if db is closed by an auto-extension.
|
||||
*/
|
||||
int xEntryPoint(sqlite3 db);
|
||||
}
|
45
ext/jni/src/org/sqlite/jni/BusyHandler.java
Normal file
45
ext/jni/src/org/sqlite/jni/BusyHandler.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
** 2023-07-22
|
||||
**
|
||||
** 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 is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
Callback proxy for use with sqlite3_busy_handler().
|
||||
*/
|
||||
public abstract class BusyHandler {
|
||||
/**
|
||||
Must function as documented for the sqlite3_busy_handler()
|
||||
callback argument, minus the (void*) argument the C-level
|
||||
function requires.
|
||||
|
||||
Any exceptions thrown by this callback are suppressed in order to
|
||||
retain the C-style API semantics of the JNI bindings.
|
||||
*/
|
||||
public abstract int xCallback(int n);
|
||||
|
||||
/**
|
||||
Optionally override to perform any cleanup when this busy
|
||||
handler is destroyed. It is destroyed when:
|
||||
|
||||
- The associated db is passed to sqlite3_close() or
|
||||
sqlite3_close_v2().
|
||||
|
||||
- sqlite3_busy_handler() is called to replace the handler,
|
||||
whether it's passed a null handler or any other instance of
|
||||
this class.
|
||||
|
||||
- sqlite3_busy_timeout() is called, which implicitly installs
|
||||
a busy handler.
|
||||
*/
|
||||
public void xDestroy(){}
|
||||
}
|
28
ext/jni/src/org/sqlite/jni/Collation.java
Normal file
28
ext/jni/src/org/sqlite/jni/Collation.java
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
** 2023-07-22
|
||||
**
|
||||
** 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 is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
*/
|
||||
public abstract class Collation {
|
||||
/**
|
||||
Must compare the given byte arrays using memcmp() semantics.
|
||||
*/
|
||||
public abstract int xCompare(byte[] lhs, byte[] rhs);
|
||||
/**
|
||||
Called by SQLite when the collation is destroyed. If a Collation
|
||||
requires custom cleanup, override this method.
|
||||
*/
|
||||
public void xDestroy() {}
|
||||
}
|
28
ext/jni/src/org/sqlite/jni/CollationNeeded.java
Normal file
28
ext/jni/src/org/sqlite/jni/CollationNeeded.java
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
** 2023-07-30
|
||||
**
|
||||
** 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 is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
Callback proxy for use with sqlite3_collation_needed().
|
||||
*/
|
||||
public interface CollationNeeded {
|
||||
/**
|
||||
Has the same semantics as the C-level sqlite3_create_collation()
|
||||
callback.
|
||||
|
||||
If it throws, the exception message is passed on to the db and
|
||||
the exception is suppressed.
|
||||
*/
|
||||
int xCollationNeeded(sqlite3 db, int eTextRep, String collationName);
|
||||
}
|
25
ext/jni/src/org/sqlite/jni/CommitHook.java
Normal file
25
ext/jni/src/org/sqlite/jni/CommitHook.java
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
** 2023-07-22
|
||||
**
|
||||
** 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 is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
Callback proxy for use with sqlite3_commit_hook().
|
||||
*/
|
||||
public interface CommitHook {
|
||||
/**
|
||||
Works as documented for the sqlite3_commit_hook() callback.
|
||||
Must not throw.
|
||||
*/
|
||||
int xCommitHook();
|
||||
}
|
38
ext/jni/src/org/sqlite/jni/Fts5.java
Normal file
38
ext/jni/src/org/sqlite/jni/Fts5.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
** 2023-08-05
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This file is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
INCOMPLETE AND COMPLETELY UNTESTED.
|
||||
|
||||
A wrapper for communicating C-level (fts5_api*) instances with
|
||||
Java. These wrappers do not own their associated pointer, they
|
||||
simply provide a type-safe way to communicate it between Java and C
|
||||
via JNI.
|
||||
*/
|
||||
public final class Fts5 {
|
||||
/* Not used */
|
||||
private Fts5(){}
|
||||
|
||||
//! Callback type for use with xTokenize() variants
|
||||
public static interface xTokenizeCallback {
|
||||
int xToken(int tFlags, byte txt[], int iStart, int iEnd);
|
||||
}
|
||||
|
||||
public static final int FTS5_TOKENIZE_QUERY = 0x0001;
|
||||
public static final int FTS5_TOKENIZE_PREFIX = 0x0002;
|
||||
public static final int FTS5_TOKENIZE_DOCUMENT = 0x0004;
|
||||
public static final int FTS5_TOKENIZE_AUX = 0x0008;
|
||||
public static final int FTS5_TOKEN_COLOCATED = 0x0001;
|
||||
}
|
23
ext/jni/src/org/sqlite/jni/Fts5Context.java
Normal file
23
ext/jni/src/org/sqlite/jni/Fts5Context.java
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
** 2023-08-04
|
||||
**
|
||||
** 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 is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
A wrapper for communicating C-level (Fts5Context*) instances with
|
||||
Java. These wrappers do not own their associated pointer, they
|
||||
simply provide a type-safe way to communicate it between Java and C
|
||||
via JNI.
|
||||
*/
|
||||
public final class Fts5Context extends NativePointerHolder<Fts5Context> {
|
||||
}
|
86
ext/jni/src/org/sqlite/jni/Fts5ExtensionApi.java
Normal file
86
ext/jni/src/org/sqlite/jni/Fts5ExtensionApi.java
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
** 2023-08-04
|
||||
**
|
||||
** 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 is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
ALMOST COMPLETELY UNTESTED.
|
||||
|
||||
FAR FROM COMPLETE and the feasibility of binding this to Java
|
||||
is still undetermined. This might be removed.
|
||||
*/
|
||||
public final class Fts5ExtensionApi extends NativePointerHolder<Fts5ExtensionApi> {
|
||||
//! Only called from JNI
|
||||
private Fts5ExtensionApi(){}
|
||||
private int iVersion = 2;
|
||||
|
||||
/* Callback type for used by xQueryPhrase(). */
|
||||
public static interface xQueryPhraseCallback {
|
||||
int xCallback(Fts5ExtensionApi fapi, Fts5Context cx);
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the singleton instance of this class.
|
||||
*/
|
||||
public static synchronized native Fts5ExtensionApi getInstance();
|
||||
|
||||
public synchronized native int xColumnCount(@NotNull Fts5Context fcx);
|
||||
public synchronized native int xColumnSize(@NotNull Fts5Context cx, int iCol,
|
||||
@NotNull OutputPointer.Int32 pnToken);
|
||||
public synchronized native int xColumnText(@NotNull Fts5Context cx, int iCol,
|
||||
@NotNull OutputPointer.String txt);
|
||||
public synchronized native int xColumnTotalSize(@NotNull Fts5Context fcx, int iCol,
|
||||
@NotNull OutputPointer.Int64 pnToken);
|
||||
public synchronized native Object xGetAuxdata(@NotNull Fts5Context cx, boolean clearIt);
|
||||
public synchronized native int xInst(@NotNull Fts5Context cx, int iIdx,
|
||||
@NotNull OutputPointer.Int32 piPhrase,
|
||||
@NotNull OutputPointer.Int32 piCol,
|
||||
@NotNull OutputPointer.Int32 piOff);
|
||||
public synchronized native int xInstCount(@NotNull Fts5Context fcx,
|
||||
@NotNull OutputPointer.Int32 pnInst);
|
||||
public synchronized native int xPhraseCount(@NotNull Fts5Context fcx);
|
||||
public synchronized native int xPhraseFirst(@NotNull Fts5Context cx, int iPhrase,
|
||||
@NotNull Fts5PhraseIter iter,
|
||||
@NotNull OutputPointer.Int32 iCol,
|
||||
@NotNull OutputPointer.Int32 iOff);
|
||||
public synchronized native int xPhraseFirstColumn(@NotNull Fts5Context cx, int iPhrase,
|
||||
@NotNull Fts5PhraseIter iter,
|
||||
@NotNull OutputPointer.Int32 iCol);
|
||||
public synchronized native void xPhraseNext(@NotNull Fts5Context cx,
|
||||
@NotNull Fts5PhraseIter iter,
|
||||
@NotNull OutputPointer.Int32 iCol,
|
||||
@NotNull OutputPointer.Int32 iOff);
|
||||
public synchronized native void xPhraseNextColumn(@NotNull Fts5Context cx,
|
||||
@NotNull Fts5PhraseIter iter,
|
||||
@NotNull OutputPointer.Int32 iCol);
|
||||
public synchronized native int xPhraseSize(@NotNull Fts5Context fcx, int iPhrase);
|
||||
public synchronized native int xQueryPhrase(@NotNull Fts5Context cx, int iPhrase,
|
||||
@NotNull xQueryPhraseCallback callback);
|
||||
public synchronized native int xRowCount(@NotNull Fts5Context fcx,
|
||||
@NotNull OutputPointer.Int64 nRow);
|
||||
public synchronized native long xRowid(@NotNull Fts5Context cx);
|
||||
/* Note that the JNI binding lacks the C version's xDelete()
|
||||
callback argument. Instead, if pAux has an xDestroy() method, it
|
||||
is called if the FTS5 API finalizes the aux state (including if
|
||||
allocation of storage for the auxdata fails). Any reference to
|
||||
pAux held by the JNI layer will be relinquished regardless of
|
||||
whether pAux has an xDestroy() method. */
|
||||
public synchronized native int xSetAuxdata(@NotNull Fts5Context cx, @Nullable Object pAux);
|
||||
public synchronized native int xTokenize(@NotNull Fts5Context cx, @NotNull byte pText[],
|
||||
@NotNull Fts5.xTokenizeCallback callback);
|
||||
|
||||
public synchronized native Object xUserData(Fts5Context cx);
|
||||
//^^^ returns the pointer passed as the 3rd arg to the C-level
|
||||
// fts5_api::xCreateFunction.
|
||||
}
|
27
ext/jni/src/org/sqlite/jni/Fts5Function.java
Normal file
27
ext/jni/src/org/sqlite/jni/Fts5Function.java
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
** 2023-08-04
|
||||
**
|
||||
** 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 is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
Fts5Function is used in conjunction with the
|
||||
sqlite3_create_fts_function() JNI-bound API to give that native code
|
||||
access to the callback functions needed in order to implement
|
||||
FTS5 auxiliary functions in Java.
|
||||
*/
|
||||
public abstract class Fts5Function {
|
||||
|
||||
public abstract void xFunction(Fts5ExtensionApi pApi, Fts5Context pFts,
|
||||
sqlite3_context pCtx, sqlite3_value argv[]);
|
||||
public void xDestroy() {}
|
||||
}
|
24
ext/jni/src/org/sqlite/jni/Fts5PhraseIter.java
Normal file
24
ext/jni/src/org/sqlite/jni/Fts5PhraseIter.java
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
** 2023-08-04
|
||||
**
|
||||
** 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 is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
A wrapper for C-level Fts5PhraseIter. They are only modified and
|
||||
inspected by native-level code.
|
||||
*/
|
||||
public final class Fts5PhraseIter extends NativePointerHolder<Fts5PhraseIter> {
|
||||
//! Updated and used only by native code.
|
||||
private long a;
|
||||
private long b;
|
||||
}
|
30
ext/jni/src/org/sqlite/jni/Fts5Tokenizer.java
Normal file
30
ext/jni/src/org/sqlite/jni/Fts5Tokenizer.java
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
** 2023-08-05x
|
||||
**
|
||||
** 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 is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
INCOMPLETE AND COMPLETELY UNTESTED.
|
||||
|
||||
A wrapper for communicating C-level (Fts5Tokenizer*) instances with
|
||||
Java. These wrappers do not own their associated pointer, they
|
||||
simply provide a type-safe way to communicate it between Java and C
|
||||
via JNI.
|
||||
|
||||
At the C level, the Fts5Tokenizer type is essentially a void
|
||||
pointer used specifically for tokenizers.
|
||||
*/
|
||||
public final class Fts5Tokenizer extends NativePointerHolder<Fts5Tokenizer> {
|
||||
//! Only called from JNI.
|
||||
private Fts5Tokenizer(){}
|
||||
}
|
33
ext/jni/src/org/sqlite/jni/NativePointerHolder.java
Normal file
33
ext/jni/src/org/sqlite/jni/NativePointerHolder.java
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
** 2023-07-21
|
||||
**
|
||||
** 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 is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
A helper for passing pointers between JNI C code and Java, in
|
||||
particular for output pointers of high-level object types in the
|
||||
sqlite3 C API, e.g. (sqlite3**) and (sqlite3_stmt**). This is
|
||||
intended to be subclassed and the ContextType is intended to be the
|
||||
class which is doing the subclassing. The intent of the ContextType
|
||||
is strictly to provide some level of type safety by avoiding that
|
||||
NativePointerHolder is not inadvertently passed to an incompatible
|
||||
function signature.
|
||||
|
||||
These objects do not _own_ the pointer they refer to. They are
|
||||
intended simply to communicate that pointer between C and Java.
|
||||
*/
|
||||
public class NativePointerHolder<ContextType> {
|
||||
//! Only set from JNI, where access permissions don't matter.
|
||||
private long nativePointer = 0;
|
||||
public final long getNativePointer(){ return nativePointer; }
|
||||
}
|
165
ext/jni/src/org/sqlite/jni/OutputPointer.java
Normal file
165
ext/jni/src/org/sqlite/jni/OutputPointer.java
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
** 2023-07-21
|
||||
**
|
||||
** 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 is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
Helper classes for handling JNI output pointers.
|
||||
|
||||
We do not use a generic OutputPointer<T> because working with those
|
||||
from the native JNI code is unduly quirky due to a lack of
|
||||
autoboxing at that level.
|
||||
|
||||
The usage is similar for all of thes types:
|
||||
|
||||
```
|
||||
OutputPointer.sqlite3 out = new OutputPointer.sqlite3();
|
||||
assert( null==out.get() );
|
||||
int rc = sqlite3_open(":memory:", out);
|
||||
if( 0!=rc ) ... error;
|
||||
assert( null!=out.get() );
|
||||
sqlite3 db = out.take();
|
||||
assert( null==out.get() );
|
||||
```
|
||||
|
||||
With the minor exception that the primitive types permit direct
|
||||
access to the object's value via the `value` property, whereas the
|
||||
JNI-level opaque types do not permit client-level code to set that
|
||||
property.
|
||||
*/
|
||||
public final class OutputPointer {
|
||||
|
||||
/**
|
||||
Output pointer for use with routines, such as sqlite3_open(),
|
||||
which return a database handle via an output pointer. These
|
||||
pointers can only be set by the JNI layer, not by client-level
|
||||
code.
|
||||
*/
|
||||
public static final class sqlite3 {
|
||||
private org.sqlite.jni.sqlite3 value;
|
||||
//! Initializes with a null value.
|
||||
public sqlite3(){value = null;}
|
||||
//! Sets the current value to null.
|
||||
public void clear(){value = null;}
|
||||
//! Returns the current value.
|
||||
public final org.sqlite.jni.sqlite3 get(){return value;}
|
||||
//! Equivalent to calling get() then clear().
|
||||
public final org.sqlite.jni.sqlite3 take(){
|
||||
final org.sqlite.jni.sqlite3 v = value;
|
||||
value = null;
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Output pointer for use with routines, such as sqlite3_prepare(),
|
||||
which return a statement handle via an output pointer. These
|
||||
pointers can only be set by the JNI layer, not by client-level
|
||||
code.
|
||||
*/
|
||||
public static final class sqlite3_stmt {
|
||||
private org.sqlite.jni.sqlite3_stmt value;
|
||||
//! Initializes with a null value.
|
||||
public sqlite3_stmt(){value = null;}
|
||||
//! Sets the current value to null.
|
||||
public void clear(){value = null;}
|
||||
//! Returns the current value.
|
||||
public final org.sqlite.jni.sqlite3_stmt get(){return value;}
|
||||
//! Equivalent to calling get() then clear().
|
||||
public final org.sqlite.jni.sqlite3_stmt take(){
|
||||
final org.sqlite.jni.sqlite3_stmt v = value;
|
||||
value = null;
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Output pointer for use with native routines which return integers via
|
||||
output pointers.
|
||||
*/
|
||||
public static final class Int32 {
|
||||
/**
|
||||
This is public for ease of use. Accessors are provided for
|
||||
consistency with the higher-level types.
|
||||
*/
|
||||
public int value;
|
||||
//! Initializes with the value 0.
|
||||
public Int32(){this(0);}
|
||||
//! Initializes with the value v.
|
||||
public Int32(int v){value = v;}
|
||||
//! Returns the current value.
|
||||
public final int get(){return value;}
|
||||
//! Sets the current value to v.
|
||||
public final void set(int v){value = v;}
|
||||
}
|
||||
|
||||
/**
|
||||
Output pointer for use with native routines which return 64-bit integers
|
||||
via output pointers.
|
||||
*/
|
||||
public static final class Int64 {
|
||||
/**
|
||||
This is public for ease of use. Accessors are provided for
|
||||
consistency with the higher-level types.
|
||||
*/
|
||||
public long value;
|
||||
//! Initializes with the value 0.
|
||||
public Int64(){this(0);}
|
||||
//! Initializes with the value v.
|
||||
public Int64(long v){value = v;}
|
||||
//! Returns the current value.
|
||||
public final long get(){return value;}
|
||||
//! Sets the current value.
|
||||
public final void set(long v){value = v;}
|
||||
}
|
||||
|
||||
/**
|
||||
Output pointer for use with native routines which return strings via
|
||||
output pointers.
|
||||
*/
|
||||
public static final class String {
|
||||
/**
|
||||
This is public for ease of use. Accessors are provided for
|
||||
consistency with the higher-level types.
|
||||
*/
|
||||
public java.lang.String value;
|
||||
//! Initializes with a null value.
|
||||
public String(){this(null);}
|
||||
//! Initializes with the value v.
|
||||
public String(java.lang.String v){value = v;}
|
||||
//! Returns the current value.
|
||||
public final java.lang.String get(){return value;}
|
||||
//! Sets the current value.
|
||||
public final void set(java.lang.String v){value = v;}
|
||||
}
|
||||
|
||||
/**
|
||||
Output pointer for use with native routines which return byte
|
||||
arrays via output pointers.
|
||||
*/
|
||||
public static final class ByteArray {
|
||||
/**
|
||||
This is public for ease of use. Accessors are provided for
|
||||
consistency with the higher-level types.
|
||||
*/
|
||||
public byte[] value;
|
||||
//! Initializes with the value null.
|
||||
public ByteArray(){this(null);}
|
||||
//! Initializes with the value v.
|
||||
public ByteArray(byte[] v){value = v;}
|
||||
//! Returns the current value.
|
||||
public final byte[] get(){return value;}
|
||||
//! Sets the current value.
|
||||
public final void set(byte[] v){value = v;}
|
||||
}
|
||||
}
|
27
ext/jni/src/org/sqlite/jni/ProgressHandler.java
Normal file
27
ext/jni/src/org/sqlite/jni/ProgressHandler.java
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
** 2023-07-22
|
||||
**
|
||||
** 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 is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
Callback proxy for use with sqlite3_progress_handler().
|
||||
*/
|
||||
public interface ProgressHandler {
|
||||
/**
|
||||
Works as documented for the sqlite3_progress_handler() callback.
|
||||
|
||||
If it throws, the exception message is passed on to the db and
|
||||
the exception is suppressed.
|
||||
*/
|
||||
int xCallback();
|
||||
}
|
155
ext/jni/src/org/sqlite/jni/ResultCode.java
Normal file
155
ext/jni/src/org/sqlite/jni/ResultCode.java
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
** 2023-07-21
|
||||
**
|
||||
** 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 is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
This enum contains all of the core and "extended" result codes used
|
||||
by the sqlite3 library. It is provided not for use with the C-style
|
||||
API (with which it won't work) but for higher-level code which may
|
||||
find it useful to map SQLite result codes to human-readable names.
|
||||
*/
|
||||
public enum ResultCode {
|
||||
SQLITE_OK(SQLite3Jni.SQLITE_OK),
|
||||
SQLITE_ERROR(SQLite3Jni.SQLITE_ERROR),
|
||||
SQLITE_INTERNAL(SQLite3Jni.SQLITE_INTERNAL),
|
||||
SQLITE_PERM(SQLite3Jni.SQLITE_PERM),
|
||||
SQLITE_ABORT(SQLite3Jni.SQLITE_ABORT),
|
||||
SQLITE_BUSY(SQLite3Jni.SQLITE_BUSY),
|
||||
SQLITE_LOCKED(SQLite3Jni.SQLITE_LOCKED),
|
||||
SQLITE_NOMEM(SQLite3Jni.SQLITE_NOMEM),
|
||||
SQLITE_READONLY(SQLite3Jni.SQLITE_READONLY),
|
||||
SQLITE_INTERRUPT(SQLite3Jni.SQLITE_INTERRUPT),
|
||||
SQLITE_IOERR(SQLite3Jni.SQLITE_IOERR),
|
||||
SQLITE_CORRUPT(SQLite3Jni.SQLITE_CORRUPT),
|
||||
SQLITE_NOTFOUND(SQLite3Jni.SQLITE_NOTFOUND),
|
||||
SQLITE_FULL(SQLite3Jni.SQLITE_FULL),
|
||||
SQLITE_CANTOPEN(SQLite3Jni.SQLITE_CANTOPEN),
|
||||
SQLITE_PROTOCOL(SQLite3Jni.SQLITE_PROTOCOL),
|
||||
SQLITE_EMPTY(SQLite3Jni.SQLITE_EMPTY),
|
||||
SQLITE_SCHEMA(SQLite3Jni.SQLITE_SCHEMA),
|
||||
SQLITE_TOOBIG(SQLite3Jni.SQLITE_TOOBIG),
|
||||
SQLITE_CONSTRAINT(SQLite3Jni.SQLITE_CONSTRAINT),
|
||||
SQLITE_MISMATCH(SQLite3Jni.SQLITE_MISMATCH),
|
||||
SQLITE_MISUSE(SQLite3Jni.SQLITE_MISUSE),
|
||||
SQLITE_NOLFS(SQLite3Jni.SQLITE_NOLFS),
|
||||
SQLITE_AUTH(SQLite3Jni.SQLITE_AUTH),
|
||||
SQLITE_FORMAT(SQLite3Jni.SQLITE_FORMAT),
|
||||
SQLITE_RANGE(SQLite3Jni.SQLITE_RANGE),
|
||||
SQLITE_NOTADB(SQLite3Jni.SQLITE_NOTADB),
|
||||
SQLITE_NOTICE(SQLite3Jni.SQLITE_NOTICE),
|
||||
SQLITE_WARNING(SQLite3Jni.SQLITE_WARNING),
|
||||
SQLITE_ROW(SQLite3Jni.SQLITE_ROW),
|
||||
SQLITE_DONE(SQLite3Jni.SQLITE_DONE),
|
||||
SQLITE_ERROR_MISSING_COLLSEQ(SQLite3Jni.SQLITE_ERROR_MISSING_COLLSEQ),
|
||||
SQLITE_ERROR_RETRY(SQLite3Jni.SQLITE_ERROR_RETRY),
|
||||
SQLITE_ERROR_SNAPSHOT(SQLite3Jni.SQLITE_ERROR_SNAPSHOT),
|
||||
SQLITE_IOERR_READ(SQLite3Jni.SQLITE_IOERR_READ),
|
||||
SQLITE_IOERR_SHORT_READ(SQLite3Jni.SQLITE_IOERR_SHORT_READ),
|
||||
SQLITE_IOERR_WRITE(SQLite3Jni.SQLITE_IOERR_WRITE),
|
||||
SQLITE_IOERR_FSYNC(SQLite3Jni.SQLITE_IOERR_FSYNC),
|
||||
SQLITE_IOERR_DIR_FSYNC(SQLite3Jni.SQLITE_IOERR_DIR_FSYNC),
|
||||
SQLITE_IOERR_TRUNCATE(SQLite3Jni.SQLITE_IOERR_TRUNCATE),
|
||||
SQLITE_IOERR_FSTAT(SQLite3Jni.SQLITE_IOERR_FSTAT),
|
||||
SQLITE_IOERR_UNLOCK(SQLite3Jni.SQLITE_IOERR_UNLOCK),
|
||||
SQLITE_IOERR_RDLOCK(SQLite3Jni.SQLITE_IOERR_RDLOCK),
|
||||
SQLITE_IOERR_DELETE(SQLite3Jni.SQLITE_IOERR_DELETE),
|
||||
SQLITE_IOERR_BLOCKED(SQLite3Jni.SQLITE_IOERR_BLOCKED),
|
||||
SQLITE_IOERR_NOMEM(SQLite3Jni.SQLITE_IOERR_NOMEM),
|
||||
SQLITE_IOERR_ACCESS(SQLite3Jni.SQLITE_IOERR_ACCESS),
|
||||
SQLITE_IOERR_CHECKRESERVEDLOCK(SQLite3Jni.SQLITE_IOERR_CHECKRESERVEDLOCK),
|
||||
SQLITE_IOERR_LOCK(SQLite3Jni.SQLITE_IOERR_LOCK),
|
||||
SQLITE_IOERR_CLOSE(SQLite3Jni.SQLITE_IOERR_CLOSE),
|
||||
SQLITE_IOERR_DIR_CLOSE(SQLite3Jni.SQLITE_IOERR_DIR_CLOSE),
|
||||
SQLITE_IOERR_SHMOPEN(SQLite3Jni.SQLITE_IOERR_SHMOPEN),
|
||||
SQLITE_IOERR_SHMSIZE(SQLite3Jni.SQLITE_IOERR_SHMSIZE),
|
||||
SQLITE_IOERR_SHMLOCK(SQLite3Jni.SQLITE_IOERR_SHMLOCK),
|
||||
SQLITE_IOERR_SHMMAP(SQLite3Jni.SQLITE_IOERR_SHMMAP),
|
||||
SQLITE_IOERR_SEEK(SQLite3Jni.SQLITE_IOERR_SEEK),
|
||||
SQLITE_IOERR_DELETE_NOENT(SQLite3Jni.SQLITE_IOERR_DELETE_NOENT),
|
||||
SQLITE_IOERR_MMAP(SQLite3Jni.SQLITE_IOERR_MMAP),
|
||||
SQLITE_IOERR_GETTEMPPATH(SQLite3Jni.SQLITE_IOERR_GETTEMPPATH),
|
||||
SQLITE_IOERR_CONVPATH(SQLite3Jni.SQLITE_IOERR_CONVPATH),
|
||||
SQLITE_IOERR_VNODE(SQLite3Jni.SQLITE_IOERR_VNODE),
|
||||
SQLITE_IOERR_AUTH(SQLite3Jni.SQLITE_IOERR_AUTH),
|
||||
SQLITE_IOERR_BEGIN_ATOMIC(SQLite3Jni.SQLITE_IOERR_BEGIN_ATOMIC),
|
||||
SQLITE_IOERR_COMMIT_ATOMIC(SQLite3Jni.SQLITE_IOERR_COMMIT_ATOMIC),
|
||||
SQLITE_IOERR_ROLLBACK_ATOMIC(SQLite3Jni.SQLITE_IOERR_ROLLBACK_ATOMIC),
|
||||
SQLITE_IOERR_DATA(SQLite3Jni.SQLITE_IOERR_DATA),
|
||||
SQLITE_IOERR_CORRUPTFS(SQLite3Jni.SQLITE_IOERR_CORRUPTFS),
|
||||
SQLITE_LOCKED_SHAREDCACHE(SQLite3Jni.SQLITE_LOCKED_SHAREDCACHE),
|
||||
SQLITE_LOCKED_VTAB(SQLite3Jni.SQLITE_LOCKED_VTAB),
|
||||
SQLITE_BUSY_RECOVERY(SQLite3Jni.SQLITE_BUSY_RECOVERY),
|
||||
SQLITE_BUSY_SNAPSHOT(SQLite3Jni.SQLITE_BUSY_SNAPSHOT),
|
||||
SQLITE_BUSY_TIMEOUT(SQLite3Jni.SQLITE_BUSY_TIMEOUT),
|
||||
SQLITE_CANTOPEN_NOTEMPDIR(SQLite3Jni.SQLITE_CANTOPEN_NOTEMPDIR),
|
||||
SQLITE_CANTOPEN_ISDIR(SQLite3Jni.SQLITE_CANTOPEN_ISDIR),
|
||||
SQLITE_CANTOPEN_FULLPATH(SQLite3Jni.SQLITE_CANTOPEN_FULLPATH),
|
||||
SQLITE_CANTOPEN_CONVPATH(SQLite3Jni.SQLITE_CANTOPEN_CONVPATH),
|
||||
SQLITE_CANTOPEN_SYMLINK(SQLite3Jni.SQLITE_CANTOPEN_SYMLINK),
|
||||
SQLITE_CORRUPT_VTAB(SQLite3Jni.SQLITE_CORRUPT_VTAB),
|
||||
SQLITE_CORRUPT_SEQUENCE(SQLite3Jni.SQLITE_CORRUPT_SEQUENCE),
|
||||
SQLITE_CORRUPT_INDEX(SQLite3Jni.SQLITE_CORRUPT_INDEX),
|
||||
SQLITE_READONLY_RECOVERY(SQLite3Jni.SQLITE_READONLY_RECOVERY),
|
||||
SQLITE_READONLY_CANTLOCK(SQLite3Jni.SQLITE_READONLY_CANTLOCK),
|
||||
SQLITE_READONLY_ROLLBACK(SQLite3Jni.SQLITE_READONLY_ROLLBACK),
|
||||
SQLITE_READONLY_DBMOVED(SQLite3Jni.SQLITE_READONLY_DBMOVED),
|
||||
SQLITE_READONLY_CANTINIT(SQLite3Jni.SQLITE_READONLY_CANTINIT),
|
||||
SQLITE_READONLY_DIRECTORY(SQLite3Jni.SQLITE_READONLY_DIRECTORY),
|
||||
SQLITE_ABORT_ROLLBACK(SQLite3Jni.SQLITE_ABORT_ROLLBACK),
|
||||
SQLITE_CONSTRAINT_CHECK(SQLite3Jni.SQLITE_CONSTRAINT_CHECK),
|
||||
SQLITE_CONSTRAINT_COMMITHOOK(SQLite3Jni.SQLITE_CONSTRAINT_COMMITHOOK),
|
||||
SQLITE_CONSTRAINT_FOREIGNKEY(SQLite3Jni.SQLITE_CONSTRAINT_FOREIGNKEY),
|
||||
SQLITE_CONSTRAINT_FUNCTION(SQLite3Jni.SQLITE_CONSTRAINT_FUNCTION),
|
||||
SQLITE_CONSTRAINT_NOTNULL(SQLite3Jni.SQLITE_CONSTRAINT_NOTNULL),
|
||||
SQLITE_CONSTRAINT_PRIMARYKEY(SQLite3Jni.SQLITE_CONSTRAINT_PRIMARYKEY),
|
||||
SQLITE_CONSTRAINT_TRIGGER(SQLite3Jni.SQLITE_CONSTRAINT_TRIGGER),
|
||||
SQLITE_CONSTRAINT_UNIQUE(SQLite3Jni.SQLITE_CONSTRAINT_UNIQUE),
|
||||
SQLITE_CONSTRAINT_VTAB(SQLite3Jni.SQLITE_CONSTRAINT_VTAB),
|
||||
SQLITE_CONSTRAINT_ROWID(SQLite3Jni.SQLITE_CONSTRAINT_ROWID),
|
||||
SQLITE_CONSTRAINT_PINNED(SQLite3Jni.SQLITE_CONSTRAINT_PINNED),
|
||||
SQLITE_CONSTRAINT_DATATYPE(SQLite3Jni.SQLITE_CONSTRAINT_DATATYPE),
|
||||
SQLITE_NOTICE_RECOVER_WAL(SQLite3Jni.SQLITE_NOTICE_RECOVER_WAL),
|
||||
SQLITE_NOTICE_RECOVER_ROLLBACK(SQLite3Jni.SQLITE_NOTICE_RECOVER_ROLLBACK),
|
||||
SQLITE_WARNING_AUTOINDEX(SQLite3Jni.SQLITE_WARNING_AUTOINDEX),
|
||||
SQLITE_AUTH_USER(SQLite3Jni.SQLITE_AUTH_USER),
|
||||
SQLITE_OK_LOAD_PERMANENTLY(SQLite3Jni.SQLITE_OK_LOAD_PERMANENTLY);
|
||||
|
||||
public final int value;
|
||||
|
||||
ResultCode(int rc){
|
||||
value = rc;
|
||||
ResultCodeMap.set(rc, this);
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the entry from this enum for the given result code, or
|
||||
null if no match is found.
|
||||
*/
|
||||
public static ResultCode getEntryForInt(int rc){
|
||||
return ResultCodeMap.get(rc);
|
||||
}
|
||||
|
||||
/**
|
||||
Internal level of indirection required because we cannot initialize
|
||||
static enum members in an enum before the enum constructor is
|
||||
invoked.
|
||||
*/
|
||||
private static final class ResultCodeMap {
|
||||
private static final java.util.Map<Integer,ResultCode> i2e
|
||||
= new java.util.HashMap<>();
|
||||
private static void set(int rc, ResultCode e){ i2e.put(rc, e); }
|
||||
private static ResultCode get(int rc){ return i2e.get(rc); }
|
||||
}
|
||||
|
||||
}
|
25
ext/jni/src/org/sqlite/jni/RollbackHook.java
Normal file
25
ext/jni/src/org/sqlite/jni/RollbackHook.java
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
** 2023-07-22
|
||||
**
|
||||
** 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 is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
Callback proxy for use with sqlite3_rollback_hook().
|
||||
*/
|
||||
public interface RollbackHook {
|
||||
/**
|
||||
Works as documented for the sqlite3_rollback_hook() callback.
|
||||
Must not throw.
|
||||
*/
|
||||
void xRollbackHook();
|
||||
}
|
172
ext/jni/src/org/sqlite/jni/SQLFunction.java
Normal file
172
ext/jni/src/org/sqlite/jni/SQLFunction.java
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
** 2023-07-22
|
||||
**
|
||||
** 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 is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
SQLFunction is used in conjunction with the
|
||||
sqlite3_create_function() JNI-bound API to give that native code
|
||||
access to the callback functions needed in order to implement SQL
|
||||
functions in Java.
|
||||
|
||||
This class is not used by itself, but is a marker base class. The
|
||||
three UDF types are modelled by the inner classes Scalar,
|
||||
Aggregate<T>, and Window<T>. Most simply, clients may create
|
||||
anonymous classes from those to implement UDFs. Clients are free to
|
||||
create their own classes for use with UDFs, so long as they conform
|
||||
to the public interfaces defined by those three classes. The JNI
|
||||
layer only actively relies on the SQLFunction base class.
|
||||
*/
|
||||
public abstract class SQLFunction {
|
||||
|
||||
/**
|
||||
PerContextState assists aggregate and window functions in
|
||||
managinga their accumulator state across calls to the UDF's
|
||||
callbacks.
|
||||
|
||||
If a given aggregate or window function is called multiple times
|
||||
in a single SQL statement, e.g. SELECT MYFUNC(A), MYFUNC(B)...,
|
||||
then the clients need some way of knowing which call is which so
|
||||
that they can map their state between their various UDF callbacks
|
||||
and reset it via xFinal(). This class takes care of such
|
||||
mappings.
|
||||
|
||||
This class works by mapping
|
||||
sqlite3_context.getAggregateContext() to a single piece of
|
||||
state, of a client-defined type (the T part of this class), which
|
||||
persists across a "matching set" of the UDF's callbacks.
|
||||
|
||||
This class is a helper providing commonly-needed functionality -
|
||||
it is not required for use with aggregate or window functions.
|
||||
Client UDFs are free to perform such mappings using custom
|
||||
approaches. The provided Aggregate<T> and Window<T> classes
|
||||
use this.
|
||||
*/
|
||||
public static final class PerContextState<T> {
|
||||
private final java.util.Map<Long,ValueHolder<T>> map
|
||||
= new java.util.HashMap<>();
|
||||
|
||||
/**
|
||||
Should be called from a UDF's xStep(), xValue(), and xInverse()
|
||||
methods, passing it that method's first argument and an initial
|
||||
value for the persistent state. If there is currently no
|
||||
mapping for cx.getAggregateContext() within the map, one is
|
||||
created using the given initial value, else the existing one is
|
||||
used and the 2nd argument is ignored. It returns a
|
||||
ValueHolder<T> which can be used to modify that state directly
|
||||
without requiring that the client update the underlying map's
|
||||
entry.
|
||||
|
||||
T must be of a type which can be legally stored as a value in
|
||||
java.util.HashMap<KeyType,T>.
|
||||
*/
|
||||
public ValueHolder<T> getAggregateState(sqlite3_context cx, T initialValue){
|
||||
ValueHolder<T> rc = map.get(cx.getAggregateContext());
|
||||
if(null == rc){
|
||||
map.put(cx.getAggregateContext(), rc = new ValueHolder<>(initialValue));
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
Should be called from a UDF's xFinal() method and passed that
|
||||
method's first argument. This function removes the value
|
||||
associated with cx.getAggregateContext() from the map and
|
||||
returns it, returning null if no other UDF method has been
|
||||
called to set up such a mapping. The latter condition will be
|
||||
the case if a UDF is used in a statement which has no result
|
||||
rows.
|
||||
*/
|
||||
public T takeAggregateState(sqlite3_context cx){
|
||||
final ValueHolder<T> h = map.remove(cx.getAggregateContext());
|
||||
return null==h ? null : h.value;
|
||||
}
|
||||
}
|
||||
|
||||
//! Subclass for creating scalar functions.
|
||||
public static abstract class Scalar extends SQLFunction {
|
||||
|
||||
//! As for the xFunc() argument of the C API's sqlite3_create_function()
|
||||
public abstract void xFunc(sqlite3_context cx, sqlite3_value[] args);
|
||||
|
||||
/**
|
||||
Optionally override to be notified when the UDF is finalized by
|
||||
SQLite.
|
||||
*/
|
||||
public void xDestroy() {}
|
||||
}
|
||||
|
||||
/**
|
||||
SQLFunction Subclass for creating aggregate functions. Its T is
|
||||
the data type of its "accumulator" state, an instance of which is
|
||||
intended to be be managed using the getAggregateState() and
|
||||
takeAggregateState() methods.
|
||||
*/
|
||||
public static abstract class Aggregate<T> extends SQLFunction {
|
||||
|
||||
//! As for the xStep() argument of the C API's sqlite3_create_function()
|
||||
public abstract void xStep(sqlite3_context cx, sqlite3_value[] args);
|
||||
|
||||
//! As for the xFinal() argument of the C API's sqlite3_create_function()
|
||||
public abstract void xFinal(sqlite3_context cx);
|
||||
|
||||
/**
|
||||
Optionally override to be notified when the UDF is finalized by
|
||||
SQLite.
|
||||
*/
|
||||
public void xDestroy() {}
|
||||
|
||||
//! Per-invocation state for the UDF.
|
||||
private final PerContextState<T> map = new PerContextState<>();
|
||||
|
||||
/**
|
||||
To be called from the implementation's xStep() method, as well
|
||||
as the xValue() and xInverse() methods of the Window<T>
|
||||
subclass, to fetch the current per-call UDF state. On the
|
||||
first call to this method for any given sqlite3_context
|
||||
argument, the context is set to the given initial value. On all other
|
||||
calls, the 2nd argument is ignored.
|
||||
|
||||
@see PerContextState<T>#takeAggregateState()
|
||||
*/
|
||||
protected final ValueHolder<T> getAggregateState(sqlite3_context cx, T initialValue){
|
||||
return map.getAggregateState(cx, initialValue);
|
||||
}
|
||||
|
||||
/**
|
||||
To be called from the implementation's xFinal() method to fetch
|
||||
the final state of the UDF and remove its mapping.
|
||||
|
||||
@see PerContextState<T>#takeAggregateState()
|
||||
*/
|
||||
protected final T takeAggregateState(sqlite3_context cx){
|
||||
return map.takeAggregateState(cx);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
An SQLFunction subclass for creating window functions. Note that
|
||||
Window<T> inherits from Aggregate<T> and each instance is
|
||||
required to implement the inherited abstract methods from that
|
||||
class. See Aggregate<T> for information on managing the UDF's
|
||||
invocation-specific state.
|
||||
*/
|
||||
public static abstract class Window<T> extends Aggregate<T> {
|
||||
|
||||
//! As for the xInverse() argument of the C API's sqlite3_create_window_function()
|
||||
public abstract void xInverse(sqlite3_context cx, sqlite3_value[] args);
|
||||
|
||||
//! As for the xValue() argument of the C API's sqlite3_create_window_function()
|
||||
public abstract void xValue(sqlite3_context cx);
|
||||
}
|
||||
}
|
1645
ext/jni/src/org/sqlite/jni/SQLite3Jni.java
Normal file
1645
ext/jni/src/org/sqlite/jni/SQLite3Jni.java
Normal file
File diff suppressed because it is too large
Load Diff
1163
ext/jni/src/org/sqlite/jni/Tester1.java
Normal file
1163
ext/jni/src/org/sqlite/jni/Tester1.java
Normal file
File diff suppressed because it is too large
Load Diff
87
ext/jni/src/org/sqlite/jni/TesterFts5.java
Normal file
87
ext/jni/src/org/sqlite/jni/TesterFts5.java
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
** 2023-08-04
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This file contains a set of tests for the sqlite3 JNI bindings.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
import static org.sqlite.jni.SQLite3Jni.*;
|
||||
import static org.sqlite.jni.Tester1.*;
|
||||
|
||||
public class TesterFts5 {
|
||||
|
||||
private static void test1(){
|
||||
Fts5ExtensionApi fea = Fts5ExtensionApi.getInstance();
|
||||
affirm( null != fea );
|
||||
affirm( fea.getNativePointer() != 0 );
|
||||
affirm( fea == Fts5ExtensionApi.getInstance() )/*singleton*/;
|
||||
|
||||
sqlite3 db = createNewDb();
|
||||
fts5_api fApi = fts5_api.getInstanceForDb(db);
|
||||
affirm( fApi != null );
|
||||
affirm( fApi == fts5_api.getInstanceForDb(db) /* singleton per db */ );
|
||||
|
||||
execSql(db, new String[] {
|
||||
"CREATE VIRTUAL TABLE ft USING fts5(a, b);",
|
||||
"INSERT INTO ft(rowid, a, b) VALUES(1, 'X Y', 'Y Z');",
|
||||
"INSERT INTO ft(rowid, a, b) VALUES(2, 'A Z', 'Y Y');"
|
||||
});
|
||||
|
||||
final String pUserData = "This is pUserData";
|
||||
ValueHolder<Boolean> xDestroyCalled = new ValueHolder<>(false);
|
||||
ValueHolder<Integer> xFuncCount = new ValueHolder<>(0);
|
||||
final fts5_extension_function func = new fts5_extension_function(){
|
||||
public void xFunction(Fts5ExtensionApi ext, Fts5Context fCx,
|
||||
sqlite3_context pCx, sqlite3_value argv[]){
|
||||
int nCols = ext.xColumnCount(fCx);
|
||||
affirm( 2 == nCols );
|
||||
affirm( nCols == argv.length );
|
||||
affirm( ext.xUserData(fCx) == pUserData );
|
||||
if(true){
|
||||
OutputPointer.String op = new OutputPointer.String();
|
||||
for(int i = 0; i < nCols; ++i ){
|
||||
int rc = ext.xColumnText(fCx, i, op);
|
||||
affirm( 0 == rc );
|
||||
final String val = op.value;
|
||||
affirm( val.equals(sqlite3_value_text(argv[i])) );
|
||||
//outln("xFunction col "+i+": "+val);
|
||||
}
|
||||
}
|
||||
++xFuncCount.value;
|
||||
}
|
||||
public void xDestroy(){
|
||||
xDestroyCalled.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
int rc = fApi.xCreateFunction("myaux", pUserData, func);
|
||||
affirm( 0==rc );
|
||||
|
||||
affirm( 0==xFuncCount.value );
|
||||
execSql(db, "select myaux(ft,a,b) from ft;");
|
||||
affirm( 2==xFuncCount.value );
|
||||
affirm( !xDestroyCalled.value );
|
||||
sqlite3_close_v2(db);
|
||||
affirm( xDestroyCalled.value );
|
||||
}
|
||||
|
||||
public TesterFts5(){
|
||||
int oldAffirmCount = Tester1.affirmCount;
|
||||
Tester1.affirmCount = 0;
|
||||
final long timeStart = System.nanoTime();
|
||||
test1();
|
||||
final long timeEnd = System.nanoTime();
|
||||
outln("FTS5 Tests done. Metrics:");
|
||||
outln("\tAssertions checked: "+Tester1.affirmCount);
|
||||
outln("\tTotal time = "
|
||||
+((timeEnd - timeStart)/1000000.0)+"ms");
|
||||
Tester1.affirmCount = oldAffirmCount;
|
||||
}
|
||||
}
|
62
ext/jni/src/org/sqlite/jni/Tracer.java
Normal file
62
ext/jni/src/org/sqlite/jni/Tracer.java
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
** 2023-07-22
|
||||
**
|
||||
** 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 is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
Callback proxy for use with sqlite3_trace_v2().
|
||||
*/
|
||||
public interface Tracer {
|
||||
/**
|
||||
Achtung: this interface is subject to change because the current
|
||||
approach to mapping the passed-in natives back to Java is
|
||||
uncomfortably quirky.
|
||||
|
||||
Called by sqlite3 for various tracing operations, as per
|
||||
sqlite3_trace_v2(). Note that this interface elides the 2nd
|
||||
argument to the native trace callback, as that role is better
|
||||
filled by instance-local state.
|
||||
|
||||
The 2nd argument to this function, if non-0, will be a native
|
||||
pointer to either an sqlite3 or sqlite3_stmt object, depending on
|
||||
the first argument (see below). Client code can pass it to the
|
||||
sqlite3 resp. sqlite3_stmt constructor to create a wrapping
|
||||
object, if necessary. This API does not do so by default because
|
||||
tracing can be called frequently, creating such a wrapper for
|
||||
each call is comparatively expensive, and the objects are
|
||||
probably only seldom useful.
|
||||
|
||||
The final argument to this function is the "X" argument
|
||||
documented for sqlite3_trace() and sqlite3_trace_v2(). Its type
|
||||
depends on value of the first argument:
|
||||
|
||||
- SQLITE_TRACE_STMT: pNative is a sqlite3_stmt. pX is a string
|
||||
containing the prepared SQL, with one caveat: JNI only provides
|
||||
us with the ability to convert that string to MUTF-8, as
|
||||
opposed to standard UTF-8, and is cannot be ruled out that that
|
||||
difference may be significant for certain inputs. The
|
||||
alternative would be that we first convert it to UTF-16 before
|
||||
passing it on, but there's no readily-available way to do that
|
||||
without calling back into the db to peform the conversion
|
||||
(which would lead to further tracing).
|
||||
|
||||
- SQLITE_TRACE_PROFILE: pNative is a sqlite3_stmt. pX is a Long
|
||||
holding an approximate number of nanoseconds the statement took
|
||||
to run.
|
||||
|
||||
- SQLITE_TRACE_ROW: pNative is a sqlite3_stmt. pX is null.
|
||||
|
||||
- SQLITE_TRACE_CLOSE: pNative is a sqlite3. pX is null.
|
||||
*/
|
||||
int xCallback(int traceFlag, Object pNative, Object pX);
|
||||
}
|
25
ext/jni/src/org/sqlite/jni/UpdateHook.java
Normal file
25
ext/jni/src/org/sqlite/jni/UpdateHook.java
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
** 2023-07-22
|
||||
**
|
||||
** 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 is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
Callback proxy for use with sqlite3_update_hook().
|
||||
*/
|
||||
public interface UpdateHook {
|
||||
/**
|
||||
Works as documented for the sqlite3_update_hook() callback.
|
||||
Must not throw.
|
||||
*/
|
||||
void xUpdateHook(int opId, String dbName, String tableName, long rowId);
|
||||
}
|
25
ext/jni/src/org/sqlite/jni/ValueHolder.java
Normal file
25
ext/jni/src/org/sqlite/jni/ValueHolder.java
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
** 2023-07-21
|
||||
**
|
||||
** 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 is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
A helper class which simply holds a single value. Its current use
|
||||
is for communicating values out of anonymous classes, as doing so
|
||||
requires a "final" reference.
|
||||
*/
|
||||
public class ValueHolder<T> {
|
||||
public T value;
|
||||
public ValueHolder(){}
|
||||
public ValueHolder(T v){value = v;}
|
||||
}
|
69
ext/jni/src/org/sqlite/jni/fts5_api.java
Normal file
69
ext/jni/src/org/sqlite/jni/fts5_api.java
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
** 2023-08-05
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This file is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
INCOMPLETE AND COMPLETELY UNTESTED.
|
||||
|
||||
A wrapper for communicating C-level (fts5_api*) instances with
|
||||
Java. These wrappers do not own their associated pointer, they
|
||||
simply provide a type-safe way to communicate it between Java and C
|
||||
via JNI.
|
||||
*/
|
||||
public final class fts5_api extends NativePointerHolder<fts5_api> {
|
||||
/* Only invoked from JNI */
|
||||
private fts5_api(){}
|
||||
public final int iVersion = 2;
|
||||
|
||||
/**
|
||||
Returns the fts5_api instance associated with the given db, or
|
||||
null if something goes horribly wrong.
|
||||
*/
|
||||
public static synchronized native fts5_api getInstanceForDb(@NotNull sqlite3 db);
|
||||
|
||||
// int (*xCreateTokenizer)(
|
||||
// fts5_api *pApi,
|
||||
// const char *zName,
|
||||
// void *pContext,
|
||||
// fts5_tokenizer *pTokenizer,
|
||||
// void (*xDestroy)(void*)
|
||||
// );
|
||||
|
||||
// /* Find an existing tokenizer */
|
||||
// int (*xFindTokenizer)(
|
||||
// fts5_api *pApi,
|
||||
// const char *zName,
|
||||
// void **ppContext,
|
||||
// fts5_tokenizer *pTokenizer
|
||||
// );
|
||||
|
||||
// /* Create a new auxiliary function */
|
||||
// int (*xCreateFunction)(
|
||||
// fts5_api *pApi,
|
||||
// const char *zName,
|
||||
// void *pContext,
|
||||
// fts5_extension_function xFunction,
|
||||
// void (*xDestroy)(void*)
|
||||
// );
|
||||
|
||||
public synchronized native int xCreateFunction(@NotNull String name,
|
||||
@Nullable Object userData,
|
||||
@NotNull fts5_extension_function xFunction);
|
||||
|
||||
public int xCreateFunction(@NotNull String name,
|
||||
@NotNull fts5_extension_function xFunction){
|
||||
return xCreateFunction(name, null, xFunction);
|
||||
}
|
||||
|
||||
}
|
37
ext/jni/src/org/sqlite/jni/fts5_extension_function.java
Normal file
37
ext/jni/src/org/sqlite/jni/fts5_extension_function.java
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
** 2023-08-05
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This file is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
JNI-level wrapper for C's fts5_extension_function type.
|
||||
|
||||
*/
|
||||
public abstract class fts5_extension_function {
|
||||
// typedef void (*fts5_extension_function)(
|
||||
// const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
|
||||
// Fts5Context *pFts, /* First arg to pass to pApi functions */
|
||||
// sqlite3_context *pCtx, /* Context for returning result/error */
|
||||
// int nVal, /* Number of values in apVal[] array */
|
||||
// sqlite3_value **apVal /* Array of trailing arguments */
|
||||
// );
|
||||
|
||||
/**
|
||||
The callback implementation, corresponding to the xFunction
|
||||
argument of C's fts5_api::xCreateFunction().
|
||||
*/
|
||||
public abstract void xFunction(Fts5ExtensionApi ext, Fts5Context fCx,
|
||||
sqlite3_context pCx, sqlite3_value argv[]);
|
||||
//! Optionally override
|
||||
public void xDestroy(){}
|
||||
}
|
49
ext/jni/src/org/sqlite/jni/fts5_tokenizer.java
Normal file
49
ext/jni/src/org/sqlite/jni/fts5_tokenizer.java
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
** 2023-08-05
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This file is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
INCOMPLETE AND COMPLETELY UNTESTED.
|
||||
|
||||
A wrapper for communicating C-level (fts5_tokenizer*) instances with
|
||||
Java. These wrappers do not own their associated pointer, they
|
||||
simply provide a type-safe way to communicate it between Java and C
|
||||
via JNI.
|
||||
*/
|
||||
public final class fts5_tokenizer extends NativePointerHolder<fts5_tokenizer> {
|
||||
/* Only invoked by JNI */
|
||||
private fts5_tokenizer(){}
|
||||
|
||||
// int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
|
||||
// void (*xDelete)(Fts5Tokenizer*);
|
||||
|
||||
public native int xTokenize(@NotNull Fts5Tokenizer t, int tokFlags,
|
||||
@NotNull byte pText[],
|
||||
@NotNull Fts5.xTokenizeCallback callback);
|
||||
|
||||
|
||||
// int (*xTokenize)(Fts5Tokenizer*,
|
||||
// void *pCtx,
|
||||
// int flags, /* Mask of FTS5_TOKENIZE_* flags */
|
||||
// const char *pText, int nText,
|
||||
// int (*xToken)(
|
||||
// void *pCtx, /* Copy of 2nd argument to xTokenize() */
|
||||
// int tflags, /* Mask of FTS5_TOKEN_* flags */
|
||||
// const char *pToken, /* Pointer to buffer containing token */
|
||||
// int nToken, /* Size of token in bytes */
|
||||
// int iStart, /* Byte offset of token within input text */
|
||||
// int iEnd /* Byte offset of end of token within input text */
|
||||
// )
|
||||
// );
|
||||
}
|
37
ext/jni/src/org/sqlite/jni/sqlite3.java
Normal file
37
ext/jni/src/org/sqlite/jni/sqlite3.java
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
** 2023-07-21
|
||||
**
|
||||
** 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 is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
A wrapper for communicating C-level (sqlite3*) instances with
|
||||
Java. These wrappers do not own their associated pointer, they
|
||||
simply provide a type-safe way to communicate it between Java
|
||||
and C via JNI.
|
||||
*/
|
||||
public final class sqlite3 extends NativePointerHolder<sqlite3> {
|
||||
// Only invoked from JNI
|
||||
private sqlite3(){}
|
||||
|
||||
public String toString(){
|
||||
long ptr = getNativePointer();
|
||||
if( 0==ptr ){
|
||||
return sqlite3.class.getSimpleName()+"@null";
|
||||
}
|
||||
String fn = SQLite3Jni.sqlite3_db_filename(this, "main");
|
||||
return sqlite3.class.getSimpleName()
|
||||
+"@"+String.format("0x%08x",ptr)
|
||||
+"["+((null == fn) ? "<unnamed>" : fn)+"]"
|
||||
;
|
||||
}
|
||||
}
|
66
ext/jni/src/org/sqlite/jni/sqlite3_context.java
Normal file
66
ext/jni/src/org/sqlite/jni/sqlite3_context.java
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
** 2023-07-21
|
||||
**
|
||||
** 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 is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
sqlite3_context instances are used in conjunction with user-defined
|
||||
SQL functions (a.k.a. UDFs).
|
||||
*/
|
||||
public final class sqlite3_context extends NativePointerHolder<sqlite3_context> {
|
||||
/**
|
||||
For use only by the JNI layer. It's permitted to set this even
|
||||
though it's private.
|
||||
*/
|
||||
private long aggregateContext = 0;
|
||||
|
||||
/**
|
||||
getAggregateContext() corresponds to C's
|
||||
sqlite3_aggregate_context(), with a slightly different interface
|
||||
to account for cross-language differences. It serves the same
|
||||
purposes in a slightly different way: it provides a key which is
|
||||
stable across invocations of "matching sets" of a UDF's callbacks,
|
||||
such that all calls into those callbacks can determine which "set"
|
||||
of those calls they belong to.
|
||||
|
||||
If this object is being used in the context of an aggregate or
|
||||
window UDF, this function returns a non-0 value which is distinct
|
||||
for each set of UDF callbacks from a single invocation of the
|
||||
UDF, otherwise it returns 0. The returned value is only only
|
||||
valid within the context of execution of a single SQL statement,
|
||||
and may be re-used by future invocations of the UDF in different
|
||||
SQL statements.
|
||||
|
||||
Consider this SQL, where MYFUNC is a user-defined aggregate function:
|
||||
|
||||
SELECT MYFUNC(A), MYFUNC(B) FROM T;
|
||||
|
||||
The xStep() and xFinal() methods of the callback need to be able
|
||||
to differentiate between those two invocations in order to
|
||||
perform their work properly. The value returned by
|
||||
getAggregateContext() will be distinct for each of those
|
||||
invocations of MYFUNC() and is intended to be used as a lookup
|
||||
key for mapping callback invocations to whatever client-defined
|
||||
state is needed by the UDF.
|
||||
|
||||
There is one case where this will return 0 in the context of an
|
||||
aggregate or window function: if the result set has no rows,
|
||||
the UDF's xFinal() will be called without any other x...() members
|
||||
having been called. In that one case, no aggregate context key will
|
||||
have been generated. xFinal() implementations need to be prepared to
|
||||
accept that condition as legal.
|
||||
*/
|
||||
public long getAggregateContext(){
|
||||
return aggregateContext;
|
||||
}
|
||||
}
|
25
ext/jni/src/org/sqlite/jni/sqlite3_stmt.java
Normal file
25
ext/jni/src/org/sqlite/jni/sqlite3_stmt.java
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
** 2023-07-21
|
||||
**
|
||||
** 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 is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
/**
|
||||
A wrapper for communicating C-level (sqlite3_stmt*) instances with
|
||||
Java. These wrappers do not own their associated pointer, they
|
||||
simply provide a type-safe way to communicate it between Java and C
|
||||
via JNI.
|
||||
*/
|
||||
public final class sqlite3_stmt extends NativePointerHolder<sqlite3_stmt> {
|
||||
// Only invoked from JNI.
|
||||
private sqlite3_stmt(){}
|
||||
}
|
19
ext/jni/src/org/sqlite/jni/sqlite3_value.java
Normal file
19
ext/jni/src/org/sqlite/jni/sqlite3_value.java
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
** 2023-07-21
|
||||
**
|
||||
** 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 is part of the JNI bindings for the sqlite3 C API.
|
||||
*/
|
||||
package org.sqlite.jni;
|
||||
|
||||
public final class sqlite3_value extends NativePointerHolder<sqlite3_value> {
|
||||
//! Invoked only from JNI.
|
||||
private sqlite3_value(){}
|
||||
}
|
1421
ext/jni/src/org/sqlite/jni/tester/SQLTester.java
Normal file
1421
ext/jni/src/org/sqlite/jni/tester/SQLTester.java
Normal file
File diff suppressed because it is too large
Load Diff
269
ext/jni/src/org/sqlite/jni/tester/test-script-interpreter.md
Normal file
269
ext/jni/src/org/sqlite/jni/tester/test-script-interpreter.md
Normal file
@@ -0,0 +1,269 @@
|
||||
# Specifications For A Rudimentary SQLite Test Script Interpreter
|
||||
|
||||
## Overview
|
||||
|
||||
The purpose of the Test Script Interpreter is to read and interpret
|
||||
script files that contain SQL commands and desired results. The
|
||||
interpreter will check results and report an discrepencies found.
|
||||
|
||||
The test script files are ASCII text files. The filename always ends with
|
||||
".test". Each script is evaluated independently; context does not carry
|
||||
forward from one script to the next. So, for example, the --null command
|
||||
run in one test script does not cause any changes in the behavior of
|
||||
subsequent test scripts. All open database connections are closed
|
||||
at the end of each test script. All database files created by a test
|
||||
script are deleted when the script finishes.
|
||||
|
||||
## Parsing Rules:
|
||||
|
||||
1. The test script is read line by line, where a line is a sequence of
|
||||
characters that runs up to the next '\\n' (0x0a) character or until
|
||||
the end of the file. There is never a need to read ahead past the
|
||||
end of the current line.
|
||||
|
||||
2. If any line contains the string " MODULE_NAME:" (with a space before
|
||||
the initial "M") or "MIXED_MODULE_NAME:" then that test script is
|
||||
incompatible with this spec. Processing of the test script should
|
||||
end immediately. There is no need to read any more of the file.
|
||||
In verbose mode, the interpreter might choose to emit an informational
|
||||
messages saying that the test script was abandoned due to an
|
||||
incompatible module type.
|
||||
|
||||
3. If any line contains the string "SCRIPT_MODULE_NAME:" then the input
|
||||
script is known to be of the correct type for this specification and
|
||||
processing may continue. The "MODULE_NAME" checking in steps 2 and 3
|
||||
may optionally be discontinued after sighting a "SCRIPT_MODULE_NAME".
|
||||
|
||||
4. If any line contains "REQUIRED_PROPERTIES:" and that substring is followed
|
||||
by any non-whitespace text, then the script is not compatible with this
|
||||
spec. Processing should stop immediately. In verbose mode, the
|
||||
interpreter might choose to emit an information message saying that the
|
||||
test script was abandoned due to unsupported requirement properties.
|
||||
|
||||
5. If any line begins with the "\|" (0x7c) character, that indicates that
|
||||
the input script is not compatible with this specification. Processing
|
||||
of the script should stop immediately. In verbose mode, the interpreter
|
||||
might choose to emit an informational message indicating that the
|
||||
test script was abandoned because it contained "a dbtotxt format database
|
||||
specification".
|
||||
|
||||
6. Any line that begins with "#" is a C-preprocessor line. The interpreter
|
||||
described by this spec does not know how to deal with C-preprocessor lines.
|
||||
Hence, processing should be abandoned. In verbose mode, the interpreter
|
||||
might emit an informational message similar to
|
||||
"script NAME abandoned due to C-preprocessor line: ..."
|
||||
|
||||
7. If a line begins with exactly two minus signs followed by a
|
||||
lowercase letter, that is a command. Process commands as described
|
||||
below.
|
||||
|
||||
8. All other lines should be accumulated into the "input buffer".
|
||||
The various commands will have access to this input buffer.
|
||||
Some commands will reset the buffer.
|
||||
|
||||
## Initialization
|
||||
|
||||
The initial state of the interpreter at the start of processing each script
|
||||
is as if the following command sequence had been run:
|
||||
|
||||
> ~~~
|
||||
--close all
|
||||
--db 0
|
||||
--new test.db
|
||||
--null nil
|
||||
~~~
|
||||
|
||||
In words, all database connections are closed except for connection 0 (the
|
||||
default) which is open on an empty database named "test.db". The string
|
||||
"nil" is displayed for NULL column values.
|
||||
|
||||
The only context carried forward after the evaluation of one test script
|
||||
into the evaluation of the next test script is the count of the number of
|
||||
tests run and the number of failures seen.
|
||||
|
||||
## Commands:
|
||||
|
||||
Each command looks like an SQL comment. The command begins at the left
|
||||
margin (no leading space) and starts with exactly 2 minus signs ("-").
|
||||
The command name consists of lowercase letters and maybe a "-" or two.
|
||||
Some commands have arguments.
|
||||
The arguments are separated from the command name by one or more spaces.
|
||||
|
||||
Commands have access to the input buffer and might reset the input buffer.
|
||||
The command can also optionally read (and consume) additional text from
|
||||
script that comes after the command.
|
||||
|
||||
Unknown or unrecognized commands indicate that the script contains features
|
||||
that are not (yet) supported by this specification. Processing of the
|
||||
script should terminate immediately. When this happens and when the
|
||||
interpreter is in a "verbose" mode, the interpreter might choose to emit
|
||||
an informational message along the lines of "test script NAME abandoned
|
||||
due to unsupported command: --whatever".
|
||||
|
||||
The initial implemention will only recognize a few commands. Other
|
||||
commands may be added later. The following is the initial set of
|
||||
commands:
|
||||
|
||||
### The --testcase command
|
||||
|
||||
Every test case starts with a --testcase command. The --testcase
|
||||
command resets both the "input buffer" and the "result buffer". The
|
||||
argument to the --testcase command is the name of the test case. That
|
||||
test case name is used for logging and debugging and when printing
|
||||
errors. The input buffer is set to the body of the test case.
|
||||
|
||||
### The --result command
|
||||
|
||||
The --result command tries to execute the text in the input buffer as SQL.
|
||||
For each row of result coming out of this SQL, the text of that result is
|
||||
appended to the "result buffer". If a result row contains multiple columns,
|
||||
the columns are processed from left to right. For each column, text is
|
||||
appended to the result buffer according to the following rules:
|
||||
|
||||
* If the result buffer already contains some text, append a space.
|
||||
(In this way, all column values and all row values are separated from
|
||||
each other by a single space.)
|
||||
|
||||
* If sqlite3_column_text() returns NULL, then append "nil" - or
|
||||
some other text that is specified by the --null command - and skip
|
||||
all subsequent rules.
|
||||
|
||||
* If sqlite3_column_text() is an empty string, append `{}` to the
|
||||
result buffer and skip all subsequent rules.
|
||||
|
||||
* If sqlite3_column_text() does not contain any special
|
||||
characters, append it to the result buffer without any
|
||||
formatting and skip all subsequent rules. Special characters are:
|
||||
0x00 to 0x20 (inclusive), double-quote (0x22), backslash (0x5c),
|
||||
curly braces (0x7b and 0x7d).
|
||||
|
||||
* If sqlite3_column_text() does not contains curly braces, then put
|
||||
the text inside of `{...}` and append it and skip all subsequent rules.
|
||||
|
||||
* Append the text within double-quotes (`"..."`) and within the text
|
||||
escape '"' and '\\' by prepending a single '\\' and escape any
|
||||
control characters (characters less than 0x20) using octal notation:
|
||||
'\\NNN'.
|
||||
|
||||
If an error is encountered while running the SQL, then append the
|
||||
symbolic C-preprocessor name for the error
|
||||
code (ex: "SQLITE_CONSTRAINT") as if it were a column value. Then append
|
||||
the error message text as if it where a column value. Then stop processing.
|
||||
|
||||
After the SQL text has been run, compare the content of the result buffer
|
||||
against the argument to the --result command and report a testing error if
|
||||
there are any differences.
|
||||
|
||||
The --result command resets the input buffer, but it does not reset
|
||||
the result buffer. This distinction does not matter for the --result
|
||||
command itself, but it is important for related commands like --glob
|
||||
and --notglob. Sometimes test cases will contains a bunch of SQL
|
||||
followed by multiple --glob and/or --notglob statements. All of the
|
||||
globs should be evaluted agains the result buffer correct, but the SQL
|
||||
should only be run once. This is accomplished by resetting the input
|
||||
buffer but not the result buffer.
|
||||
|
||||
### The --glob command
|
||||
|
||||
The --glob command works just like --result except that the argument to
|
||||
--glob is interpreted as a TEST-GLOB pattern and the results are compared
|
||||
using that glob pattern rather than using strcmp(). Other than that,
|
||||
the two operate the same.
|
||||
|
||||
The TEST-GLOB pattern is slightly different for a standard GLOB:
|
||||
|
||||
* The '*' character matches zero or more characters.
|
||||
|
||||
* The '?' character matches any single character
|
||||
|
||||
* The '[...]' character sequence machines a single character
|
||||
in between the brackets.
|
||||
|
||||
* The '#' character matches one or more digits (This is the main
|
||||
difference between standard unix-glob and TEST-GLOB. unix-glob
|
||||
does not have this feature. It was added to because it comes
|
||||
up a lot during SQLite testing.)
|
||||
|
||||
### The --notglob command
|
||||
|
||||
The --notglob command works just like --glob except that it reports an
|
||||
error if the GLOB does match, rather than if the GLOB does not matches.
|
||||
|
||||
### The --oom command
|
||||
|
||||
This command is to be used for out-of-memory testing. It means that
|
||||
OOM errors should be simulated to ensure that SQLite is able to deal with
|
||||
them. This command can be silently ignored for now. We might add support
|
||||
for this later.
|
||||
|
||||
### The --tableresult command
|
||||
|
||||
The --tableresult command works like --glob except that the GLOB pattern
|
||||
to be matched is taken from subsequent lines of the input script up to
|
||||
the next --end. Every span of one or more whitespace characters in this
|
||||
pattern text is collapsed into a single space (0x20).
|
||||
Leading and trailing whitespace are removed from the pattern.
|
||||
The --end that ends the GLOB pattern is not part of the GLOB pattern, but
|
||||
the --end is consumed from the script input.
|
||||
|
||||
### The --new and --open commands
|
||||
|
||||
The --new and --open commands cause a database file to be opened.
|
||||
The name of the file is the argument to the command. The --new command
|
||||
opens an initially empty database (it deletes the file before opening it)
|
||||
whereas the --open command opens an existing database if it already
|
||||
exists.
|
||||
|
||||
### The --db command
|
||||
|
||||
The script interpreter can have up to 7 different SQLite database
|
||||
connections open at a time. The --db command is used to switch between
|
||||
them. The argument to --db is an integer between 0 and 6 that selects
|
||||
which database connection to use moving forward.
|
||||
|
||||
### The --close command
|
||||
|
||||
The --close command causes an existing database connection to close.
|
||||
This command is a no-op if the database connection is not currently
|
||||
open. There can be up to 7 different database connections, numbered 0
|
||||
through 6. The number of the database connection to close is an
|
||||
argument to the --close command, which will fail if an out-of-range
|
||||
value is provided. Or if the argument to --close is "all" then all
|
||||
open database connections are closed. If passed no argument, the
|
||||
currently-active database is assumed.
|
||||
|
||||
### The --null command
|
||||
|
||||
The NULL command changes the text that is used to represent SQL NULL
|
||||
values in the result buffer.
|
||||
|
||||
### The --run command
|
||||
|
||||
The --run command executes text in the input buffer as if it where SQL.
|
||||
However, nothing is added to the result buffer. Any output from the SQL
|
||||
is silently ignored. Errors in the SQL are silently ignored.
|
||||
|
||||
The --run command normally executes the SQL in the current database
|
||||
connection. However, if --run has an argument that is an integer between
|
||||
0 and 6 then the SQL is run in the alternative database connection specified
|
||||
by that argument.
|
||||
|
||||
### The --json and --json-block commands
|
||||
|
||||
The --json and --json-block commands work like --result and --tableresult,
|
||||
respectively. The difference is that column values are appended to the
|
||||
result buffer literally, without ever enclosing the values in `{...}` or
|
||||
`"..."` and without escaping any characters in the column value and comparison
|
||||
is always an exact strcmp() not a GLOB.
|
||||
|
||||
### The --print command
|
||||
|
||||
The --print command emits both its arguments and its body (if any) to
|
||||
stdout, indenting each line of output.
|
||||
|
||||
### The --column-names command
|
||||
|
||||
The --column-names command requires 0 or 1 as an argument, to disable
|
||||
resp. enable it, and modifies SQL execution to include column names
|
||||
in output. When this option is on, each column value emitted gets
|
||||
prefixed by its column name, with a single space between them.
|
52
ext/jni/src/tests/000-000-sanity.test
Normal file
52
ext/jni/src/tests/000-000-sanity.test
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
** This is a comment. There are many like it but this one is mine.
|
||||
**
|
||||
** SCRIPT_MODULE_NAME: sanity-check
|
||||
** xMIXED_MODULE_NAME: mixed-module
|
||||
** xMODULE_NAME: module-name
|
||||
** xREQUIRED_PROPERTIES: small fast reliable
|
||||
** xREQUIRED_PROPERTIES: RECURSIVE_TRIGGERS
|
||||
** xREQUIRED_PROPERTIES: TEMPSTORE_MEM TEMPSTORE_FILE
|
||||
**
|
||||
*/
|
||||
--print starting up 😃
|
||||
--close all
|
||||
--oom
|
||||
--db 0
|
||||
--new my.db
|
||||
--null zilch
|
||||
--testcase 1.0
|
||||
SELECT 1, null;
|
||||
--result 1 zilch
|
||||
--glob *zil*
|
||||
--notglob *ZIL*
|
||||
SELECT 1, 2;
|
||||
intentional error;
|
||||
--run
|
||||
--testcase json-1
|
||||
SELECT json_array(1,2,3)
|
||||
--json [1,2,3]
|
||||
--testcase tableresult-1
|
||||
select 1, 'a';
|
||||
select 2, 'b';
|
||||
--tableresult
|
||||
# [a-z]
|
||||
2 b
|
||||
--end
|
||||
--testcase json-block-1
|
||||
select json_array(1,2,3);
|
||||
select json_object('a',1,'b',2);
|
||||
--json-block
|
||||
[1,2,3]
|
||||
{"a":1,"b":2}
|
||||
--end
|
||||
--testcase col-names-on
|
||||
--column-names 1
|
||||
select 1 as 'a', 2 as 'b';
|
||||
--result a 1 b 2
|
||||
--testcase col-names-off
|
||||
--column-names 0
|
||||
select 1 as 'a', 2 as 'b';
|
||||
--result 1 2
|
||||
--close
|
||||
--print reached the end 😃
|
9
ext/jni/src/tests/000-001-ignored.test
Normal file
9
ext/jni/src/tests/000-001-ignored.test
Normal file
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
** This script must be marked as ignored because it contains
|
||||
** content which triggers that condition.
|
||||
**
|
||||
** SCRIPT_MODULE_NAME: ignored
|
||||
**
|
||||
*/
|
||||
|
||||
|
|
@@ -642,7 +642,7 @@ static Decimal *decimalFromDouble(double r){
|
||||
|
||||
/*
|
||||
** SQL Function: decimal(X)
|
||||
** OR: decimal_sci(X)
|
||||
** OR: decimal_exp(X)
|
||||
**
|
||||
** Convert input X into decimal and then back into text.
|
||||
**
|
||||
@@ -650,7 +650,7 @@ static Decimal *decimalFromDouble(double r){
|
||||
** point value is done. Or if X is an 8-byte blob, it is interpreted
|
||||
** as a float and similarly expanded.
|
||||
**
|
||||
** The decimal_sci(X) function returns the result in scientific notation.
|
||||
** The decimal_exp(X) function returns the result in exponential notation.
|
||||
** decimal(X) returns a complete decimal, without the e+NNN at the end.
|
||||
*/
|
||||
static void decimalFunc(
|
||||
@@ -853,7 +853,7 @@ int sqlite3_decimal_init(
|
||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
|
||||
} aFunc[] = {
|
||||
{ "decimal", 1, 0, decimalFunc },
|
||||
{ "decimal_sci", 1, 1, decimalFunc },
|
||||
{ "decimal_exp", 1, 1, decimalFunc },
|
||||
{ "decimal_cmp", 2, 0, decimalCmpFunc },
|
||||
{ "decimal_add", 2, 0, decimalAddFunc },
|
||||
{ "decimal_sub", 2, 0, decimalSubFunc },
|
||||
|
@@ -1919,7 +1919,7 @@ static int rtreeFilter(
|
||||
#else
|
||||
p->u.rValue = (double)iVal;
|
||||
if( iVal>=((sqlite3_int64)1)<<48
|
||||
|| -iVal>=((sqlite3_int64)1)<<48
|
||||
|| iVal<=-(((sqlite3_int64)1)<<48)
|
||||
){
|
||||
if( p->op==RTREE_LT ) p->op = RTREE_LE;
|
||||
if( p->op==RTREE_GT ) p->op = RTREE_GE;
|
||||
|
@@ -1046,8 +1046,7 @@ endif
|
||||
# Push files to public wasm-testing.sqlite.org server
|
||||
wasm-testing.include = *.js *.mjs *.html \
|
||||
./tests \
|
||||
batch-runner.list \
|
||||
$(dir.dout) $(dir.sql) $(dir.common) $(dir.fiddle) $(dir.jacc)
|
||||
$(dir.dout) $(dir.common) $(dir.fiddle) $(dir.jacc)
|
||||
wasm-testing.exclude = sql/speedtest1.sql
|
||||
wasm-testing.dir = /jail/sites/wasm-testing
|
||||
wasm-testing.dest ?= wasm-testing:$(wasm-testing.dir)
|
||||
|
3
main.mk
3
main.mk
@@ -942,6 +942,9 @@ testrunner: testfixture$(EXE)
|
||||
#
|
||||
devtest: testfixture$(EXE) fuzztest testrunner
|
||||
|
||||
mdevtest:
|
||||
tclsh $(TOP)/test/testrunner.tcl mdevtest
|
||||
|
||||
# A very quick test using only testfixture and omitting all the slower
|
||||
# tests. Designed to run in under 3 minutes on a workstation.
|
||||
#
|
||||
|
131
manifest
131
manifest
@@ -1,21 +1,21 @@
|
||||
C Fix\sproblems\srelated\sto\sstructured-exception-handling\son\sthis\sbranch.
|
||||
D 2023-08-21T18:25:41.874
|
||||
C Merge\slatest\schanges\sfrom\sthe\swal2\sbranch\sinto\sthis\sone.
|
||||
D 2023-08-21T18:31:53.800
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
F Makefile.in 1ac6badc8e625d87c76f64fad033ece76721c6d9341c685baeb17aea5f620acd
|
||||
F Makefile.in 0a5501ba18ddbe0ef10c02bfc12931b55148a216f2b14af79b2b76d715c4c65b
|
||||
F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6
|
||||
F Makefile.msc 0b57ab2867b1fdc90c4e35a6777a3b24b81006cc7ba947c8db13929b4edd3800
|
||||
F README.md c1c4218efcc4071a6e26db2b517fdbc1035696a29b370edd655faddbef02b224
|
||||
F Makefile.msc 01eac287493d2ea7b0ced738dcf19a2234c60195d39e1c86f2b0fa20c9d7d14e
|
||||
F README.md 093d7054271141a0a8518558e3d49087cb71f84d33b50ee10053946ed85dcac8
|
||||
F VERSION c6366dc72582d3144ce87b013cc35fe48d62f6d07d5be0c9716ea33c862144aa
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
|
||||
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
|
||||
F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
|
||||
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
|
||||
F autoconf/Makefile.am a8d1d24affe52ebf8d7ddcf91aa973fa0316618ab95bb68c87cabf8faf527dc8
|
||||
F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347
|
||||
F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac
|
||||
F autoconf/Makefile.msc 00f11ce1f7904416fe841c33e7d789defe8c39e1df6b97e93ed2af3b1bbaf9d7
|
||||
F autoconf/Makefile.msc 012cdd820963653a7db147a185ebe9085756b6ab15ac964e8cc1dae4c29485cd
|
||||
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
|
||||
F autoconf/README.txt 42cfd21d0b19dc7d5d85fb5c405c5f3c6a4c923021c39128f6ba685355d8fd56
|
||||
F autoconf/configure.ac ec7fa914c5e74ff212fe879f9bb6918e1234497e05facfb641f30c4d5893b277
|
||||
@@ -38,6 +38,7 @@ F configure.ac 4654d32ac0a0d0b48f1e1e79bdc3d777b723cf2f63c33eb1d7c4ed8b435938e8
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
|
||||
F doc/begin_concurrent.md 4bee2c3990d1eb800f1ce3726a911292a8e4b889300b2ffd4b08d357370db299
|
||||
F doc/compile-for-windows.md e9d49959f44114a35dbec66f6aa5c3688ea9cb1b3f969a8537cd80b86d8969f7
|
||||
F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347bb123ce1ea4f
|
||||
F doc/lemon.html d2862dbef72496e87f7996f37e814b146848190a742c12161d13fd15346051b0
|
||||
F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710
|
||||
@@ -87,14 +88,14 @@ F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7
|
||||
F ext/fts3/unicode/mkunicode.tcl d5aebf022fa4577ee8cdf27468f0d847879993959101f6dbd6348ef0cfc324a7
|
||||
F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb
|
||||
F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
|
||||
F ext/fts5/fts5.h 9bebc9fb8b75b0777e741c758540e07c3c80ce75204198979028fe6cc4c59486
|
||||
F ext/fts5/fts5.h 05501612cc655504c5dce8ba765ab621d50fc478490089beaa0d75e00b23e520
|
||||
F ext/fts5/fts5Int.h 78a63cc0795186cde5384816a9403a68c65774b35d952e05b81a1b4b158e07c8
|
||||
F ext/fts5/fts5_aux.c 572d5ec92ba7301df2fea3258576332f2f4d2dfd66d8263afd157d9deceac480
|
||||
F ext/fts5/fts5_buffer.c 3001fbabb585d6de52947b44b455235072b741038391f830d6b729225eeaf6a5
|
||||
F ext/fts5/fts5_config.c 054359543566cbff1ba65a188330660a5457299513ac71c53b3a07d934c7b081
|
||||
F ext/fts5/fts5_expr.c 2473c13542f463cae4b938c498d6193c90d38ea1a2a4f9849c0479736e50d24d
|
||||
F ext/fts5/fts5_expr.c bd3b81ce669c4104e34ffe66570af1999a317b142c15fccb112de9fb0caa57a6
|
||||
F ext/fts5/fts5_hash.c 65e7707bc8774706574346d18c20218facf87de3599b995963c3e6d6809f203d
|
||||
F ext/fts5/fts5_index.c 93b4cd116b76b6adf224cd3d213f1e06cfe10ae0eb21d6372b1c53b8f0c382a3
|
||||
F ext/fts5/fts5_index.c 7990b39f68010d6ee0d89a92784900a5fe582b90ca02fedc8a5d4b6b589498b8
|
||||
F ext/fts5/fts5_main.c 4df36d3e7e641dd8af1244fdd9b1639d80844d4559531580586edb802691c353
|
||||
F ext/fts5/fts5_storage.c 3c9b41fce41b6410f2e8f82eb035c6a29b2560483f773e6dc98cf3cb2e4ddbb5
|
||||
F ext/fts5/fts5_tcl.c b1445cbe69908c411df8084a10b2485500ac70a9c747cdc8cda175a3da59d8ae
|
||||
@@ -153,7 +154,7 @@ F ext/fts5/test/fts5determin.test 1b77879b2ae818b5b71c859e534ee334dac088b7cf3ff3
|
||||
F ext/fts5/test/fts5dlidx.test b90852c55881b29dbac6380b274de27beae623ac4b6d567c6c8fb9cdc315a86e
|
||||
F ext/fts5/test/fts5doclist.test faa9e9cc3c0645fa6203667cb5f007c359447c6ee66753f71a58175c2497cacd
|
||||
F ext/fts5/test/fts5ea.test b01e3a18cdfabbff8104a96a5242a06a68a998a0
|
||||
F ext/fts5/test/fts5eb.test a973baadac524dbbb4ad9b0e99030e12cabde2c6b28e0ac437298007b642cd12
|
||||
F ext/fts5/test/fts5eb.test 5f0a86e9fe4715912e6bfa556368aae96d13c61a481373f24daa40429d5d5ca1
|
||||
F ext/fts5/test/fts5fault1.test d28a65caee75db6897c3cf1358c5230d3bb2a3bf7fb31062c19c7e5382b3d2bd
|
||||
F ext/fts5/test/fts5fault2.test 69c8fdbef830cd0d450908d4504d5bb86609e255af99c421c20a0756251fe344
|
||||
F ext/fts5/test/fts5fault3.test da2f9e3e56ff5740d68ebdd6877c97089e7ed28ddff28a0da87a6afea27e5522
|
||||
@@ -204,13 +205,13 @@ F ext/fts5/test/fts5secure2.test 2e961d7eef939f294c56b5d895cac7f1c3a60b934ee2cfd
|
||||
F ext/fts5/test/fts5secure3.test 12bc9ffa5dbd5a0951c6fe73bbf53b1c6507217589d7c8f5d4637a4fbb534401
|
||||
F ext/fts5/test/fts5secure4.test 0d10a80590c07891478700af7793b232962042677432b9846cf7fc8337b67c97
|
||||
F ext/fts5/test/fts5secure5.test c07a68ced5951567ac116c22f2d2aafae497e47fe9fcb6a335c22f9c7a4f2c3a
|
||||
F ext/fts5/test/fts5secure6.test 7a959d834be6725c641b3c3b38ef86570ea671216ad803e054e4fdff33a72ce2
|
||||
F ext/fts5/test/fts5secure6.test a0a28cfb9bf9721408b65b5d7c7ce369af3d688e273da24d101c25d60cdce05c
|
||||
F ext/fts5/test/fts5securefault.test dbca2b6a1c16700017f5051138991b705410889933f2a37c57ae8a23b296b10b
|
||||
F ext/fts5/test/fts5simple.test a298670508c1458b88ce6030440f26a30673931884eb5f4094ac1773b3ba217b
|
||||
F ext/fts5/test/fts5simple2.test 258a1b0c590409bfa5271e872c79572b319d2a56554d0585f68f146a0da603f0
|
||||
F ext/fts5/test/fts5simple3.test d5c74a9d3ca71bd5dd5cacb7c55b86ea12cdddfc8b1910e3de2995206898380f
|
||||
F ext/fts5/test/fts5synonym.test 1651815b8008de170e8e600dcacc17521d765482ea8f074ae82cfa870d8bb7fb
|
||||
F ext/fts5/test/fts5synonym2.test b54cce5c34ec08ed616f646635538ae82e34a0e28f947ec60b6fadbc4b3fb17a
|
||||
F ext/fts5/test/fts5synonym2.test 8f891fc49cc1e8daed727051e77e1f42849c784a6a54bef82564761b2cb3e016
|
||||
F ext/fts5/test/fts5tok1.test 1f7817499f5971450d8c4a652114b3d833393c8134e32422d0af27884ffe9cef
|
||||
F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2
|
||||
F ext/fts5/test/fts5tokenizer.test ac3c9112b263a639fb0508ae73a3ee886bf4866d2153771a8e8a20c721305a43
|
||||
@@ -234,6 +235,46 @@ F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c
|
||||
F ext/icu/README.txt 7ab7ced8ae78e3a645b57e78570ff589d4c672b71370f5aa9e1cd7024f400fc9
|
||||
F ext/icu/icu.c c074519b46baa484bb5396c7e01e051034da8884bad1a1cb7f09bbe6be3f0282
|
||||
F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a32075a8
|
||||
F ext/jni/GNUmakefile 3deba6bc0bf37c1ee5f15d1ff3c3512ae2f3cf44a2b8ae7b4af92690514b0cb4
|
||||
F ext/jni/README.md 5c60e4580aa5c94ff74d7bef1fb6231e578f7764e831a07b5981b6ab62b35560
|
||||
F ext/jni/jar-dist.make 93da95f8fe01ef22fccacc27f2e805938058e91e8c72c0532558d3a812a42e74
|
||||
F ext/jni/src/c/sqlite3-jni.c bea6b8691a5fa3a8626a771757bb261208d3c5fc6598266d3b0ee23d88e35632
|
||||
F ext/jni/src/c/sqlite3-jni.h 28565de9efc971195c684095ba0d184b90401290698c987f7ea3f54e47ff4f2f
|
||||
F ext/jni/src/org/sqlite/jni/Authorizer.java 1308988f7f40579ea0e4deeaec3c6be971630566bd021c31367fe3f5140db892
|
||||
F ext/jni/src/org/sqlite/jni/AutoExtension.java 18e83f6f463e306df60b2dceb65247d32af1f78af4bbbae9155411a8c6cdb093
|
||||
F ext/jni/src/org/sqlite/jni/BusyHandler.java 1b1d3e5c86cd796a0580c81b6af6550ad943baa25e47ada0dcca3aff3ebe978c
|
||||
F ext/jni/src/org/sqlite/jni/Collation.java 8dffbb00938007ad0967b2ab424d3c908413af1bbd3d212b9c9899910f1218d1
|
||||
F ext/jni/src/org/sqlite/jni/CollationNeeded.java ad67843b6dd1c06b6b0a1dc72887b7c48e2a98042fcf6cacf14d42444037eab8
|
||||
F ext/jni/src/org/sqlite/jni/CommitHook.java 87c6a8e5138c61a8eeff018fe16d23f29219150239746032687f245938baca1a
|
||||
F ext/jni/src/org/sqlite/jni/Fts5.java 13844685231e8b4840a706db3bed84d5dfcf15be0ae7e809eac40420dba24901
|
||||
F ext/jni/src/org/sqlite/jni/Fts5Context.java 0a5a02047a6a1dd3e4a38b0e542a8dd2de365033ba30e6ae019a676305959890
|
||||
F ext/jni/src/org/sqlite/jni/Fts5ExtensionApi.java 01f890105c6b7edbbad1c0f5635f783cea62c4b2ae694a71e76514a936ee03ec
|
||||
F ext/jni/src/org/sqlite/jni/Fts5Function.java 65cde7151e441fee012250a5e03277de7babcd11a0c308a832b7940574259bcc
|
||||
F ext/jni/src/org/sqlite/jni/Fts5PhraseIter.java 6642beda341c0b1b46af4e2d7f6f9ab03a7aede43277b2c92859176d6bce3be9
|
||||
F ext/jni/src/org/sqlite/jni/Fts5Tokenizer.java 91489893596b6528c0df5cd7180bd5b55809c26e2b797fb321dfcdbc1298c060
|
||||
F ext/jni/src/org/sqlite/jni/NativePointerHolder.java 9c5d901cce4f7e57c3d623f4e2476f9f79a8eed6e51b2a603f37866018e040ee
|
||||
F ext/jni/src/org/sqlite/jni/OutputPointer.java d81f8bd43d2296ae373692370cfad16ddde76f5c14cd2760f7b4e1113ef56d4c
|
||||
F ext/jni/src/org/sqlite/jni/ProgressHandler.java 6f62053a828a572de809828b1ee495380677e87daa29a1c57a0e2c06b0a131dc
|
||||
F ext/jni/src/org/sqlite/jni/ResultCode.java ba701f20213a5f259e94cfbfdd36eb7ac7ce7797f2c6c7fca2004ff12ce20f86
|
||||
F ext/jni/src/org/sqlite/jni/RollbackHook.java b04c8abcc6ade44a8a57129e33765793f69df0ba909e49ba18d73f4268d92564
|
||||
F ext/jni/src/org/sqlite/jni/SQLFunction.java 09ce81c1c637e31c3a830d4c859cce95d65f5e02ff45f8bd1985b3479381bc46
|
||||
F ext/jni/src/org/sqlite/jni/SQLite3Jni.java 4b6fd22e04e63eb65d8e4e38fda39ecf15ce244d034607517627ce2e766e7e65
|
||||
F ext/jni/src/org/sqlite/jni/Tester1.java 4253dc7bcff64500a9388f1a17d3d39dbe4eb9d7db9fc035ce6e2380d45ad5fc
|
||||
F ext/jni/src/org/sqlite/jni/TesterFts5.java 59e22dd24af033ea8827d36225a2f3297908fb6af8818ead8850c6c6847557b1
|
||||
F ext/jni/src/org/sqlite/jni/Tracer.java a5cece9f947b0af27669b8baec300b6dd7ff859c3e6a6e4a1bd8b50f9714775d
|
||||
F ext/jni/src/org/sqlite/jni/UpdateHook.java e58645a1727f8a9bbe72dc072ec5b40d9f9362cb0aa24acfe93f49ff56a9016d
|
||||
F ext/jni/src/org/sqlite/jni/ValueHolder.java f022873abaabf64f3dd71ab0d6037c6e71cece3b8819fa10bf26a5461dc973ee
|
||||
F ext/jni/src/org/sqlite/jni/fts5_api.java 5198be71c162e3e0cb1f4962a7cdf0d7596e8af53f70c4af6db24aab8d53d9ba
|
||||
F ext/jni/src/org/sqlite/jni/fts5_extension_function.java ac825035d7d83fc7fd960347abfa6803e1614334a21533302041823ad5fc894c
|
||||
F ext/jni/src/org/sqlite/jni/fts5_tokenizer.java e530b36e6437fcc500e95d5d75fbffe272bdea20d2fac6be2e1336c578fba98b
|
||||
F ext/jni/src/org/sqlite/jni/sqlite3.java 62b1b81935ccf3393472d17cb883dc5ff39c388ec3bc1de547f098a0217158fc
|
||||
F ext/jni/src/org/sqlite/jni/sqlite3_context.java d26573fc7b309228cb49786e9078597d96232257defa955a3425d10897bca810
|
||||
F ext/jni/src/org/sqlite/jni/sqlite3_stmt.java 78e6d1b95ac600a9475e9db4623f69449322b0c93d1bd4e1616e76ed547ed9fc
|
||||
F ext/jni/src/org/sqlite/jni/sqlite3_value.java 3d1d4903e267bc0bc81d57d21f5e85978eff389a1a6ed46726dbe75f85e6914a
|
||||
F ext/jni/src/org/sqlite/jni/tester/SQLTester.java 1f1286428fab38dfefe328e72b5735f533b19af8dd17712dd3df7e044d21c8b8
|
||||
F ext/jni/src/org/sqlite/jni/tester/test-script-interpreter.md f9f25126127045d051e918fe59004a1485311c50a13edbf18c79a6ff9160030e
|
||||
F ext/jni/src/tests/000-000-sanity.test cfe6dc1b950751d6096e3f5695becaadcdaa048bfe9567209d6eb676e693366d
|
||||
F ext/jni/src/tests/000-001-ignored.test e17e874c6ab3c437f1293d88093cf06286083b65bf162317f91bbfd92f961b70
|
||||
F ext/lsm1/Makefile a553b728bba6c11201b795188c5708915cc4290f02b7df6ba7e8c4c943fd5cd9
|
||||
F ext/lsm1/Makefile.msc f8c878b467232226de288da320e1ac71c131f5ec91e08b21f502303347260013
|
||||
F ext/lsm1/lsm-test/README 87ea529d2abe615e856d4714bfe8bb185e6c2771b8612aa6298588b7b43e6f86
|
||||
@@ -297,7 +338,7 @@ F ext/misc/completion.c 6dafd7f4348eecc7be9e920d4b419d1fb2af75d938cd9c59a20cfe8b
|
||||
F ext/misc/compress.c 3354c77a7c8e86e07d849916000cdac451ed96500bfb5bd83b20eb61eee012c9
|
||||
F ext/misc/csv.c ca8d6dafc5469639de81937cb66ae2e6b358542aba94c4f791910d355a8e7f73
|
||||
F ext/misc/dbdump.c b8592f6f2da292c62991a13864a60d6c573c47a9cc58362131b9e6a64f823e01
|
||||
F ext/misc/decimal.c a61343b36672760e1d6d5b20a42cb52264db55bcd11d0a44e2e06e8ce23227e3
|
||||
F ext/misc/decimal.c 172cf81a8634e6a0f0bedaf71a8372fee63348cf5a3c4e1b78bb233c35889fdc
|
||||
F ext/misc/eval.c 04bc9aada78c888394204b4ed996ab834b99726fb59603b0ee3ed6e049755dc1
|
||||
F ext/misc/explain.c 0086fab288d4352ea638cf40ac382aad3b0dc5e845a1ea829a694c015fd970fe
|
||||
F ext/misc/fileio.c 4e7f7cd30de8df4820c552f14af3c9ca451c5ffe1f2e7bef34d598a12ebfb720
|
||||
@@ -415,7 +456,7 @@ F ext/repair/test/checkindex01.test b530f141413b587c9eb78ff734de6bb79bc3515c3350
|
||||
F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c
|
||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||
F ext/rtree/geopoly.c 971e0b5bd9adaf0811feb8c0842a310811159da10319eb0e74fdb42bf26b99ca
|
||||
F ext/rtree/rtree.c fb36e05027505f2c0dab24564e1d58ca4b789a6dfa48cf51aeee570018cf4814
|
||||
F ext/rtree/rtree.c 6954f4a3ca51c2e3db35c52e0513f3520999eb7a967f3d53b71db7ebddd8b3a5
|
||||
F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412
|
||||
F ext/rtree/rtree1.test 877d40b8b61b1f88cec9d4dc0ff8334f5b05299fac12a35141532e2881860e9d
|
||||
F ext/rtree/rtree2.test 9d9deddbb16fd0c30c36e6b4fdc3ee3132d765567f0f9432ee71e1303d32603d
|
||||
@@ -496,7 +537,7 @@ F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
|
||||
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
|
||||
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
|
||||
F ext/wasm/EXPORTED_FUNCTIONS.fiddle 7fb73f7150ab79d83bb45a67d257553c905c78cd3d693101699243f36c5ae6c3
|
||||
F ext/wasm/GNUmakefile 8159bc5f9433fe21022c1a8e8c30cb1a523530ba9ef53bdf5d1e0a2186554806
|
||||
F ext/wasm/GNUmakefile d02f3c8798b754f68b1f6b422ccff894a10bf352fc9c4eb8945baeace1acac28
|
||||
F ext/wasm/README-dist.txt 6382cb9548076fca472fb3330bbdba3a55c1ea0b180ff9253f084f07ff383576
|
||||
F ext/wasm/README.md a8a2962c3aebdf8d2104a9102e336c5554e78fc6072746e5daf9c61514e7d193
|
||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api c5eaceabb9e759aaae7d3101a4a3e542f96ab2c99d89a80ce20ec18c23115f33
|
||||
@@ -571,7 +612,7 @@ F ext/wasm/wasmfs.make 8a4955882aaa0783b3f60a9484a1f0f3d8b6f775c0fcd17c082f31966
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0
|
||||
F main.mk 17ab4dd35f863772967540d8ebcb659691638e18c746b68ce8a8b3f545cb8ec3
|
||||
F main.mk 5fe45da4f1e5f705eb9c2dfc896bc8b0e212e4edee70fb989ae243118dd314a9
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421
|
||||
@@ -580,7 +621,7 @@ F mptest/mptest.c aa41ace6dbc5050d76b02548d3521e6bbccae4f0
|
||||
F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d
|
||||
F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
|
||||
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F sqlite_cfg.h.in baf2e409c63d4e7a765e17769b6ff17c5a82bbd9cbf1e284fd2e4cefaff3fcf2
|
||||
F src/alter.c 3ff8c2fca0c0636d43459154bb40d79c882df1b34df77f89c4ec47ab2e2389f5
|
||||
@@ -604,7 +645,7 @@ F src/delete.c cb766727c78e715f9fb7ec8a7d03658ed2a3016343ca687acfcec9083cdca500
|
||||
F src/expr.c 1affe0cc049683ef0ef3545d9b6901508556b0ef7e2892a344c3df6d7288d79d
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c a7fcbf7e66d14dbb73cf49f31489ebf66d0e6006c62b95246924a3bae9f37b36
|
||||
F src/func.c cb04a0496022ed1b32f2701695632cae4a44c806684178a298f2efaf27160519
|
||||
F src/func.c 2c5b3d0c5f9998fa60ef2eda64fcb51d59a950dd0e695cdb5324943c4947c3d9
|
||||
F src/global.c 29f56a330ed9d1b5cd9b79ac0ca36f97ac3afc730ff8bfa987b0db9e559d684d
|
||||
F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220
|
||||
F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
|
||||
@@ -613,7 +654,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c 3f0a94082d978bbdd33c38fefea15346c6c6bffb70bc645a71dc0f1f87dd3276
|
||||
F src/json.c ae840f87b418f039f5d336b488933d09396bd31e6b31e855b93055ccaee4e255
|
||||
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
||||
F src/loadext.c 176d6b2cb18a6ad73b133db17f6fc351c4d9a2d510deebdb76c22bde9cfd1465
|
||||
F src/loadext.c 98cfba10989b3da6f1807ad42444017742db7f100a54f1032af7a8b1295912c0
|
||||
F src/main.c e56843b488ead74369eeffc64cd5b9d3a7ffbf8621bb0cd695272d9b9ce53afa
|
||||
F src/malloc.c 47b82c5daad557d9b963e3873e99c22570fb470719082c6658bf64e3012f7d23
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
@@ -636,10 +677,10 @@ F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e
|
||||
F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a
|
||||
F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107
|
||||
F src/os_unix.c c8003dfe6502315cf930160b6cf1b93f82211bed5ab9226509faa6324030c8ea
|
||||
F src/os_win.c 7038223a1cda0a47e2ab4db47f63bf1833fe53ba0542f0f283a062ea13894103
|
||||
F src/os_win.c 4a50a154aeebc66a1f8fb79c1ff6dd5fe3d005556533361e0d460d41cb6a45a8
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c fda6c42c41a7eb58a62fd786cdef7a0e836234553ab8e59e03ea10b4dc3e26a1
|
||||
F src/pager.h 55870bc2e0cabd29bcbaf650d342d3b970e316f440886f388052e34623ad1e29
|
||||
F src/pager.h 314eb19f250d6ce31bdc32255a47141125f9b7c13cc202da2995eed5ef3c9825
|
||||
F src/parse.y 92a9cc670816e1274a107d02ed8efec6028c23713c767f035479fde411c86f27
|
||||
F src/pcache.c 4cd4a0043167da9ba7e19b4d179a0e6354e7fe32c16f781ecf9bf0a5ff63b40b
|
||||
F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
|
||||
@@ -652,17 +693,17 @@ F src/random.c 9bd018738ec450bf35d28050b4b33fa9a6eebf3aaefb1a1cff42dc14a7725673
|
||||
F src/resolve.c 37953a5f36c60bea413c3c04efcd433b6177009f508ef2ace0494728912fe2e9
|
||||
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
||||
F src/select.c 996dda45d2a1a0228005849702348c7fd598437afa169c2c110f2c2ee582b382
|
||||
F src/shell.c.in 694aaf751f00610381533d4a31c83d142cfc83ef91ef65e2aa6912ace7c39b40
|
||||
F src/shell.c.in 2f9be25294b68b07e7e81f0adcec4475aba6011b64f160e414efe226910c4d7b
|
||||
F src/sqlite.h.in bc319c39cb72ef72c4f1d1d3b7662bce1fb8ba961913e0c145472f2d9fc11a3b
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h da473ce2b3d0ae407a6300c4a164589b9a6bfdbec9462688a8593ff16f3bb6e4
|
||||
F src/sqlite3ext.h 2f30b2671f4c03cd27a43f039e11251391066c97d11385f5f963bb40b03038ac
|
||||
F src/sqliteInt.h d639aff687cfaa64f273a0f62eebb81bad875fdb9e8ff02d1a0235a8c1957e96
|
||||
F src/sqliteLimit.h 33b1c9baba578d34efe7dfdb43193b366111cdf41476b1e82699e14c11ee1fb6
|
||||
F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749
|
||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||
F src/tclsqlite.c ecbc3c99c0d0c3ed122a913f143026c26d38d57f33e06bb71185dd5c1efe37cd
|
||||
F src/test1.c 91addc5c30c1389d257380b6e42ae0681d32d24553b9938d798a47ff96fa75ca
|
||||
F src/test2.c 827446e259a3b7ab949da1542953edda7b5117982576d3e6f1c24a0dd20a5cef
|
||||
F src/test2.c 54520d0565ef2b9bf0f8f1dcac43dc4d06baf4ffe13d10905f8d8c3ad3e4b9ab
|
||||
F src/test3.c e5178558c41ff53236ae0271e9acb3d6885a94981d2eb939536ee6474598840e
|
||||
F src/test4.c 4533b76419e7feb41b40582554663ed3cd77aaa54e135cf76b3205098cd6e664
|
||||
F src/test5.c 328aae2c010c57a9829d255dc099d6899311672d
|
||||
@@ -716,15 +757,15 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
||||
F src/tokenize.c 23d9f4539880b40226254ad9072f4ecf12eb1902e62aea47aac29928afafcfd5
|
||||
F src/treeview.c 1d52fbc4e97161e65858d36e3424ea6e3fc045dd8a679c82b4b9593dc30de3bd
|
||||
F src/trigger.c ad6ab9452715fa9a8075442e15196022275b414b9141b566af8cdb7a1605f2b0
|
||||
F src/update.c eafa1d6e32de4749986cbebc32ffb094c4401318bb713e5d2a18fe3e5a93ae8d
|
||||
F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145
|
||||
F src/update.c 0f8df185d63e1d3a777ae889880be1f9227bb37bb40d3e461555a6925ac298f8
|
||||
F src/upsert.c fa125a8d3410ce9a97b02cb50f7ae68a2476c405c76aa692d3acf6b8586e9242
|
||||
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
|
||||
F src/util.c a40062117e705eb3339201842717a022092816b92479eead6397cde28af32ff9
|
||||
F src/util.c 278b81c3b33db1b5a5f3859adf8905c165b910080043061d44d3c5a25b4b406d
|
||||
F src/vacuum.c b1dd6d73869229b6e08bac910ac011dc9da42e3120ec2b7241accc5a752bd419
|
||||
F src/vdbe.c 3ef180bab789aa99aec753fd26ecb8f3d56c9f6870997cafd8c5fc2b7c989a43
|
||||
F src/vdbe.h 41485521f68e9437fdb7ec4a90f9d86ab294e9bb8281e33b235915e29122cfc0
|
||||
F src/vdbeInt.h 949669dfd8a41550d27dcb905b494f2ccde9a2e6c1b0b04daa1227e2e74c2b2c
|
||||
F src/vdbeapi.c f37822f215740ede2a8fcae99bc13f2cc3a72dd0e1d22b81b9298c5ca67dbc38
|
||||
F src/vdbeapi.c 37341acd781fda162e8cf4d9fc2eaea2febad3b365877a9d7233b8c6d0960d85
|
||||
F src/vdbeaux.c 2c87c99975ac23e777e9c270d979eca38f2a021b1f14f061c83faab5b24d5576
|
||||
F src/vdbeblob.c 2516697b3ee8154eb8915f29466fb5d4f1ae39ee8b755ea909cefaf57ec5e2ce
|
||||
F src/vdbemem.c 317b9f48708139db6239ade40c7980b4bc8233168383690d588dad6d8437f722
|
||||
@@ -733,8 +774,8 @@ F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf8
|
||||
F src/vdbevtab.c 57fa8f56478e5b5cb558cb425e7878515e0a105c54f96f1d1bbf4b9433529254
|
||||
F src/vtab.c 1ecf8c3745d29275688d583e12822fa984d421e0286b5ef50c137bc3bf6d7a64
|
||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c 56eedfe60c278d0ee53f8a91b513ab40020773a1e83e29ec7ccc6a000ad5bd28
|
||||
F src/wal.h dcb0533caecf286be1c87b683e1282f3ca29fa5c00eb798e9226ce377a687cf4
|
||||
F src/wal.c ba4ea857cac27bb2fa9eb4bfecec4b552baca0fdbe527aac324e106de5201cc6
|
||||
F src/wal.h 8d02ab8c2a93a941f5898eb3345bf711c1d3f8f86f4be8d5428fb6c074962d8a
|
||||
F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2
|
||||
F src/where.c b8917792f1e0dbfa28fb29e6cd3d560060d69667be0ba4c491cbc772363264f5
|
||||
F src/whereInt.h c7d19902863beadec1d04e66aca39c0bcd60b74f05f0eaa7422c7005dfc5d51a
|
||||
@@ -966,7 +1007,7 @@ F test/dbpage.test fce29035c7566fd7835ec0f19422cb4b9c6944ce0e1b936ff8452443f92e8
|
||||
F test/dbpagefault.test d9111a62f3601d3efc6841ace3940181937342d245f92a1cca6cba8206d4f58a
|
||||
F test/dbstatus.test 4a4221a883025ffd39696b3d1b3910b928fb097d77e671351acb35f3aed42759
|
||||
F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef
|
||||
F test/decimal.test 18e7b4cb12e8d5c60d768b686ba52af3e1ca3ced4f870231f0476666fd9fab7e
|
||||
F test/decimal.test ef731887b43ee32ef86e1c8fddb61a40789f988332c029c601dcf2c319277e9e
|
||||
F test/default.test 9687cfb16717e4b8238c191697c98be88c0b16e568dd5368cd9284154097ef50
|
||||
F test/delete.test 2686e1c98d552ef37d79ad55b17b93fe96fad9737786917ce3839767f734c48f
|
||||
F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
|
||||
@@ -1151,7 +1192,7 @@ F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c
|
||||
F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634
|
||||
F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830
|
||||
F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2
|
||||
F test/fuzzcheck.c 29a2f0237553375498f891c9487a2ef3267b47deecc5d5b4335fa37f904cb8d3
|
||||
F test/fuzzcheck.c 69b8549e112fb815931a8c14c7955a0c407ae91a79356eecb82458384f2cb989
|
||||
F test/fuzzdata1.db 3e86d9cf5aea68ddb8e27c02d7dfdaa226347426c7eb814918e4d95475bf8517
|
||||
F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f
|
||||
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
|
||||
@@ -1253,7 +1294,7 @@ F test/json/README.md 63e3e589e1df8fd3cc1588ba1faaff659214003f8b77a15af5c6452b35
|
||||
F test/json/json-generator.tcl dc0dd0f393800c98658fc4c47eaa6af29d4e17527380cd28656fb261bddc8a3f
|
||||
F test/json/json-q1.txt 65f9d1cdcc4cffa9823fb73ed936aae5658700cd001fde448f68bfb91c807307
|
||||
F test/json/json-speed-check.sh 8b7babf530faa58bd59d6d362cec8e9036a68c5457ff46f3b1f1511d21af6737 x
|
||||
F test/json101.test 243b0a2650218ac5eafde6ce2a92a0e9d02bf24f62aec68693b69d9a693f120a
|
||||
F test/json101.test dc9d5a2a5b1fd1b54dbd71c538b17933cc98d84b4c1f821ead754933663dca55
|
||||
F test/json102.test 24f6f204f9cde45b971016691d0b92a9b4c58040d699e36d6b12cb165f9083ff
|
||||
F test/json103.test 53df87f83a4e5fa0c0a56eb29ff6c94055c6eb919f33316d62161a8880112dbe
|
||||
F test/json104.test 1b844a70cddcfa2e4cd81a5db0657b2e61e7f00868310f24f56a9ba0114348c1
|
||||
@@ -1265,7 +1306,7 @@ F test/kvtest.c 6e0228409ea7ca0497dad503fbd109badb5e59545d131014b6aaac68b56f484a
|
||||
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
|
||||
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
|
||||
F test/lemon-test01.y 58b764610fd934e189ffbb0bbfa33d171b9cb06019b55bdc04d090d6767e11d7
|
||||
F test/like.test 5fe0bc37f307aef0a453ce2de4632bdfc0759448f0421c39f6d53caefe905fac
|
||||
F test/like.test 242ee7f5d08a031144c0daf63bbd7e7710c847ccf387a83347e0b61b3aa69526
|
||||
F test/like2.test d3be15fefee3e02fc88942a9b98f26c5339bbdef7783c90023c092c4955fe3d3
|
||||
F test/like3.test a76e5938fadbe6d32807284c796bafd869974a961057bc5fc5a28e06de98745c
|
||||
F test/limit.test 350f5d03c29e7dff9a2cde016f84f8d368d40bcd02fa2b2a52fa10c4bf3cbfaf
|
||||
@@ -1390,7 +1431,7 @@ F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
|
||||
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
|
||||
F test/pendingrace.test cbdf0f74bc939fb43cebad64dda7a0b5a3941a10b7e9cc2b596ff3e423a18156
|
||||
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
|
||||
F test/permutations.test afbe9e54e88b93bb9b9b55d078d6c826de33a48b784258ba74d9549d2eb000a1
|
||||
F test/permutations.test f46a1b5a8f1c81b7e3054f59a8354d8d7af3ca1827a347d4a9865440fc8c47b9
|
||||
F test/pg_common.tcl 3b27542224db1e713ae387459b5d117c836a5f6e328846922993b6d2b7640d9f
|
||||
F test/pragma.test 57a36226218c03cfb381019fe43234b2cefbd8a1f12825514f906a17ccf7991e
|
||||
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
|
||||
@@ -1419,7 +1460,7 @@ F test/recover.test fd5199f928757cb308661b5fdca1abc19398a798ff7f24b57c3071e9f8e0
|
||||
F test/regexp1.test 8f2a8bc1569666e29a4cee6c1a666cd224eb6d50e2470d1dc1df995170f3e0f1
|
||||
F test/regexp2.test 55ed41da802b0e284ac7e2fe944be3948f93ff25abbca0361a609acfed1368b5
|
||||
F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2118d
|
||||
F test/releasetest_data.tcl c8cf85aeb313a771e18dae01396f5ca70e85d4574df681990629b1103f185afe
|
||||
F test/releasetest_data.tcl 80ef3941bf7ad136f4dc3d8960786f10a4f488797238171bdd757cc6eb4c3efa
|
||||
F test/resetdb.test 54c06f18bc832ac6d6319e5ab23d5c8dd49fdbeec7c696d791682a8006bd5fc3
|
||||
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
|
||||
F test/returning1.test db532cde29d6aebbc48c6ddc3149b30476f8e69ca7a2c4b53986c7635e6fd8ec
|
||||
@@ -1523,7 +1564,7 @@ F test/snapshot_up.test a0a29c4cf33475fcef07c3f8e64af795e24ab91b4cc68295863402a3
|
||||
F test/soak.test 18944cf21b94a7fe0df02016a6ee1e9632bc4e8d095a0cb49d95e15d5cca2d5c
|
||||
F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087
|
||||
F test/sort.test f86751134159abb5e5fd4381a0d7038c91013638cd1e3fa1d7850901f6df6196
|
||||
F test/sort2.test cc23b7c19d684657559e8a55b02f7fcee03851d0
|
||||
F test/sort2.test 2f8c66402a03adebe77ce7aafca129fbf32df27d6c9b8f7a9f1b958e39f56da8
|
||||
F test/sort3.test 1480ed7c4c157682542224e05e3b75faf4a149e5
|
||||
F test/sort4.test cca6f4b0b5255882645bbbe346a6a9f4a5c7b6a18513a6a7bf4ac1c4761ddc19
|
||||
F test/sort5.test 6b43ae0e2169b5ceed441844492e55ba7f1ae0790528395ddf7888ab3094525d
|
||||
@@ -1582,8 +1623,8 @@ F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d163
|
||||
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
|
||||
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
|
||||
F test/tester.tcl e6b9adcf4e56aa5c658501c10650646fee467b85d51a4ac80263d2cdae3993ba
|
||||
F test/testrunner.tcl 59490f189cac99b16b0376d0cc0a7ecfb753a84b89c9f4c361af337d88db53ac
|
||||
F test/testrunner_data.tcl 8169c68654ac8906833b8a6aadca973358a441ebf88270dd05c153e5f96f76b8
|
||||
F test/testrunner.tcl 56a744d4e6e516b2091c2ca6b7b27b9600e9ded136a2c860c350515511ebe20a
|
||||
F test/testrunner_data.tcl 8afa4eeec7f7421db3d3af64cdd5544015e887c4289cf871a730cca5a7a8d934
|
||||
F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899
|
||||
F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502
|
||||
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
|
||||
@@ -1800,7 +1841,7 @@ F test/upfrom2.test 66f3ebf721b3cebd922faee5c386bf244f816d416b57c000753ff51af623
|
||||
F test/upfrom3.test 6130f24ebf97f5ea865e5d2a14a2d543fe5428a62e87cc60f62d875e45c1f5f0
|
||||
F test/upfrom4.test 78f742a6577c91a7a55c64edb8811004e7c6aa99b8d57b2320f70a918c357807
|
||||
F test/upfromfault.test 3a10075a0043f0c4fad6614b2c371f88a8ba5a4acab68b907438413865d6a8d6
|
||||
F test/upsert1.test b0ae2f58680c5205b4bc1cdeed3c3d444057c506f6c44494fa3eac60731d68a2
|
||||
F test/upsert1.test a512e2f884d3a36159fce2e45108c236f78ae38e35bda55f4050db580ceb25d3
|
||||
F test/upsert2.test 720e94d09f7362a282bc69b3c6b83d51daeaaf0440eb4920a08b86518b8c7496
|
||||
F test/upsert3.test 88d7d590a1948a9cb6eac1b54b0642f67a9f35a1fc0f19b200e97d5d39e3179c
|
||||
F test/upsert4.test 25d2a1da92f149331ae0c51ca6e3eee78189577585eab92de149900d62994fa5
|
||||
@@ -2052,7 +2093,7 @@ F tool/sqldiff.c 2a693b4e7c1818c23f871f82f0c3fe67d80b67e3f087893089d33da29c1e387
|
||||
F tool/sqlite3_analyzer.c.in f88615bf33098945e0a42f17733f472083d150b58bdaaa5555a7129d0a51621c
|
||||
F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898
|
||||
F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848
|
||||
F tool/src-verify.c f0cef434a8d8629c4928a02a644fb85e33c8b875a7f2352ba68cc50965a7d213
|
||||
F tool/src-verify.c 41c586dee84d0b190ad13e0282ed83d4a65ec9fefde9adf4943efdf6558eea7f
|
||||
F tool/srcck1.c 371de5363b70154012955544f86fdee8f6e5326f
|
||||
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
|
||||
F tool/stripccomments.c 20b8aabc4694d0d4af5566e42da1f1a03aff057689370326e9269a9ddcffdc37
|
||||
@@ -2088,8 +2129,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 331f2f3e5db9b6139be984f1b959cd0d51563adaa68452aa2f42741c69bc6319
|
||||
R 8cf5124efb077972dc4592e59c017049
|
||||
P d3d77e35ea39df9e22032a7e1af5b7f38d53a4d43bc46afe36e342cdcfd17528 135bf72c6b5f436b11463dd40b3a73bcc610bf9c2dcbe6646dbedd0d9325f6a9
|
||||
R b7d659f9bcf8ba358058d0baa617e913
|
||||
U dan
|
||||
Z 86179e20e1202dcde51614a70e1512c5
|
||||
Z 380a55b5d6a3d9fc5af4f4bcbddcaf42
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@@ -1 +1 @@
|
||||
d3d77e35ea39df9e22032a7e1af5b7f38d53a4d43bc46afe36e342cdcfd17528
|
||||
4d8df0c426b8ce3db6cfb71e23f752026ef886b9bb833dc4be9717db9955b1db
|
161
sqlite3.1
161
sqlite3.1
@@ -2,7 +2,7 @@
|
||||
.\" First parameter, NAME, should be all caps
|
||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||
.\" other parameters are allowed: see man(7), man(1)
|
||||
.TH SQLITE3 1 "Fri Oct 31 10:41:31 EDT 2014"
|
||||
.TH SQLITE3 1 "Fri Aug 11 23:50:12 CET 2023"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.\" Some roff macros, for reference:
|
||||
@@ -49,9 +49,9 @@ a table named "memos" and insert a couple of records into that table:
|
||||
$
|
||||
.B sqlite3 mydata.db
|
||||
.br
|
||||
SQLite version 3.8.8
|
||||
SQLite version 3.43.0 2023-08-11 17:45:23
|
||||
.br
|
||||
Enter ".help" for instructions
|
||||
Enter ".help" for usage hints.
|
||||
.br
|
||||
sqlite>
|
||||
.B create table memos(text, priority INTEGER);
|
||||
@@ -108,141 +108,13 @@ sqlite>
|
||||
.B .help
|
||||
.nf
|
||||
.tr %.
|
||||
%backup ?DB? FILE Backup DB (default "main") to FILE
|
||||
%bail on|off Stop after hitting an error. Default OFF
|
||||
%clone NEWDB Clone data into NEWDB from the existing database
|
||||
%databases List names and files of attached databases
|
||||
%dump ?TABLE? ... Dump the database in an SQL text format
|
||||
If TABLE specified, only dump tables matching
|
||||
LIKE pattern TABLE.
|
||||
%echo on|off Turn command echo on or off
|
||||
%eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN
|
||||
%exit Exit this program
|
||||
%explain ?on|off? Turn output mode suitable for EXPLAIN on or off.
|
||||
With no args, it turns EXPLAIN on.
|
||||
%fullschema Show schema and the content of sqlite_stat tables
|
||||
%headers on|off Turn display of headers on or off
|
||||
%help Show this message
|
||||
%import FILE TABLE Import data from FILE into TABLE
|
||||
%indices ?TABLE? Show names of all indices
|
||||
If TABLE specified, only show indices for tables
|
||||
matching LIKE pattern TABLE.
|
||||
%load FILE ?ENTRY? Load an extension library
|
||||
%log FILE|off Turn logging on or off. FILE can be stderr/stdout
|
||||
%mode MODE ?TABLE? Set output mode where MODE is one of:
|
||||
csv Comma-separated values
|
||||
column Left-aligned columns. (See .width)
|
||||
html HTML <table> code
|
||||
insert SQL insert statements for TABLE
|
||||
line One value per line
|
||||
list Values delimited by .separator string
|
||||
tabs Tab-separated values
|
||||
tcl TCL list elements
|
||||
%nullvalue STRING Use STRING in place of NULL values
|
||||
%once FILENAME Output for the next SQL command only to FILENAME
|
||||
%open ?FILENAME? Close existing database and reopen FILENAME
|
||||
%output ?FILENAME? Send output to FILENAME or stdout
|
||||
%print STRING... Print literal STRING
|
||||
%prompt MAIN CONTINUE Replace the standard prompts
|
||||
%quit Exit this program
|
||||
%read FILENAME Execute SQL in FILENAME
|
||||
%restore ?DB? FILE Restore content of DB (default "main") from FILE
|
||||
%save FILE Write in-memory database into FILE
|
||||
%schema ?TABLE? Show the CREATE statements
|
||||
If TABLE specified, only show tables matching
|
||||
LIKE pattern TABLE.
|
||||
%separator STRING ?NL? Change separator used by output mode and .import
|
||||
NL is the end-of-line mark for CSV
|
||||
%shell CMD ARGS... Run CMD ARGS... in a system shell
|
||||
%show Show the current values for various settings
|
||||
%stats on|off Turn stats on or off
|
||||
%system CMD ARGS... Run CMD ARGS... in a system shell
|
||||
%tables ?TABLE? List names of tables
|
||||
If TABLE specified, only list tables matching
|
||||
LIKE pattern TABLE.
|
||||
%timeout MS Try opening locked tables for MS milliseconds
|
||||
%timer on|off Turn SQL timer on or off
|
||||
%trace FILE|off Output each SQL statement as it is run
|
||||
%vfsname ?AUX? Print the name of the VFS stack
|
||||
%width NUM1 NUM2 ... Set column widths for "column" mode
|
||||
Negative values right-justify
|
||||
sqlite>
|
||||
...
|
||||
.sp
|
||||
.fi
|
||||
.SH OPTIONS
|
||||
.B sqlite3
|
||||
has the following options:
|
||||
.TP
|
||||
.B \-bail
|
||||
Stop after hitting an error.
|
||||
.TP
|
||||
.B \-batch
|
||||
Force batch I/O.
|
||||
.TP
|
||||
.B \-column
|
||||
Query results will be displayed in a table like form, using
|
||||
whitespace characters to separate the columns and align the
|
||||
output.
|
||||
.TP
|
||||
.BI \-cmd\ command
|
||||
run
|
||||
.I command
|
||||
before reading stdin
|
||||
.TP
|
||||
.B \-csv
|
||||
Set output mode to CSV (comma separated values).
|
||||
.TP
|
||||
.B \-echo
|
||||
Print commands before execution.
|
||||
.TP
|
||||
.BI \-init\ file
|
||||
Read and execute commands from
|
||||
.I file
|
||||
, which can contain a mix of SQL statements and meta-commands.
|
||||
.TP
|
||||
.B \-[no]header
|
||||
Turn headers on or off.
|
||||
.TP
|
||||
.B \-help
|
||||
Show help on options and exit.
|
||||
.TP
|
||||
.B \-html
|
||||
Query results will be output as simple HTML tables.
|
||||
.TP
|
||||
.B \-interactive
|
||||
Force interactive I/O.
|
||||
.TP
|
||||
.B \-line
|
||||
Query results will be displayed with one value per line, rows
|
||||
separated by a blank line. Designed to be easily parsed by
|
||||
scripts or other programs
|
||||
.TP
|
||||
.B \-list
|
||||
Query results will be displayed with the separator (|, by default)
|
||||
character between each field value. The default.
|
||||
.TP
|
||||
.BI \-mmap\ N
|
||||
Set default mmap size to
|
||||
.I N
|
||||
\.
|
||||
.TP
|
||||
.BI \-nullvalue\ string
|
||||
Set string used to represent NULL values. Default is ''
|
||||
(empty string).
|
||||
.TP
|
||||
.BI \-separator\ separator
|
||||
Set output field separator. Default is '|'.
|
||||
.TP
|
||||
.B \-stats
|
||||
Print memory stats before each finalize.
|
||||
.TP
|
||||
.B \-version
|
||||
Show SQLite version.
|
||||
.TP
|
||||
.BI \-vfs\ name
|
||||
Use
|
||||
.I name
|
||||
as the default VFS.
|
||||
|
||||
The available commands differ by version and build options, so they
|
||||
are not listed here. Please refer to your local copy for all available
|
||||
options.
|
||||
|
||||
|
||||
.SH INIT FILE
|
||||
@@ -265,22 +137,25 @@ continue prompt = " ...> "
|
||||
.sp
|
||||
.fi
|
||||
|
||||
o If the file
|
||||
o If the file
|
||||
.B ${XDG_CONFIG_HOME}/sqlite3/sqliterc
|
||||
or
|
||||
.B ~/.sqliterc
|
||||
exists, it is processed first.
|
||||
can be found in the user's home directory, it is
|
||||
read and processed. It should generally only contain meta-commands.
|
||||
exists, the first of those to be found is processed during startup.
|
||||
It should generally only contain meta-commands.
|
||||
|
||||
o If the -init option is present, the specified file is processed.
|
||||
|
||||
o All other command line options are processed.
|
||||
|
||||
.SH SEE ALSO
|
||||
http://www.sqlite.org/cli.html
|
||||
https://sqlite.org/cli.html
|
||||
.br
|
||||
https://sqlite.org/fiddle (a WebAssembly build of the CLI app)
|
||||
.br
|
||||
The sqlite3-doc package.
|
||||
.SH AUTHOR
|
||||
This manual page was originally written by Andreas Rottmann
|
||||
<rotty@debian.org>, for the Debian GNU/Linux system (but may be used
|
||||
by others). It was subsequently revised by Bill Bumgarner <bbum@mac.com> and
|
||||
further updated by Laszlo Boszormenyi <gcs@debian.hu> .
|
||||
by others). It was subsequently revised by Bill Bumgarner <bbum@mac.com>,
|
||||
Laszlo Boszormenyi <gcs@debian.hu>, and the sqlite3 developers.
|
||||
|
13
src/func.c
13
src/func.c
@@ -2156,8 +2156,10 @@ void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){
|
||||
** sensitive.
|
||||
*/
|
||||
void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
|
||||
FuncDef *pDef;
|
||||
struct compareInfo *pInfo;
|
||||
int flags;
|
||||
int nArg;
|
||||
if( caseSensitive ){
|
||||
pInfo = (struct compareInfo*)&likeInfoAlt;
|
||||
flags = SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE;
|
||||
@@ -2165,10 +2167,13 @@ void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
|
||||
pInfo = (struct compareInfo*)&likeInfoNorm;
|
||||
flags = SQLITE_FUNC_LIKE;
|
||||
}
|
||||
sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
|
||||
sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
|
||||
sqlite3FindFunction(db, "like", 2, SQLITE_UTF8, 0)->funcFlags |= flags;
|
||||
sqlite3FindFunction(db, "like", 3, SQLITE_UTF8, 0)->funcFlags |= flags;
|
||||
for(nArg=2; nArg<=3; nArg++){
|
||||
sqlite3CreateFunc(db, "like", nArg, SQLITE_UTF8, pInfo, likeFunc,
|
||||
0, 0, 0, 0, 0);
|
||||
pDef = sqlite3FindFunction(db, "like", nArg, SQLITE_UTF8, 0);
|
||||
pDef->funcFlags |= flags;
|
||||
pDef->funcFlags &= ~SQLITE_FUNC_UNSAFE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -512,7 +512,9 @@ static const sqlite3_api_routines sqlite3Apis = {
|
||||
/* Version 3.40.0 and later */
|
||||
sqlite3_value_encoding,
|
||||
/* Version 3.41.0 and later */
|
||||
sqlite3_is_interrupted
|
||||
sqlite3_is_interrupted,
|
||||
/* Version 3.43.0 and later */
|
||||
sqlite3_stmt_explain
|
||||
};
|
||||
|
||||
/* True if x is the directory separator character
|
||||
|
@@ -4747,6 +4747,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"0123456789";
|
||||
size_t i, j;
|
||||
DWORD pid;
|
||||
int nPre = sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX);
|
||||
int nMax, nBuf, nDir, nLen;
|
||||
char *zBuf;
|
||||
@@ -4959,7 +4960,10 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
|
||||
|
||||
j = sqlite3Strlen30(zBuf);
|
||||
sqlite3_randomness(15, &zBuf[j]);
|
||||
pid = osGetCurrentProcessId();
|
||||
for(i=0; i<15; i++, j++){
|
||||
zBuf[j] += pid & 0xff;
|
||||
pid >>= 8;
|
||||
zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
|
||||
}
|
||||
zBuf[j] = 0;
|
||||
|
@@ -274,7 +274,7 @@ int sqlite3PagerWalInfo(Pager*, u32 *pnPrior, u32 *pnFrame);
|
||||
# define enable_simulated_io_errors()
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_USE_SEH
|
||||
#if defined(SQLITE_USE_SEH) && !defined(SQLITE_OMIT_WAL)
|
||||
int sqlite3PagerWalSystemErrno(Pager*);
|
||||
#endif
|
||||
|
||||
|
@@ -4799,7 +4799,6 @@ static const char *(azHelp[]) = {
|
||||
" --async Write to FILE without journal and fsync()",
|
||||
#endif
|
||||
".bail on|off Stop after hitting an error. Default OFF",
|
||||
".binary on|off Turn binary output on or off. Default OFF",
|
||||
#ifndef SQLITE_SHELL_FIDDLE
|
||||
".cd DIRECTORY Change the working directory to DIRECTORY",
|
||||
#endif
|
||||
@@ -4809,6 +4808,9 @@ static const char *(azHelp[]) = {
|
||||
".clone NEWDB Clone data into NEWDB from the existing database",
|
||||
#endif
|
||||
".connection [close] [#] Open or close an auxiliary database connection",
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
".crnl on|off Translate \\n to \\r\\n. Default ON",
|
||||
#endif
|
||||
".databases List names and files of attached databases",
|
||||
".dbconfig ?op? ?val? List or change sqlite3_db_config() options",
|
||||
#if SQLITE_SHELL_HAVE_RECOVER
|
||||
@@ -8164,6 +8166,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
}else
|
||||
|
||||
/* Undocumented. Legacy only. See "crnl" below */
|
||||
if( c=='b' && n>=3 && cli_strncmp(azArg[0], "binary", n)==0 ){
|
||||
if( nArg==2 ){
|
||||
if( booleanValue(azArg[1]) ){
|
||||
@@ -8172,6 +8175,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
setTextMode(p->out, 1);
|
||||
}
|
||||
}else{
|
||||
raw_printf(stderr, "The \".binary\" command is deprecated."
|
||||
" Use \".crnl\" instead.\n");
|
||||
raw_printf(stderr, "Usage: .binary on|off\n");
|
||||
rc = 1;
|
||||
}
|
||||
@@ -8299,6 +8304,22 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
}else
|
||||
|
||||
if( c=='c' && n==4 && cli_strncmp(azArg[0], "crnl", n)==0 ){
|
||||
if( nArg==2 ){
|
||||
if( booleanValue(azArg[1]) ){
|
||||
setTextMode(p->out, 1);
|
||||
}else{
|
||||
setBinaryMode(p->out, 1);
|
||||
}
|
||||
}else{
|
||||
#if !defined(_WIN32) && !defined(WIN32)
|
||||
raw_printf(stderr, "The \".crnl\" is a no-op on non-Windows machines.\n");
|
||||
#endif
|
||||
raw_printf(stderr, "Usage: .crnl on|off\n");
|
||||
rc = 1;
|
||||
}
|
||||
}else
|
||||
|
||||
if( c=='d' && n>1 && cli_strncmp(azArg[0], "databases", n)==0 ){
|
||||
char **azName = 0;
|
||||
int nName = 0;
|
||||
@@ -11283,6 +11304,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
#endif /* SQLITE_USER_AUTHENTICATION */
|
||||
|
||||
if( c=='v' && cli_strncmp(azArg[0], "version", n)==0 ){
|
||||
char *zPtrSz = sizeof(void*)==8 ? "64-bit" : "32-bit";
|
||||
utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
|
||||
sqlite3_libversion(), sqlite3_sourceid());
|
||||
#if SQLITE_HAVE_ZLIB
|
||||
@@ -11293,11 +11315,11 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
#if defined(__clang__) && defined(__clang_major__)
|
||||
utf8_printf(p->out, "clang-" CTIMEOPT_VAL(__clang_major__) "."
|
||||
CTIMEOPT_VAL(__clang_minor__) "."
|
||||
CTIMEOPT_VAL(__clang_patchlevel__) "\n");
|
||||
CTIMEOPT_VAL(__clang_patchlevel__) " (%s)\n", zPtrSz);
|
||||
#elif defined(_MSC_VER)
|
||||
utf8_printf(p->out, "msvc-" CTIMEOPT_VAL(_MSC_VER) "\n");
|
||||
utf8_printf(p->out, "msvc-" CTIMEOPT_VAL(_MSC_VER) " (%s)\n", zPtrSz);
|
||||
#elif defined(__GNUC__) && defined(__VERSION__)
|
||||
utf8_printf(p->out, "gcc-" __VERSION__ "\n");
|
||||
utf8_printf(p->out, "gcc-" __VERSION__ " (%s)\n", zPtrSz);
|
||||
#endif
|
||||
}else
|
||||
|
||||
@@ -12471,7 +12493,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
}else if( cli_strcmp(z,"-bail")==0 ){
|
||||
/* No-op. The bail_on_error flag should already be set. */
|
||||
}else if( cli_strcmp(z,"-version")==0 ){
|
||||
printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
|
||||
printf("%s %s (%d-bit)\n", sqlite3_libversion(), sqlite3_sourceid(),
|
||||
8*(int)sizeof(char*));
|
||||
return 0;
|
||||
}else if( cli_strcmp(z,"-interactive")==0 ){
|
||||
stdin_is_interactive = 1;
|
||||
|
@@ -361,6 +361,8 @@ struct sqlite3_api_routines {
|
||||
int (*value_encoding)(sqlite3_value*);
|
||||
/* Version 3.41.0 and later */
|
||||
int (*is_interrupted)(sqlite3*);
|
||||
/* Version 3.43.0 and later */
|
||||
int (*stmt_explain)(sqlite3_stmt*,int);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -689,6 +691,8 @@ typedef int (*sqlite3_loadext_entry)(
|
||||
#define sqlite3_value_encoding sqlite3_api->value_encoding
|
||||
/* Version 3.41.0 and later */
|
||||
#define sqlite3_is_interrupted sqlite3_api->is_interrupted
|
||||
/* Version 3.43.0 and later */
|
||||
#define sqlite3_stmt_explain sqlite3_api->stmt_explain
|
||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
|
@@ -608,7 +608,7 @@ static int faultSimCallback(int x){
|
||||
zInt[i] = (x%10) + '0';
|
||||
}
|
||||
if( isNeg ) zInt[i--] = '-';
|
||||
memcpy(faultSimScript+faultSimScriptSize, zInt+i+1, sizeof(zInt)-i);
|
||||
memcpy(faultSimScript+faultSimScriptSize, zInt+i+1, sizeof(zInt)-i-1);
|
||||
}
|
||||
rc = Tcl_Eval(faultSimInterp, faultSimScript);
|
||||
if( rc ){
|
||||
|
@@ -1270,9 +1270,9 @@ static void updateVirtualTable(
|
||||
sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr, 0)
|
||||
);
|
||||
}else{
|
||||
Expr *pRow = exprRowColumn(pParse, i);
|
||||
if( pRow ) pRow->op2 = OPFLAG_NOCHNG;
|
||||
pList = sqlite3ExprListAppend(pParse, pList, pRow);
|
||||
Expr *pRowExpr = exprRowColumn(pParse, i);
|
||||
if( pRowExpr ) pRowExpr->op2 = OPFLAG_NOCHNG;
|
||||
pList = sqlite3ExprListAppend(pParse, pList, pRowExpr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -178,7 +178,7 @@ int sqlite3UpsertAnalyzeTarget(
|
||||
pExpr = &sCol[0];
|
||||
}
|
||||
for(jj=0; jj<nn; jj++){
|
||||
if( sqlite3ExprCompare(pParse,pTarget->a[jj].pExpr,pExpr,iCursor)<2 ){
|
||||
if( sqlite3ExprCompare(0,pTarget->a[jj].pExpr,pExpr,iCursor)<2 ){
|
||||
break; /* Column ii of the index matches column jj of target */
|
||||
}
|
||||
}
|
||||
|
@@ -610,7 +610,11 @@ do_atof_calc:
|
||||
}
|
||||
assert( r>=0.0 );
|
||||
if( r>+1.7976931348623157081452742373e+308L ){
|
||||
#ifdef INFINITY
|
||||
*pResult = +INFINITY;
|
||||
#else
|
||||
*pResult = 1.0e308*10.0;
|
||||
#endif
|
||||
}else{
|
||||
*pResult = (double)r;
|
||||
}
|
||||
@@ -1016,7 +1020,7 @@ void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRound){
|
||||
** The error terms on constants like 1.0e+100 computed using the
|
||||
** decimal extension, for example as follows:
|
||||
**
|
||||
** SELECT decimal_sci(decimal_sub('1.0e+100',decimal(1.0e+100)));
|
||||
** SELECT decimal_exp(decimal_sub('1.0e+100',decimal(1.0e+100)));
|
||||
*/
|
||||
double rr[2];
|
||||
rr[0] = r;
|
||||
|
@@ -1864,7 +1864,7 @@ int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode){
|
||||
Vdbe *v = (Vdbe*)pStmt;
|
||||
int rc;
|
||||
sqlite3_mutex_enter(v->db->mutex);
|
||||
if( v->explain==eMode ){
|
||||
if( ((int)v->explain)==eMode ){
|
||||
rc = SQLITE_OK;
|
||||
}else if( eMode<0 || eMode>2 ){
|
||||
rc = SQLITE_ERROR;
|
||||
|
28
src/wal.c
28
src/wal.c
@@ -795,6 +795,8 @@ struct Wal {
|
||||
#ifdef SQLITE_USE_SEH
|
||||
u32 lockMask; /* Mask of locks held */
|
||||
void *pFree; /* Pointer to sqlite3_free() if exception thrown */
|
||||
u32 *pWiValue; /* Value to write into apWiData[iWiPg] */
|
||||
int iWiPg; /* Write pWiValue into apWiData[iWiPg] */
|
||||
int iSysErrno; /* System error code following exception */
|
||||
#endif
|
||||
#ifdef SQLITE_DEBUG
|
||||
@@ -969,11 +971,24 @@ static void sehInjectFault(Wal *pWal){
|
||||
#define SEH_FREE_ON_ERROR(X,Y) \
|
||||
assert( (X==0 || Y==0) && pWal->pFree==X ); pWal->pFree = Y
|
||||
|
||||
/*
|
||||
** There are two ways to use this macro. To arrange for pWal->apWiData[iPg]
|
||||
** to be set to pValue if an exception is thrown:
|
||||
**
|
||||
** SEH_SET_ON_ERROR(iPg, pValue);
|
||||
**
|
||||
** and to cancel the same:
|
||||
**
|
||||
** SEH_SET_ON_ERROR(0, 0);
|
||||
*/
|
||||
#define SEH_SET_ON_ERROR(X,Y) pWal->iWiPg = X; pWal->pWiValue = Y
|
||||
|
||||
#else
|
||||
# define SEH_TRY VVA_ONLY(pWal->nSehTry++);
|
||||
# define SEH_EXCEPT(X) VVA_ONLY(pWal->nSehTry--); assert( pWal->nSehTry==0 );
|
||||
# define SEH_INJECT_FAULT assert( pWal->nSehTry>0 );
|
||||
# define SEH_FREE_ON_ERROR(X,Y)
|
||||
# define SEH_SET_ON_ERROR(X,Y)
|
||||
#endif /* ifdef SQLITE_USE_SEH */
|
||||
|
||||
/*
|
||||
@@ -1782,6 +1797,7 @@ static int walIndexRecoverOne(Wal *pWal, int iWal, u32 *pnCkpt, int *pbZero){
|
||||
rc = walIndexPage(pWal, iPg, (volatile u32**)&aShare);
|
||||
assert( aShare!=0 || rc!=SQLITE_OK );
|
||||
if( aShare==0 ) break;
|
||||
SEH_SET_ON_ERROR(iPg, aShare);
|
||||
pWal->apWiData[iPg] = aPrivate;
|
||||
|
||||
if( iWal ){
|
||||
@@ -1820,6 +1836,7 @@ static int walIndexRecoverOne(Wal *pWal, int iWal, u32 *pnCkpt, int *pbZero){
|
||||
}
|
||||
}
|
||||
pWal->apWiData[iPg] = aShare;
|
||||
SEH_SET_ON_ERROR(0, 0);
|
||||
nHdr = (iPg==0 ? WALINDEX_HDR_SIZE : 0);
|
||||
nHdr32 = nHdr / sizeof(u32);
|
||||
#ifndef SQLITE_SAFER_WALINDEX_RECOVERY
|
||||
@@ -3001,7 +3018,9 @@ static void walLimitSize(Wal *pWal, i64 nMax){
|
||||
**
|
||||
** 2) Frees the pointer at Wal.pFree, if any, using sqlite3_free().
|
||||
**
|
||||
** 3) Returns SQLITE_IOERR.
|
||||
** 3) Set pWal->apWiData[pWal->iWiPg] to pWal->pWiValue if not NULL
|
||||
**
|
||||
** 4) Returns SQLITE_IOERR.
|
||||
*/
|
||||
static int walHandleException(Wal *pWal){
|
||||
if( pWal->exclusiveMode==0 ){
|
||||
@@ -3020,6 +3039,10 @@ static int walHandleException(Wal *pWal){
|
||||
}
|
||||
sqlite3_free(pWal->pFree);
|
||||
pWal->pFree = 0;
|
||||
if( pWal->pWiValue ){
|
||||
pWal->apWiData[pWal->iWiPg] = pWal->pWiValue;
|
||||
pWal->pWiValue = 0;
|
||||
}
|
||||
return SQLITE_IOERR_IN_PAGE;
|
||||
}
|
||||
|
||||
@@ -3834,7 +3857,8 @@ static int walSnapshotRecover(
|
||||
|
||||
rc = walHashGet(pWal, walFramePage(i), &sLoc);
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
pgno = sLoc.aPgno[i-sLoc.iZero];
|
||||
assert( i - sLoc.iZero - 1 >=0 );
|
||||
pgno = sLoc.aPgno[i-sLoc.iZero-1];
|
||||
iDbOff = (i64)(pgno-1) * szPage;
|
||||
|
||||
if( iDbOff+szPage<=szDb ){
|
||||
|
@@ -46,6 +46,7 @@
|
||||
# define sqlite3WalFindFrame(x,y,z) 0
|
||||
# define sqlite3WalFile(x) 0
|
||||
# define sqlite3WalJournalMode(x) 0
|
||||
# undef SQLITE_USE_SEH
|
||||
#else
|
||||
|
||||
#define WAL_SAVEPOINT_NDATA 4
|
||||
|
@@ -49,7 +49,7 @@ do_execsql_test 1080 {
|
||||
SELECT decimal('+123e+4');
|
||||
} {1230000}
|
||||
do_execsql_test 1081 {
|
||||
SELECT decimal_sci('+123e+4');
|
||||
SELECT decimal_exp('+123e+4');
|
||||
} {+1.23e+06}
|
||||
|
||||
|
||||
|
@@ -1205,10 +1205,12 @@ int runCombinedDbSqlInput(
|
||||
iSql = decodeDatabase((unsigned char*)aData, (int)nByte, &aDb, &nDb);
|
||||
if( iSql<0 ) return 0;
|
||||
if( nDb>=75 ){
|
||||
dbFlags = (aDb[72]<<24) + (aDb[73]<<16) + (aDb[74]<<8) + aDb[75];
|
||||
dbFlags = ((unsigned int)aDb[72]<<24) + ((unsigned int)aDb[73]<<16) +
|
||||
((unsigned int)aDb[74]<<8) + (unsigned int)aDb[75];
|
||||
}
|
||||
if( nDb>=79 ){
|
||||
dbOpt = (aDb[76]<<24) + (aDb[77]<<16) + (aDb[78]<<8) + aDb[79];
|
||||
dbOpt = ((unsigned int)aDb[76]<<24) + ((unsigned int)aDb[77]<<16) +
|
||||
((unsigned int)aDb[78]<<8) + (unsigned int)aDb[79];
|
||||
}
|
||||
nSql = (int)(nByte - iSql);
|
||||
if( bScript ){
|
||||
@@ -2031,7 +2033,9 @@ int main(int argc, char **argv){
|
||||
if( strcmp(z,"version")==0 ){
|
||||
int ii;
|
||||
const char *zz;
|
||||
printf("SQLite %s %s\n", sqlite3_libversion(), sqlite3_sourceid());
|
||||
printf("SQLite %s %s (%d-bit)\n",
|
||||
sqlite3_libversion(), sqlite3_sourceid(),
|
||||
8*(int)sizeof(char*));
|
||||
for(ii=0; (zz = sqlite3_compileoption_get(ii))!=0; ii++){
|
||||
printf("%s\n", zz);
|
||||
}
|
||||
@@ -2536,9 +2540,10 @@ int main(int argc, char **argv){
|
||||
printf("fuzzcheck: %u query invariants checked\n", g.nInvariant);
|
||||
}
|
||||
printf("fuzzcheck: 0 errors out of %d tests in %d.%03d seconds\n"
|
||||
"SQLite %s %s\n",
|
||||
"SQLite %s %s (%d-bit)\n",
|
||||
nTest, (int)(iElapse/1000), (int)(iElapse%1000),
|
||||
sqlite3_libversion(), sqlite3_sourceid());
|
||||
sqlite3_libversion(), sqlite3_sourceid(),
|
||||
8*(int)sizeof(char*));
|
||||
}
|
||||
free(azSrcDb);
|
||||
free(pHeap);
|
||||
|
@@ -122,14 +122,14 @@ do_execsql_test json101-4.8 {
|
||||
|
||||
# json_extract(JSON,'$') will return objects and arrays without change.
|
||||
#
|
||||
do_execsql_test json-4.10 {
|
||||
do_execsql_test json101-4.10 {
|
||||
SELECT count(*) FROM j1 WHERE json_type(x) IN ('object','array');
|
||||
SELECT x FROM j1
|
||||
WHERE json_extract(x,'$')<>x
|
||||
AND json_type(x) IN ('object','array');
|
||||
} {4}
|
||||
|
||||
do_execsql_test json-5.1 {
|
||||
do_execsql_test json101-5.1 {
|
||||
CREATE TABLE j2(id INTEGER PRIMARY KEY, json, src);
|
||||
INSERT INTO j2(id,json,src)
|
||||
VALUES(1,'{
|
||||
@@ -257,7 +257,7 @@ do_execsql_test json-5.1 {
|
||||
SELECT count(*) FROM j2;
|
||||
} {3}
|
||||
|
||||
do_execsql_test json-5.2 {
|
||||
do_execsql_test json101-5.2 {
|
||||
SELECT id, json_valid(json), json_type(json), '|' FROM j2 ORDER BY id;
|
||||
} {1 1 object | 2 1 object | 3 1 array |}
|
||||
|
||||
@@ -268,13 +268,13 @@ ifcapable !vtab {
|
||||
|
||||
# fullkey is always the same as path+key (with appropriate formatting)
|
||||
#
|
||||
do_execsql_test json-5.3 {
|
||||
do_execsql_test json101-5.3 {
|
||||
SELECT j2.rowid, jx.rowid, fullkey, path, key
|
||||
FROM j2, json_tree(j2.json) AS jx
|
||||
WHERE fullkey!=(path || CASE WHEN typeof(key)=='integer' THEN '['||key||']'
|
||||
ELSE '.'||key END);
|
||||
} {}
|
||||
do_execsql_test json-5.4 {
|
||||
do_execsql_test json101-5.4 {
|
||||
SELECT j2.rowid, jx.rowid, fullkey, path, key
|
||||
FROM j2, json_each(j2.json) AS jx
|
||||
WHERE fullkey!=(path || CASE WHEN typeof(key)=='integer' THEN '['||key||']'
|
||||
@@ -285,58 +285,58 @@ do_execsql_test json-5.4 {
|
||||
# Verify that the json_each.json and json_tree.json output is always the
|
||||
# same as input.
|
||||
#
|
||||
do_execsql_test json-5.5 {
|
||||
do_execsql_test json101-5.5 {
|
||||
SELECT j2.rowid, jx.rowid, fullkey, path, key
|
||||
FROM j2, json_each(j2.json) AS jx
|
||||
WHERE jx.json<>j2.json;
|
||||
} {}
|
||||
do_execsql_test json-5.6 {
|
||||
do_execsql_test json101-5.6 {
|
||||
SELECT j2.rowid, jx.rowid, fullkey, path, key
|
||||
FROM j2, json_tree(j2.json) AS jx
|
||||
WHERE jx.json<>j2.json;
|
||||
} {}
|
||||
do_execsql_test json-5.7 {
|
||||
do_execsql_test json101-5.7 {
|
||||
SELECT j2.rowid, jx.rowid, fullkey, path, key
|
||||
FROM j2, json_each(j2.json) AS jx
|
||||
WHERE jx.value<>jx.atom AND type NOT IN ('array','object');
|
||||
} {}
|
||||
do_execsql_test json-5.8 {
|
||||
do_execsql_test json101-5.8 {
|
||||
SELECT j2.rowid, jx.rowid, fullkey, path, key
|
||||
FROM j2, json_tree(j2.json) AS jx
|
||||
WHERE jx.value<>jx.atom AND type NOT IN ('array','object');
|
||||
} {}
|
||||
|
||||
do_execsql_test json-6.1 {
|
||||
do_execsql_test json101-6.1 {
|
||||
SELECT json_valid('{"a":55,"b":72,}');
|
||||
} {0}
|
||||
do_execsql_test json-6.2 {
|
||||
do_execsql_test json101-6.2 {
|
||||
SELECT json_error_position('{"a":55,"b":72,}');
|
||||
} {0}
|
||||
do_execsql_test json-6.3 {
|
||||
do_execsql_test json101-6.3 {
|
||||
SELECT json_valid(json('{"a":55,"b":72,}'));
|
||||
} {1}
|
||||
do_execsql_test json-6.4 {
|
||||
do_execsql_test json101-6.4 {
|
||||
SELECT json_valid('{"a":55,"b":72 , }');
|
||||
} {0}
|
||||
do_execsql_test json-6.5 {
|
||||
do_execsql_test json101-6.5 {
|
||||
SELECT json_error_position('{"a":55,"b":72 , }');
|
||||
} {0}
|
||||
do_execsql_test json-6.6 {
|
||||
do_execsql_test json101-6.6 {
|
||||
SELECT json_error_position('{"a":55,"b":72,,}');
|
||||
} {16}
|
||||
do_execsql_test json-6.7 {
|
||||
do_execsql_test json101-6.7 {
|
||||
SELECT json_valid('{"a":55,"b":72}');
|
||||
} {1}
|
||||
do_execsql_test json-6.8 {
|
||||
do_execsql_test json101-6.8 {
|
||||
SELECT json_error_position('["a",55,"b",72,]');
|
||||
} {0}
|
||||
do_execsql_test json-6.9 {
|
||||
do_execsql_test json101-6.9 {
|
||||
SELECT json_error_position('["a",55,"b",72 , ]');
|
||||
} {0}
|
||||
do_execsql_test json-6.10 {
|
||||
do_execsql_test json101-6.10 {
|
||||
SELECT json_error_position('["a",55,"b",72,,]');
|
||||
} {16}
|
||||
do_execsql_test json-6.11 {
|
||||
do_execsql_test json101-6.11 {
|
||||
SELECT json_valid('["a",55,"b",72]');
|
||||
} {1}
|
||||
|
||||
@@ -352,7 +352,7 @@ foreach {tn isvalid ws} {
|
||||
7.6 1 char(0x20,0x09,0x0a,0x0d,0x20)
|
||||
7.7 0 char(0x20,0x09,0x0a,0x0c,0x0d,0x20)
|
||||
} {
|
||||
do_execsql_test json-$tn.1 \
|
||||
do_execsql_test json101-$tn.1 \
|
||||
"SELECT json_valid(printf('%s{%s\"x\"%s:%s9%s}%s',
|
||||
$::ws,$::ws,$::ws,$::ws,$::ws,$::ws));" \
|
||||
$isvalid
|
||||
@@ -361,23 +361,23 @@ foreach {tn isvalid ws} {
|
||||
# Ticket https://www.sqlite.org/src/info/ad2559db380abf8e
|
||||
# Control characters must be escaped in JSON strings.
|
||||
#
|
||||
do_execsql_test json-8.1 {
|
||||
do_execsql_test json101-8.1 {
|
||||
DROP TABLE IF EXISTS t8;
|
||||
CREATE TABLE t8(a,b);
|
||||
INSERT INTO t8(a) VALUES('abc' || char(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35) || 'xyz');
|
||||
UPDATE t8 SET b=json_array(a);
|
||||
SELECT b FROM t8;
|
||||
} {{["abc\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#xyz"]}}
|
||||
do_execsql_test json-8.2 {
|
||||
do_execsql_test json101-8.2 {
|
||||
SELECT a=json_extract(b,'$[0]') FROM t8;
|
||||
} {1}
|
||||
|
||||
# 2017-04-12. Regression reported on the mailing list by Rolf Ade
|
||||
#
|
||||
do_execsql_test json-8.3 {
|
||||
do_execsql_test json101-8.3 {
|
||||
SELECT json_valid(char(0x22,0xe4,0x22));
|
||||
} {1}
|
||||
do_execsql_test json-8.4 {
|
||||
do_execsql_test json101-8.4 {
|
||||
SELECT unicode(json_extract(char(0x22,228,0x22),'$'));
|
||||
} {228}
|
||||
|
||||
@@ -385,331 +385,331 @@ do_execsql_test json-8.4 {
|
||||
# String values are quoted and interior quotes are escaped. NULL values
|
||||
# are rendered as the unquoted string "null".
|
||||
#
|
||||
do_execsql_test json-9.1 {
|
||||
do_execsql_test json101-9.1 {
|
||||
SELECT json_quote('abc"xyz');
|
||||
} {{"abc\"xyz"}}
|
||||
do_execsql_test json-9.2 {
|
||||
do_execsql_test json101-9.2 {
|
||||
SELECT json_quote(3.14159);
|
||||
} {3.14159}
|
||||
do_execsql_test json-9.3 {
|
||||
do_execsql_test json101-9.3 {
|
||||
SELECT json_quote(12345);
|
||||
} {12345}
|
||||
do_execsql_test json-9.4 {
|
||||
do_execsql_test json101-9.4 {
|
||||
SELECT json_quote(null);
|
||||
} {"null"}
|
||||
do_catchsql_test json-9.5 {
|
||||
do_catchsql_test json101-9.5 {
|
||||
SELECT json_quote(x'30313233');
|
||||
} {1 {JSON cannot hold BLOB values}}
|
||||
do_catchsql_test json-9.6 {
|
||||
do_catchsql_test json101-9.6 {
|
||||
SELECT json_quote(123,456)
|
||||
} {1 {wrong number of arguments to function json_quote()}}
|
||||
do_catchsql_test json-9.7 {
|
||||
do_catchsql_test json101-9.7 {
|
||||
SELECT json_quote()
|
||||
} {1 {wrong number of arguments to function json_quote()}}
|
||||
|
||||
# Make sure only valid backslash-escapes are accepted.
|
||||
#
|
||||
do_execsql_test json-10.1 {
|
||||
do_execsql_test json101-10.1 {
|
||||
SELECT json_valid('" \ "');
|
||||
} {0}
|
||||
do_execsql_test json-10.2 {
|
||||
do_execsql_test json101-10.2 {
|
||||
SELECT json_valid('" \! "');
|
||||
} {0}
|
||||
do_execsql_test json-10.3 {
|
||||
do_execsql_test json101-10.3 {
|
||||
SELECT json_valid('" \" "');
|
||||
} {1}
|
||||
do_execsql_test json-10.4 {
|
||||
do_execsql_test json101-10.4 {
|
||||
SELECT json_valid('" \# "');
|
||||
} {0}
|
||||
do_execsql_test json-10.5 {
|
||||
do_execsql_test json101-10.5 {
|
||||
SELECT json_valid('" \$ "');
|
||||
} {0}
|
||||
do_execsql_test json-10.6 {
|
||||
do_execsql_test json101-10.6 {
|
||||
SELECT json_valid('" \% "');
|
||||
} {0}
|
||||
do_execsql_test json-10.7 {
|
||||
do_execsql_test json101-10.7 {
|
||||
SELECT json_valid('" \& "');
|
||||
} {0}
|
||||
do_execsql_test json-10.8 {
|
||||
do_execsql_test json101-10.8 {
|
||||
SELECT json_valid('" \'' "');
|
||||
} {0}
|
||||
do_execsql_test json-10.9 {
|
||||
do_execsql_test json101-10.9 {
|
||||
SELECT json_valid('" \( "');
|
||||
} {0}
|
||||
do_execsql_test json-10.10 {
|
||||
do_execsql_test json101-10.10 {
|
||||
SELECT json_valid('" \) "');
|
||||
} {0}
|
||||
do_execsql_test json-10.11 {
|
||||
do_execsql_test json101-10.11 {
|
||||
SELECT json_valid('" \* "');
|
||||
} {0}
|
||||
do_execsql_test json-10.12 {
|
||||
do_execsql_test json101-10.12 {
|
||||
SELECT json_valid('" \+ "');
|
||||
} {0}
|
||||
do_execsql_test json-10.13 {
|
||||
do_execsql_test json101-10.13 {
|
||||
SELECT json_valid('" \, "');
|
||||
} {0}
|
||||
do_execsql_test json-10.14 {
|
||||
do_execsql_test json101-10.14 {
|
||||
SELECT json_valid('" \- "');
|
||||
} {0}
|
||||
do_execsql_test json-10.15 {
|
||||
do_execsql_test json101-10.15 {
|
||||
SELECT json_valid('" \. "');
|
||||
} {0}
|
||||
do_execsql_test json-10.16 {
|
||||
do_execsql_test json101-10.16 {
|
||||
SELECT json_valid('" \/ "');
|
||||
} {1}
|
||||
do_execsql_test json-10.17 {
|
||||
do_execsql_test json101-10.17 {
|
||||
SELECT json_valid('" \0 "');
|
||||
} {0}
|
||||
do_execsql_test json-10.18 {
|
||||
do_execsql_test json101-10.18 {
|
||||
SELECT json_valid('" \1 "');
|
||||
} {0}
|
||||
do_execsql_test json-10.19 {
|
||||
do_execsql_test json101-10.19 {
|
||||
SELECT json_valid('" \2 "');
|
||||
} {0}
|
||||
do_execsql_test json-10.20 {
|
||||
do_execsql_test json101-10.20 {
|
||||
SELECT json_valid('" \3 "');
|
||||
} {0}
|
||||
do_execsql_test json-10.21 {
|
||||
do_execsql_test json101-10.21 {
|
||||
SELECT json_valid('" \4 "');
|
||||
} {0}
|
||||
do_execsql_test json-10.22 {
|
||||
do_execsql_test json101-10.22 {
|
||||
SELECT json_valid('" \5 "');
|
||||
} {0}
|
||||
do_execsql_test json-10.23 {
|
||||
do_execsql_test json101-10.23 {
|
||||
SELECT json_valid('" \6 "');
|
||||
} {0}
|
||||
do_execsql_test json-10.24 {
|
||||
do_execsql_test json101-10.24 {
|
||||
SELECT json_valid('" \7 "');
|
||||
} {0}
|
||||
do_execsql_test json-10.25 {
|
||||
do_execsql_test json101-10.25 {
|
||||
SELECT json_valid('" \8 "');
|
||||
} {0}
|
||||
do_execsql_test json-10.26 {
|
||||
do_execsql_test json101-10.26 {
|
||||
SELECT json_valid('" \9 "');
|
||||
} {0}
|
||||
do_execsql_test json-10.27 {
|
||||
do_execsql_test json101-10.27 {
|
||||
SELECT json_valid('" \: "');
|
||||
} {0}
|
||||
do_execsql_test json-10.28 {
|
||||
do_execsql_test json101-10.28 {
|
||||
SELECT json_valid('" \; "');
|
||||
} {0}
|
||||
do_execsql_test json-10.29 {
|
||||
do_execsql_test json101-10.29 {
|
||||
SELECT json_valid('" \< "');
|
||||
} {0}
|
||||
do_execsql_test json-10.30 {
|
||||
do_execsql_test json101-10.30 {
|
||||
SELECT json_valid('" \= "');
|
||||
} {0}
|
||||
do_execsql_test json-10.31 {
|
||||
do_execsql_test json101-10.31 {
|
||||
SELECT json_valid('" \> "');
|
||||
} {0}
|
||||
do_execsql_test json-10.32 {
|
||||
do_execsql_test json101-10.32 {
|
||||
SELECT json_valid('" \? "');
|
||||
} {0}
|
||||
do_execsql_test json-10.33 {
|
||||
do_execsql_test json101-10.33 {
|
||||
SELECT json_valid('" \@ "');
|
||||
} {0}
|
||||
do_execsql_test json-10.34 {
|
||||
do_execsql_test json101-10.34 {
|
||||
SELECT json_valid('" \A "');
|
||||
} {0}
|
||||
do_execsql_test json-10.35 {
|
||||
do_execsql_test json101-10.35 {
|
||||
SELECT json_valid('" \B "');
|
||||
} {0}
|
||||
do_execsql_test json-10.36 {
|
||||
do_execsql_test json101-10.36 {
|
||||
SELECT json_valid('" \C "');
|
||||
} {0}
|
||||
do_execsql_test json-10.37 {
|
||||
do_execsql_test json101-10.37 {
|
||||
SELECT json_valid('" \D "');
|
||||
} {0}
|
||||
do_execsql_test json-10.38 {
|
||||
do_execsql_test json101-10.38 {
|
||||
SELECT json_valid('" \E "');
|
||||
} {0}
|
||||
do_execsql_test json-10.39 {
|
||||
do_execsql_test json101-10.39 {
|
||||
SELECT json_valid('" \F "');
|
||||
} {0}
|
||||
do_execsql_test json-10.40 {
|
||||
do_execsql_test json101-10.40 {
|
||||
SELECT json_valid('" \G "');
|
||||
} {0}
|
||||
do_execsql_test json-10.41 {
|
||||
do_execsql_test json101-10.41 {
|
||||
SELECT json_valid('" \H "');
|
||||
} {0}
|
||||
do_execsql_test json-10.42 {
|
||||
do_execsql_test json101-10.42 {
|
||||
SELECT json_valid('" \I "');
|
||||
} {0}
|
||||
do_execsql_test json-10.43 {
|
||||
do_execsql_test json101-10.43 {
|
||||
SELECT json_valid('" \J "');
|
||||
} {0}
|
||||
do_execsql_test json-10.44 {
|
||||
do_execsql_test json101-10.44 {
|
||||
SELECT json_valid('" \K "');
|
||||
} {0}
|
||||
do_execsql_test json-10.45 {
|
||||
do_execsql_test json101-10.45 {
|
||||
SELECT json_valid('" \L "');
|
||||
} {0}
|
||||
do_execsql_test json-10.46 {
|
||||
do_execsql_test json101-10.46 {
|
||||
SELECT json_valid('" \M "');
|
||||
} {0}
|
||||
do_execsql_test json-10.47 {
|
||||
do_execsql_test json101-10.47 {
|
||||
SELECT json_valid('" \N "');
|
||||
} {0}
|
||||
do_execsql_test json-10.48 {
|
||||
do_execsql_test json101-10.48 {
|
||||
SELECT json_valid('" \O "');
|
||||
} {0}
|
||||
do_execsql_test json-10.49 {
|
||||
do_execsql_test json101-10.49 {
|
||||
SELECT json_valid('" \P "');
|
||||
} {0}
|
||||
do_execsql_test json-10.50 {
|
||||
do_execsql_test json101-10.50 {
|
||||
SELECT json_valid('" \Q "');
|
||||
} {0}
|
||||
do_execsql_test json-10.51 {
|
||||
do_execsql_test json101-10.51 {
|
||||
SELECT json_valid('" \R "');
|
||||
} {0}
|
||||
do_execsql_test json-10.52 {
|
||||
do_execsql_test json101-10.52 {
|
||||
SELECT json_valid('" \S "');
|
||||
} {0}
|
||||
do_execsql_test json-10.53 {
|
||||
do_execsql_test json101-10.53 {
|
||||
SELECT json_valid('" \T "');
|
||||
} {0}
|
||||
do_execsql_test json-10.54 {
|
||||
do_execsql_test json101-10.54 {
|
||||
SELECT json_valid('" \U "');
|
||||
} {0}
|
||||
do_execsql_test json-10.55 {
|
||||
do_execsql_test json101-10.55 {
|
||||
SELECT json_valid('" \V "');
|
||||
} {0}
|
||||
do_execsql_test json-10.56 {
|
||||
do_execsql_test json101-10.56 {
|
||||
SELECT json_valid('" \W "');
|
||||
} {0}
|
||||
do_execsql_test json-10.57 {
|
||||
do_execsql_test json101-10.57 {
|
||||
SELECT json_valid('" \X "');
|
||||
} {0}
|
||||
do_execsql_test json-10.58 {
|
||||
do_execsql_test json101-10.58 {
|
||||
SELECT json_valid('" \Y "');
|
||||
} {0}
|
||||
do_execsql_test json-10.59 {
|
||||
do_execsql_test json101-10.59 {
|
||||
SELECT json_valid('" \Z "');
|
||||
} {0}
|
||||
do_execsql_test json-10.60 {
|
||||
do_execsql_test json101-10.60 {
|
||||
SELECT json_valid('" \[ "');
|
||||
} {0}
|
||||
do_execsql_test json-10.61 {
|
||||
do_execsql_test json101-10.61 {
|
||||
SELECT json_valid('" \\ "');
|
||||
} {1}
|
||||
do_execsql_test json-10.62 {
|
||||
do_execsql_test json101-10.62 {
|
||||
SELECT json_valid('" \] "');
|
||||
} {0}
|
||||
do_execsql_test json-10.63 {
|
||||
do_execsql_test json101-10.63 {
|
||||
SELECT json_valid('" \^ "');
|
||||
} {0}
|
||||
do_execsql_test json-10.64 {
|
||||
do_execsql_test json101-10.64 {
|
||||
SELECT json_valid('" \_ "');
|
||||
} {0}
|
||||
do_execsql_test json-10.65 {
|
||||
do_execsql_test json101-10.65 {
|
||||
SELECT json_valid('" \` "');
|
||||
} {0}
|
||||
do_execsql_test json-10.66 {
|
||||
do_execsql_test json101-10.66 {
|
||||
SELECT json_valid('" \a "');
|
||||
} {0}
|
||||
do_execsql_test json-10.67 {
|
||||
do_execsql_test json101-10.67 {
|
||||
SELECT json_valid('" \b "');
|
||||
} {1}
|
||||
do_execsql_test json-10.68 {
|
||||
do_execsql_test json101-10.68 {
|
||||
SELECT json_valid('" \c "');
|
||||
} {0}
|
||||
do_execsql_test json-10.69 {
|
||||
do_execsql_test json101-10.69 {
|
||||
SELECT json_valid('" \d "');
|
||||
} {0}
|
||||
do_execsql_test json-10.70 {
|
||||
do_execsql_test json101-10.70 {
|
||||
SELECT json_valid('" \e "');
|
||||
} {0}
|
||||
do_execsql_test json-10.71 {
|
||||
do_execsql_test json101-10.71 {
|
||||
SELECT json_valid('" \f "');
|
||||
} {1}
|
||||
do_execsql_test json-10.72 {
|
||||
do_execsql_test json101-10.72 {
|
||||
SELECT json_valid('" \g "');
|
||||
} {0}
|
||||
do_execsql_test json-10.73 {
|
||||
do_execsql_test json101-10.73 {
|
||||
SELECT json_valid('" \h "');
|
||||
} {0}
|
||||
do_execsql_test json-10.74 {
|
||||
do_execsql_test json101-10.74 {
|
||||
SELECT json_valid('" \i "');
|
||||
} {0}
|
||||
do_execsql_test json-10.75 {
|
||||
do_execsql_test json101-10.75 {
|
||||
SELECT json_valid('" \j "');
|
||||
} {0}
|
||||
do_execsql_test json-10.76 {
|
||||
do_execsql_test json101-10.76 {
|
||||
SELECT json_valid('" \k "');
|
||||
} {0}
|
||||
do_execsql_test json-10.77 {
|
||||
do_execsql_test json101-10.77 {
|
||||
SELECT json_valid('" \l "');
|
||||
} {0}
|
||||
do_execsql_test json-10.78 {
|
||||
do_execsql_test json101-10.78 {
|
||||
SELECT json_valid('" \m "');
|
||||
} {0}
|
||||
do_execsql_test json-10.79 {
|
||||
do_execsql_test json101-10.79 {
|
||||
SELECT json_valid('" \n "');
|
||||
} {1}
|
||||
do_execsql_test json-10.80 {
|
||||
do_execsql_test json101-10.80 {
|
||||
SELECT json_valid('" \o "');
|
||||
} {0}
|
||||
do_execsql_test json-10.81 {
|
||||
do_execsql_test json101-10.81 {
|
||||
SELECT json_valid('" \p "');
|
||||
} {0}
|
||||
do_execsql_test json-10.82 {
|
||||
do_execsql_test json101-10.82 {
|
||||
SELECT json_valid('" \q "');
|
||||
} {0}
|
||||
do_execsql_test json-10.83 {
|
||||
do_execsql_test json101-10.83 {
|
||||
SELECT json_valid('" \r "');
|
||||
} {1}
|
||||
do_execsql_test json-10.84 {
|
||||
do_execsql_test json101-10.84 {
|
||||
SELECT json_valid('" \s "');
|
||||
} {0}
|
||||
do_execsql_test json-10.85 {
|
||||
do_execsql_test json101-10.85 {
|
||||
SELECT json_valid('" \t "');
|
||||
} {1}
|
||||
do_execsql_test json-10.86.0 {
|
||||
do_execsql_test json101-10.86.0 {
|
||||
SELECT json_valid('" \u "');
|
||||
} {0}
|
||||
do_execsql_test json-10.86.1 {
|
||||
do_execsql_test json101-10.86.1 {
|
||||
SELECT json_valid('" \ua "');
|
||||
} {0}
|
||||
do_execsql_test json-10.86.2 {
|
||||
do_execsql_test json101-10.86.2 {
|
||||
SELECT json_valid('" \uab "');
|
||||
} {0}
|
||||
do_execsql_test json-10.86.3 {
|
||||
do_execsql_test json101-10.86.3 {
|
||||
SELECT json_valid('" \uabc "');
|
||||
} {0}
|
||||
do_execsql_test json-10.86.4 {
|
||||
do_execsql_test json101-10.86.4 {
|
||||
SELECT json_valid('" \uabcd "');
|
||||
} {1}
|
||||
do_execsql_test json-10.86.5 {
|
||||
do_execsql_test json101-10.86.5 {
|
||||
SELECT json_valid('" \uFEDC "');
|
||||
} {1}
|
||||
do_execsql_test json-10.86.6 {
|
||||
do_execsql_test json101-10.86.6 {
|
||||
SELECT json_valid('" \u1234 "');
|
||||
} {1}
|
||||
do_execsql_test json-10.87 {
|
||||
do_execsql_test json101-10.87 {
|
||||
SELECT json_valid('" \v "');
|
||||
} {0}
|
||||
do_execsql_test json-10.88 {
|
||||
do_execsql_test json101-10.88 {
|
||||
SELECT json_valid('" \w "');
|
||||
} {0}
|
||||
do_execsql_test json-10.89 {
|
||||
do_execsql_test json101-10.89 {
|
||||
SELECT json_valid('" \x "');
|
||||
} {0}
|
||||
do_execsql_test json-10.90 {
|
||||
do_execsql_test json101-10.90 {
|
||||
SELECT json_valid('" \y "');
|
||||
} {0}
|
||||
do_execsql_test json-10.91 {
|
||||
do_execsql_test json101-10.91 {
|
||||
SELECT json_valid('" \z "');
|
||||
} {0}
|
||||
do_execsql_test json-10.92 {
|
||||
do_execsql_test json101-10.92 {
|
||||
SELECT json_valid('" \{ "');
|
||||
} {0}
|
||||
do_execsql_test json-10.93 {
|
||||
do_execsql_test json101-10.93 {
|
||||
SELECT json_valid('" \| "');
|
||||
} {0}
|
||||
do_execsql_test json-10.94 {
|
||||
do_execsql_test json101-10.94 {
|
||||
SELECT json_valid('" \} "');
|
||||
} {0}
|
||||
do_execsql_test json-10.95 {
|
||||
do_execsql_test json101-10.95 {
|
||||
SELECT json_valid('" \~ "');
|
||||
} {0}
|
||||
|
||||
@@ -719,20 +719,20 @@ do_execsql_test json-10.95 {
|
||||
#
|
||||
# The following tests confirm that deeply nested JSON is considered invalid.
|
||||
#
|
||||
do_execsql_test json-11.0 {
|
||||
do_execsql_test json101-11.0 {
|
||||
/* Shallow enough to be parsed */
|
||||
SELECT json_valid(printf('%.1000c0%.1000c','[',']'));
|
||||
} {1}
|
||||
do_execsql_test json-11.1 {
|
||||
do_execsql_test json101-11.1 {
|
||||
/* Too deep by one */
|
||||
SELECT json_valid(printf('%.1001c0%.1001c','[',']'));
|
||||
} {0}
|
||||
do_execsql_test json-11.2 {
|
||||
do_execsql_test json101-11.2 {
|
||||
/* Shallow enough to be parsed { */
|
||||
SELECT json_valid(replace(printf('%.1000c0%.1000c','[','}'),'[','{"a":'));
|
||||
/* } */
|
||||
} {1}
|
||||
do_execsql_test json-11.3 {
|
||||
do_execsql_test json101-11.3 {
|
||||
/* Too deep by one { */
|
||||
SELECT json_valid(replace(printf('%.1001c0%.1001c','[','}'),'[','{"a":'));
|
||||
/* } */
|
||||
@@ -742,7 +742,7 @@ do_execsql_test json-11.3 {
|
||||
# a json structure even though the element name constains a "."
|
||||
# character, by quoting the element name in the path.
|
||||
#
|
||||
do_execsql_test json-12.100 {
|
||||
do_execsql_test json101-12.100 {
|
||||
CREATE TABLE t12(x);
|
||||
INSERT INTO t12(x) VALUES(
|
||||
'{"settings":
|
||||
@@ -766,11 +766,11 @@ do_execsql_test json-12.100 {
|
||||
}
|
||||
}');
|
||||
} {}
|
||||
do_execsql_test json-12.110 {
|
||||
do_execsql_test json101-12.110 {
|
||||
SELECT json_remove(x, '$.settings.layer2."dis.legomenon".forceDisplay')
|
||||
FROM t12;
|
||||
} {{{"settings":{"layer2":{"hapax.legomenon":{"forceDisplay":true,"transliterate":true,"add.footnote":true,"summary.report":true},"dis.legomenon":{"transliterate":false,"add.footnote":false,"summary.report":true},"tris.legomenon":{"forceDisplay":true,"transliterate":false,"add.footnote":false,"summary.report":false}}}}}}
|
||||
do_execsql_test json-12.120 {
|
||||
do_execsql_test json101-12.120 {
|
||||
SELECT json_extract(x, '$.settings.layer2."tris.legomenon"."summary.report"')
|
||||
FROM t12;
|
||||
} {0}
|
||||
@@ -779,7 +779,7 @@ do_execsql_test json-12.120 {
|
||||
# ticket https://www.sqlite.org/src/tktview/80177f0c226ff54f6ddd41
|
||||
# Make sure the query planner knows about the arguments to table-valued functions.
|
||||
#
|
||||
do_execsql_test json-13.100 {
|
||||
do_execsql_test json101-13.100 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP TABLE IF EXISTS t2;
|
||||
CREATE TABLE t1(id, json);
|
||||
@@ -794,7 +794,7 @@ do_execsql_test json-13.100 {
|
||||
WHERE EXISTS(SELECT 1 FROM json_each(t1.json,'$.items') AS Z
|
||||
WHERE Z.value==t2.id);
|
||||
} {1 {{"items":[3,5]}} 3 {{"value":3}} 1 {{"items":[3,5]}} 5 {{"value":5}}}
|
||||
do_execsql_test json-13.110 {
|
||||
do_execsql_test json101-13.110 {
|
||||
SELECT * FROM t2 CROSS JOIN t1
|
||||
WHERE EXISTS(SELECT 1 FROM json_each(t1.json,'$.items') AS Z
|
||||
WHERE Z.value==t2.id);
|
||||
@@ -804,28 +804,28 @@ do_execsql_test json-13.110 {
|
||||
# Incorrect fullkey output from json_each()
|
||||
# when the input JSON is not an array or object.
|
||||
#
|
||||
do_execsql_test json-14.100 {
|
||||
do_execsql_test json101-14.100 {
|
||||
SELECT fullkey FROM json_each('123');
|
||||
} {$}
|
||||
do_execsql_test json-14.110 {
|
||||
do_execsql_test json101-14.110 {
|
||||
SELECT fullkey FROM json_each('123.56');
|
||||
} {$}
|
||||
do_execsql_test json-14.120 {
|
||||
do_execsql_test json101-14.120 {
|
||||
SELECT fullkey FROM json_each('"hello"');
|
||||
} {$}
|
||||
do_execsql_test json-14.130 {
|
||||
do_execsql_test json101-14.130 {
|
||||
SELECT fullkey FROM json_each('null');
|
||||
} {$}
|
||||
do_execsql_test json-14.140 {
|
||||
do_execsql_test json101-14.140 {
|
||||
SELECT fullkey FROM json_tree('123');
|
||||
} {$}
|
||||
do_execsql_test json-14.150 {
|
||||
do_execsql_test json101-14.150 {
|
||||
SELECT fullkey FROM json_tree('123.56');
|
||||
} {$}
|
||||
do_execsql_test json-14.160 {
|
||||
do_execsql_test json101-14.160 {
|
||||
SELECT fullkey FROM json_tree('"hello"');
|
||||
} {$}
|
||||
do_execsql_test json-14.170 {
|
||||
do_execsql_test json101-14.170 {
|
||||
SELECT fullkey FROM json_tree('null');
|
||||
} {$}
|
||||
|
||||
@@ -835,16 +835,16 @@ do_execsql_test json-14.170 {
|
||||
#
|
||||
# Bug reported via private email. See TH3 for more information.
|
||||
#
|
||||
do_execsql_test json-15.100 {
|
||||
do_execsql_test json101-15.100 {
|
||||
SELECT * FROM JSON_EACH('{"a":1, "b":2}');
|
||||
} {a 1 integer 1 2 {} {$.a} {$} b 2 integer 2 4 {} {$.b} {$}}
|
||||
do_execsql_test json-15.110 {
|
||||
do_execsql_test json101-15.110 {
|
||||
SELECT xyz.* FROM JSON_EACH('{"a":1, "b":2}') AS xyz;
|
||||
} {a 1 integer 1 2 {} {$.a} {$} b 2 integer 2 4 {} {$.b} {$}}
|
||||
do_execsql_test json-15.120 {
|
||||
do_execsql_test json101-15.120 {
|
||||
SELECT * FROM (JSON_EACH('{"a":1, "b":2}'));
|
||||
} {a 1 integer 1 2 {} {$.a} {$} b 2 integer 2 4 {} {$.b} {$}}
|
||||
do_execsql_test json-15.130 {
|
||||
do_execsql_test json101-15.130 {
|
||||
SELECT xyz.* FROM (JSON_EACH('{"a":1, "b":2}')) AS xyz;
|
||||
} {a 1 integer 1 2 {} {$.a} {$} b 2 integer 2 4 {} {$.b} {$}}
|
||||
|
||||
@@ -852,18 +852,18 @@ do_execsql_test json-15.130 {
|
||||
# Mailing list bug report on the handling of surrogate pairs
|
||||
# in JSON.
|
||||
#
|
||||
do_execsql_test json-16.10 {
|
||||
do_execsql_test json101-16.10 {
|
||||
SELECT length(json_extract('"abc\uD834\uDD1Exyz"','$'));
|
||||
} {7}
|
||||
do_execsql_test json-16.20 {
|
||||
do_execsql_test json101-16.20 {
|
||||
SELECT length(json_extract('"\uD834\uDD1E"','$'));
|
||||
} {1}
|
||||
do_execsql_test json-16.30 {
|
||||
do_execsql_test json101-16.30 {
|
||||
SELECT unicode(json_extract('"\uD834\uDD1E"','$'));
|
||||
} {119070}
|
||||
|
||||
# 2022-01-30 dbsqlfuzz 4678cf825d27f87c9b8343720121e12cf944b71a
|
||||
do_execsql_test json-17.1 {
|
||||
do_execsql_test json101-17.1 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP TABLE IF EXISTS t2;
|
||||
CREATE TABLE t1(a,b,c);
|
||||
@@ -872,19 +872,19 @@ do_execsql_test json-17.1 {
|
||||
} {}
|
||||
|
||||
# 2022-04-04 forum post https://sqlite.org/forum/forumpost/c082aeab43
|
||||
do_execsql_test json-18.1 {
|
||||
do_execsql_test json101-18.1 {
|
||||
SELECT json_valid('{"":5}');
|
||||
} {1}
|
||||
do_execsql_test json-18.2 {
|
||||
do_execsql_test json101-18.2 {
|
||||
SELECT json_extract('{"":5}', '$.""');
|
||||
} {5}
|
||||
do_execsql_test json-18.3 {
|
||||
do_execsql_test json101-18.3 {
|
||||
SELECT json_extract('[3,{"a":4,"":[5,{"hi":6},7]},8]', '$[1].""[1].hi');
|
||||
} {6}
|
||||
do_execsql_test json-18.4 {
|
||||
do_execsql_test json101-18.4 {
|
||||
SELECT json_extract('[3,{"a":4,"":[5,{"hi":6},7]},8]', '$[1].""[1]."hi"');
|
||||
} {6}
|
||||
do_catchsql_test json-18.5 {
|
||||
do_catchsql_test json101-18.5 {
|
||||
SELECT json_extract('{"":8}', '$.');
|
||||
} {1 {JSON path error near ''}}
|
||||
|
||||
@@ -893,28 +893,28 @@ do_catchsql_test json-18.5 {
|
||||
# a problem with transaction control. But the json() function makes
|
||||
# the problem more easily accessible, so it is tested here.
|
||||
#
|
||||
do_execsql_test json-19.1 {
|
||||
do_execsql_test json101-19.1 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(x);
|
||||
} {}
|
||||
do_catchsql_test json-19.2 {
|
||||
do_catchsql_test json101-19.2 {
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES(0), (json('not-valid-json'));
|
||||
} {1 {malformed JSON}}
|
||||
do_execsql_test json-19.3 {
|
||||
do_execsql_test json101-19.3 {
|
||||
COMMIT;
|
||||
SELECT * FROM t1;
|
||||
} {}
|
||||
|
||||
# 2023-03-17 positive and negative infinities
|
||||
#
|
||||
do_execsql_test json-20.1 {
|
||||
do_execsql_test json101-20.1 {
|
||||
SELECT json_object('a',2e370,'b',-3e380);
|
||||
} {{{"a":9.0e+999,"b":-9.0e+999}}}
|
||||
do_execsql_test json-20.2 {
|
||||
do_execsql_test json101-20.2 {
|
||||
SELECT json_object('a',2e370,'b',-3e380)->>'a';
|
||||
} Inf
|
||||
do_execsql_test json-20.3 {
|
||||
do_execsql_test json101-20.3 {
|
||||
SELECT json_object('a',2e370,'b',-3e380)->>'b';
|
||||
} {-Inf}
|
||||
|
||||
@@ -924,91 +924,91 @@ do_execsql_test json-20.3 {
|
||||
#
|
||||
db null NULL
|
||||
if {[db exists {SELECT * FROM pragma_compile_options WHERE compile_options LIKE '%legacy_json_valid%'}]} {
|
||||
do_execsql_test json-21.1-legacy {
|
||||
do_execsql_test json101-21.1-legacy {
|
||||
SELECT json_valid(NULL);
|
||||
} 0
|
||||
} else {
|
||||
do_execsql_test json-21.1-correct {
|
||||
do_execsql_test json101-21.1-correct {
|
||||
SELECT json_valid(NULL);
|
||||
} NULL
|
||||
}
|
||||
do_execsql_test json-21.2 {
|
||||
do_execsql_test json101-21.2 {
|
||||
SELECT json_error_position(NULL);
|
||||
} NULL
|
||||
do_execsql_test json-21.3 {
|
||||
do_execsql_test json101-21.3 {
|
||||
SELECT json(NULL);
|
||||
} NULL
|
||||
do_execsql_test json-21.4 {
|
||||
do_execsql_test json101-21.4 {
|
||||
SELECT json_array(NULL);
|
||||
} {[null]}
|
||||
do_execsql_test json-21.5 {
|
||||
do_execsql_test json101-21.5 {
|
||||
SELECT json_extract(NULL);
|
||||
} NULL
|
||||
do_execsql_test json-21.6 {
|
||||
do_execsql_test json101-21.6 {
|
||||
SELECT json_insert(NULL,'$',123);
|
||||
} NULL
|
||||
do_execsql_test json-21.7 {
|
||||
do_execsql_test json101-21.7 {
|
||||
SELECT NULL->0;
|
||||
} NULL
|
||||
do_execsql_test json-21.8 {
|
||||
do_execsql_test json101-21.8 {
|
||||
SELECT NULL->>0;
|
||||
} NULL
|
||||
do_execsql_test json-21.9 {
|
||||
do_execsql_test json101-21.9 {
|
||||
SELECT '{a:5}'->NULL;
|
||||
} NULL
|
||||
do_execsql_test json-21.10 {
|
||||
do_execsql_test json101-21.10 {
|
||||
SELECT '{a:5}'->>NULL;
|
||||
} NULL
|
||||
do_catchsql_test json-21.11 {
|
||||
do_catchsql_test json101-21.11 {
|
||||
SELECT json_object(NULL,5);
|
||||
} {1 {json_object() labels must be TEXT}}
|
||||
do_execsql_test json-21.12 {
|
||||
do_execsql_test json101-21.12 {
|
||||
SELECT json_patch(NULL,'{a:5}');
|
||||
} NULL
|
||||
do_execsql_test json-21.13 {
|
||||
do_execsql_test json101-21.13 {
|
||||
SELECT json_patch('{a:5}',NULL);
|
||||
} NULL
|
||||
do_execsql_test json-21.14 {
|
||||
do_execsql_test json101-21.14 {
|
||||
SELECT json_patch(NULL,NULL);
|
||||
} NULL
|
||||
do_execsql_test json-21.15 {
|
||||
do_execsql_test json101-21.15 {
|
||||
SELECT json_remove(NULL,'$');
|
||||
} NULL
|
||||
do_execsql_test json-21.16 {
|
||||
do_execsql_test json101-21.16 {
|
||||
SELECT json_remove('{a:5,b:7}',NULL);
|
||||
} NULL
|
||||
do_execsql_test json-21.17 {
|
||||
do_execsql_test json101-21.17 {
|
||||
SELECT json_replace(NULL,'$.a',123);
|
||||
} NULL
|
||||
do_execsql_test json-21.18 {
|
||||
do_execsql_test json101-21.18 {
|
||||
SELECT json_replace('{a:5,b:7}',NULL,NULL);
|
||||
} {{{"a":5,"b":7}}}
|
||||
do_execsql_test json-21.19 {
|
||||
do_execsql_test json101-21.19 {
|
||||
SELECT json_set(NULL,'$.a',123);
|
||||
} NULL
|
||||
do_execsql_test json-21.20 {
|
||||
do_execsql_test json101-21.20 {
|
||||
SELECT json_set('{a:5,b:7}',NULL,NULL);
|
||||
} {{{"a":5,"b":7}}}
|
||||
do_execsql_test json-21.21 {
|
||||
do_execsql_test json101-21.21 {
|
||||
SELECT json_type(NULL);
|
||||
} NULL
|
||||
do_execsql_test json-21.22 {
|
||||
do_execsql_test json101-21.22 {
|
||||
SELECT json_type('{a:5,b:7}',NULL);
|
||||
} NULL
|
||||
do_execsql_test json-21.23 {
|
||||
do_execsql_test json101-21.23 {
|
||||
SELECT json_quote(NULL);
|
||||
} null
|
||||
do_execsql_test json-21.24 {
|
||||
do_execsql_test json101-21.24 {
|
||||
SELECT count(*) FROM json_each(NULL);
|
||||
} 0
|
||||
do_execsql_test json-21.25 {
|
||||
do_execsql_test json101-21.25 {
|
||||
SELECT count(*) FROM json_tree(NULL);
|
||||
} 0
|
||||
do_execsql_test json-21.26 {
|
||||
do_execsql_test json101-21.26 {
|
||||
WITH c(x) AS (VALUES(1),(2.0),(NULL),('three'))
|
||||
SELECT json_group_array(x) FROM c;
|
||||
} {[1,2.0,null,"three"]}
|
||||
do_execsql_test json-21.27 {
|
||||
do_execsql_test json101-21.27 {
|
||||
WITH c(x,y) AS (VALUES('a',1),('b',2.0),('c',NULL),(NULL,'three'),('e','four'))
|
||||
SELECT json_group_object(x,y) FROM c;
|
||||
} {{{"a":1,"b":2.0,"c":null,:"three","e":"four"}}}
|
||||
|
@@ -1140,4 +1140,24 @@ do_execsql_test 17.1 {
|
||||
} {1}
|
||||
|
||||
|
||||
# 2023-08-15 https://sqlite.org/forum/forumpost/925dc9f67804c540
|
||||
#
|
||||
reset_db
|
||||
sqlite3_db_config db DEFENSIVE 1
|
||||
db eval {PRAGMA trusted_schema=OFF}
|
||||
do_execsql_test 18.0 {
|
||||
CREATE TABLE t1(x INT, y TEXT);
|
||||
INSERT INTO t1 VALUES(1,'abc'),(2,'ABC'),(3,'Abc');
|
||||
CREATE VIEW t2 AS SELECT * FROM t1 WHERE y LIKE 'a%';
|
||||
SELECT * FROM t2;
|
||||
} {1 abc 2 ABC 3 Abc}
|
||||
do_execsql_test 18.1 {
|
||||
PRAGMA case_sensitive_like=OFF;
|
||||
SELECT * FROM t2;
|
||||
} {1 abc 2 ABC 3 Abc}
|
||||
do_execsql_test 18.2 {
|
||||
PRAGMA case_sensitive_like=ON;
|
||||
SELECT * FROM t2;
|
||||
} {1 abc}
|
||||
|
||||
finish_test
|
||||
|
@@ -10,9 +10,11 @@
|
||||
#***********************************************************************
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
db close
|
||||
if {[info vars ::trd::tcltest]==""} {
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
db close
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# test_suite NAME OPTIONS
|
||||
@@ -832,117 +834,111 @@ test_suite "inmemory_journal" -description {
|
||||
recoverpgsz.test
|
||||
}]
|
||||
|
||||
ifcapable mem3 {
|
||||
test_suite "memsys3" -description {
|
||||
Run tests using the allocator in mem3.c.
|
||||
} -files [test_set $::allquicktests -exclude {
|
||||
autovacuum.test delete3.test manydb.test
|
||||
bigrow.test incrblob2.test memdb.test
|
||||
bitvec.test index2.test memsubsys1.test
|
||||
capi3c.test ioerr.test memsubsys2.test
|
||||
capi3.test join3.test pagesize.test
|
||||
collate5.test limit.test backup_ioerr.test
|
||||
backup_malloc.test
|
||||
}] -initialize {
|
||||
catch {db close}
|
||||
sqlite3_reset_auto_extension
|
||||
sqlite3_shutdown
|
||||
sqlite3_config_heap 25000000 0
|
||||
sqlite3_config_lookaside 0 0
|
||||
ifcapable mem5 {
|
||||
# If both memsys3 and memsys5 are enabled in the build, the call to
|
||||
# [sqlite3_config_heap] will initialize the system to use memsys5.
|
||||
# The following overrides this preference and installs the memsys3
|
||||
# allocator.
|
||||
sqlite3_install_memsys3
|
||||
}
|
||||
install_malloc_faultsim 1
|
||||
sqlite3_initialize
|
||||
autoinstall_test_functions
|
||||
} -shutdown {
|
||||
catch {db close}
|
||||
sqlite3_shutdown
|
||||
sqlite3_config_heap 0 0
|
||||
sqlite3_config_lookaside 100 500
|
||||
install_malloc_faultsim 1
|
||||
sqlite3_initialize
|
||||
autoinstall_test_functions
|
||||
test_suite "memsys3" -description {
|
||||
Run tests using the allocator in mem3.c.
|
||||
} -files [test_set $::allquicktests -exclude {
|
||||
autovacuum.test delete3.test manydb.test
|
||||
bigrow.test incrblob2.test memdb.test
|
||||
bitvec.test index2.test memsubsys1.test
|
||||
capi3c.test ioerr.test memsubsys2.test
|
||||
capi3.test join3.test pagesize.test
|
||||
collate5.test limit.test backup_ioerr.test
|
||||
backup_malloc.test
|
||||
}] -initialize {
|
||||
catch {db close}
|
||||
sqlite3_reset_auto_extension
|
||||
sqlite3_shutdown
|
||||
sqlite3_config_heap 25000000 0
|
||||
sqlite3_config_lookaside 0 0
|
||||
ifcapable mem5 {
|
||||
# If both memsys3 and memsys5 are enabled in the build, the call to
|
||||
# [sqlite3_config_heap] will initialize the system to use memsys5.
|
||||
# The following overrides this preference and installs the memsys3
|
||||
# allocator.
|
||||
sqlite3_install_memsys3
|
||||
}
|
||||
install_malloc_faultsim 1
|
||||
sqlite3_initialize
|
||||
autoinstall_test_functions
|
||||
} -shutdown {
|
||||
catch {db close}
|
||||
sqlite3_shutdown
|
||||
sqlite3_config_heap 0 0
|
||||
sqlite3_config_lookaside 100 500
|
||||
install_malloc_faultsim 1
|
||||
sqlite3_initialize
|
||||
autoinstall_test_functions
|
||||
}
|
||||
|
||||
ifcapable mem5 {
|
||||
test_suite "memsys5" -description {
|
||||
Run tests using the allocator in mem5.c.
|
||||
} -files [test_set $::allquicktests -exclude {
|
||||
autovacuum.test delete3.test manydb.test
|
||||
bigrow.test incrblob2.test memdb.test
|
||||
bitvec.test index2.test memsubsys1.test
|
||||
capi3c.test ioerr.test memsubsys2.test
|
||||
capi3.test join3.test pagesize.test
|
||||
collate5.test limit.test zeroblob.test
|
||||
}] -initialize {
|
||||
catch {db close}
|
||||
sqlite3_shutdown
|
||||
sqlite3_config_heap 25000000 64
|
||||
sqlite3_config_lookaside 0 0
|
||||
install_malloc_faultsim 1
|
||||
sqlite3_initialize
|
||||
autoinstall_test_functions
|
||||
} -shutdown {
|
||||
catch {db close}
|
||||
sqlite3_shutdown
|
||||
sqlite3_config_heap 0 0
|
||||
sqlite3_config_lookaside 100 500
|
||||
install_malloc_faultsim 1
|
||||
sqlite3_initialize
|
||||
autoinstall_test_functions
|
||||
}
|
||||
|
||||
test_suite "memsys5-2" -description {
|
||||
Run tests using the allocator in mem5.c in a different configuration.
|
||||
} -files {
|
||||
select1.test
|
||||
} -initialize {
|
||||
catch {db close}
|
||||
sqlite3_shutdown
|
||||
sqlite3_config_memstatus 0
|
||||
sqlite3_config_heap 40000000 16
|
||||
sqlite3_config_lookaside 0 0
|
||||
install_malloc_faultsim 1
|
||||
sqlite3_initialize
|
||||
autoinstall_test_functions
|
||||
} -shutdown {
|
||||
catch {db close}
|
||||
sqlite3_shutdown
|
||||
sqlite3_config_heap 0 0
|
||||
sqlite3_config_lookaside 100 500
|
||||
install_malloc_faultsim 1
|
||||
sqlite3_initialize
|
||||
autoinstall_test_functions
|
||||
}
|
||||
test_suite "memsys5" -description {
|
||||
Run tests using the allocator in mem5.c.
|
||||
} -files [test_set $::allquicktests -exclude {
|
||||
autovacuum.test delete3.test manydb.test
|
||||
bigrow.test incrblob2.test memdb.test
|
||||
bitvec.test index2.test memsubsys1.test
|
||||
capi3c.test ioerr.test memsubsys2.test
|
||||
capi3.test join3.test pagesize.test
|
||||
collate5.test limit.test zeroblob.test
|
||||
}] -initialize {
|
||||
catch {db close}
|
||||
sqlite3_shutdown
|
||||
sqlite3_config_heap 25000000 64
|
||||
sqlite3_config_lookaside 0 0
|
||||
install_malloc_faultsim 1
|
||||
sqlite3_initialize
|
||||
autoinstall_test_functions
|
||||
} -shutdown {
|
||||
catch {db close}
|
||||
sqlite3_shutdown
|
||||
sqlite3_config_heap 0 0
|
||||
sqlite3_config_lookaside 100 500
|
||||
install_malloc_faultsim 1
|
||||
sqlite3_initialize
|
||||
autoinstall_test_functions
|
||||
}
|
||||
|
||||
ifcapable threadsafe {
|
||||
test_suite "no_mutex_try" -description {
|
||||
The sqlite3_mutex_try() interface always fails
|
||||
} -files [
|
||||
test_set $::allquicktests -exclude mutex1.test mutex2.test
|
||||
] -initialize {
|
||||
catch {db close}
|
||||
sqlite3_shutdown
|
||||
install_mutex_counters 1
|
||||
set ::disable_mutex_try 1
|
||||
sqlite3_initialize
|
||||
autoinstall_test_functions
|
||||
} -shutdown {
|
||||
catch {db close}
|
||||
catch {db2 close}
|
||||
catch {db3 close}
|
||||
sqlite3_shutdown
|
||||
install_mutex_counters 0
|
||||
sqlite3_initialize
|
||||
autoinstall_test_functions
|
||||
}
|
||||
test_suite "memsys5-2" -description {
|
||||
Run tests using the allocator in mem5.c in a different configuration.
|
||||
} -files {
|
||||
select1.test
|
||||
} -initialize {
|
||||
catch {db close}
|
||||
sqlite3_shutdown
|
||||
sqlite3_config_memstatus 0
|
||||
sqlite3_config_heap 40000000 16
|
||||
sqlite3_config_lookaside 0 0
|
||||
install_malloc_faultsim 1
|
||||
sqlite3_initialize
|
||||
autoinstall_test_functions
|
||||
} -shutdown {
|
||||
catch {db close}
|
||||
sqlite3_shutdown
|
||||
sqlite3_config_heap 0 0
|
||||
sqlite3_config_lookaside 100 500
|
||||
install_malloc_faultsim 1
|
||||
sqlite3_initialize
|
||||
autoinstall_test_functions
|
||||
}
|
||||
|
||||
test_suite "no_mutex_try" -description {
|
||||
The sqlite3_mutex_try() interface always fails
|
||||
} -files [
|
||||
test_set $::allquicktests -exclude mutex1.test mutex2.test
|
||||
] -initialize {
|
||||
catch {db close}
|
||||
sqlite3_shutdown
|
||||
install_mutex_counters 1
|
||||
set ::disable_mutex_try 1
|
||||
sqlite3_initialize
|
||||
autoinstall_test_functions
|
||||
} -shutdown {
|
||||
catch {db close}
|
||||
catch {db2 close}
|
||||
catch {db3 close}
|
||||
sqlite3_shutdown
|
||||
install_mutex_counters 0
|
||||
sqlite3_initialize
|
||||
autoinstall_test_functions
|
||||
}
|
||||
|
||||
# run_tests "crash_safe_append" -description {
|
||||
|
@@ -53,6 +53,12 @@ array set ::Configs [strip_comments {
|
||||
--enable-session
|
||||
-DSQLITE_ENABLE_RBU
|
||||
}
|
||||
"All-Debug" {
|
||||
--enable-debug --enable-all
|
||||
}
|
||||
"All-O0" {
|
||||
-O0 --enable-all
|
||||
}
|
||||
"Sanitize" {
|
||||
CC=clang -fsanitize=address,undefined
|
||||
-DSQLITE_ENABLE_STAT4
|
||||
@@ -672,6 +678,12 @@ proc main_trscript {args} {
|
||||
lappend opts -DSQLITE_ENABLE_PREUPDATE_HOOK
|
||||
lappend opts -DSQLITE_ENABLE_SESSION
|
||||
}
|
||||
--enable-all {
|
||||
}
|
||||
--enable-debug {
|
||||
# lappend makeOpts OPTIMIZATIONS=0
|
||||
lappend opts -DSQLITE_DEBUG
|
||||
}
|
||||
default {
|
||||
error "Cannot translate $param for MSVC"
|
||||
}
|
||||
@@ -717,7 +729,12 @@ proc main_trscript {args} {
|
||||
puts " \$SRCDIR/configure --with-tcl=\$TCL $configOpts"
|
||||
puts {fi}
|
||||
puts {}
|
||||
puts {OPTS=" -DSQLITE_NO_SYNC=1"}
|
||||
if {[info exists ::env(OPTS)]} {
|
||||
puts "# From environment variable:"
|
||||
puts "OPTS=$::env(OPTS)"
|
||||
puts ""
|
||||
}
|
||||
puts {OPTS="$OPTS -DSQLITE_NO_SYNC=1"}
|
||||
foreach o $opts {
|
||||
puts "OPTS=\"\$OPTS $o\""
|
||||
}
|
||||
|
@@ -69,7 +69,7 @@ foreach {tn script} {
|
||||
# Because it uses so much data, this test can take 12-13 seconds even on
|
||||
# a modern workstation. So it is omitted from "veryquick" and other
|
||||
# permutations.test tests.
|
||||
if {[isquick]==0} {
|
||||
if {[isquick]==0 && [clang_sanitize_address]==0} {
|
||||
do_execsql_test $tn.3 {
|
||||
PRAGMA cache_size = 5;
|
||||
WITH r(x,y) AS (
|
||||
|
@@ -1,6 +1,6 @@
|
||||
|
||||
set dir [pwd]
|
||||
set testdir [file dirname $argv0]
|
||||
set testdir [file normalize [file dirname $argv0]]
|
||||
set saved $argv
|
||||
set argv [list]
|
||||
source [file join $testdir testrunner_data.tcl]
|
||||
@@ -8,6 +8,42 @@ source [file join $testdir permutations.test]
|
||||
set argv $saved
|
||||
cd $dir
|
||||
|
||||
# This script requires an interpreter that supports [package require sqlite3]
|
||||
# to run. If this is not such an intepreter, see if there is a [testfixture]
|
||||
# in the current directory. If so, run the command using it. If not,
|
||||
# recommend that the user build one.
|
||||
#
|
||||
proc find_interpreter {} {
|
||||
set interpreter [file tail [info nameofexec]]
|
||||
set rc [catch { package require sqlite3 }]
|
||||
if {$rc} {
|
||||
if { [string match -nocase testfixture* $interpreter]==0
|
||||
&& [file executable ./testfixture]
|
||||
} {
|
||||
puts "Failed to find tcl package sqlite3. Restarting with ./testfixture.."
|
||||
set status [catch {
|
||||
exec ./testfixture [info script] {*}$::argv >@ stdout
|
||||
} msg]
|
||||
exit $status
|
||||
}
|
||||
}
|
||||
if {$rc} {
|
||||
puts stderr "Failed to find tcl package sqlite3"
|
||||
puts stderr "Run \"make testfixture\" and then try again..."
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
find_interpreter
|
||||
|
||||
# Usually this script is run by [testfixture]. But it can also be run
|
||||
# by a regular [tclsh]. For these cases, emulate the [clock_milliseconds]
|
||||
# command.
|
||||
if {[info commands clock_milliseconds]==""} {
|
||||
proc clock_milliseconds {} {
|
||||
clock milliseconds
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Usage:
|
||||
#
|
||||
@@ -74,16 +110,20 @@ proc guess_number_of_cores {} {
|
||||
if {[catch {number_of_cores} ret]} {
|
||||
set ret 4
|
||||
|
||||
if {$::tcl_platform(os)=="Darwin"} {
|
||||
set cmd "sysctl -n hw.logicalcpu"
|
||||
if {$::tcl_platform(platform)=="windows"} {
|
||||
catch { set ret $::env(NUMBER_OF_PROCESSORS) }
|
||||
} else {
|
||||
set cmd "nproc"
|
||||
}
|
||||
catch {
|
||||
set fd [open "|$cmd" r]
|
||||
set ret [gets $fd]
|
||||
close $fd
|
||||
set ret [expr $ret]
|
||||
if {$::tcl_platform(os)=="Darwin"} {
|
||||
set cmd "sysctl -n hw.logicalcpu"
|
||||
} else {
|
||||
set cmd "nproc"
|
||||
}
|
||||
catch {
|
||||
set fd [open "|$cmd" r]
|
||||
set ret [gets $fd]
|
||||
close $fd
|
||||
set ret [expr $ret]
|
||||
}
|
||||
}
|
||||
}
|
||||
return $ret
|
||||
@@ -152,10 +192,8 @@ set TRG(schema) {
|
||||
state TEXT CHECK( state IN ('', 'ready', 'running', 'done', 'failed') ),
|
||||
time INTEGER, -- Time in ms
|
||||
output TEXT, -- full output of test script
|
||||
priority AS ((config='make') + ((config='build')*2) + (slow*4)),
|
||||
jobtype AS (
|
||||
CASE WHEN config IN ('build', 'make') THEN config ELSE 'script' END
|
||||
),
|
||||
priority INTEGER,
|
||||
jobtype TEXT CHECK( jobtype IN ('script', 'build', 'make') ),
|
||||
PRIMARY KEY(build, config, filename)
|
||||
);
|
||||
|
||||
@@ -181,10 +219,11 @@ if {[llength $argv]==2
|
||||
set script [file normalize [lindex $argv 1]]
|
||||
set ::argv [list]
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $::testdir/tester.tcl
|
||||
|
||||
if {$permutation=="full"} {
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $::testdir/tester.tcl
|
||||
unset -nocomplain ::G(isquick)
|
||||
reset_db
|
||||
|
||||
@@ -241,6 +280,22 @@ if {([llength $argv]==2 || [llength $argv]==1)
|
||||
}
|
||||
#--------------------------------------------------------------------------
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Check if this is the "script" command:
|
||||
#
|
||||
if {[string compare -nocase script [lindex $argv 0]]==0} {
|
||||
if {[llength $argv]!=2 && !([llength $argv]==3&&[lindex $argv 1]=="-msvc")} {
|
||||
usage
|
||||
}
|
||||
|
||||
set bMsvc [expr ([llength $argv]==3)]
|
||||
set config [lindex $argv [expr [llength $argv]-1]]
|
||||
|
||||
puts [trd_buildscript $config [file dirname $testdir] $bMsvc]
|
||||
exit
|
||||
}
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Check if this is the "status" command:
|
||||
#
|
||||
@@ -289,9 +344,13 @@ if {[llength $argv]==1
|
||||
|
||||
set cmdline [mydb one { SELECT value FROM config WHERE name='cmdline' }]
|
||||
set nJob [mydb one { SELECT value FROM config WHERE name='njob' }]
|
||||
set tm [expr [clock_milliseconds] - [mydb one {
|
||||
SELECT value FROM config WHERE name='start'
|
||||
}]]
|
||||
|
||||
set now [clock_milliseconds]
|
||||
set tm [mydb one {
|
||||
SELECT
|
||||
COALESCE((SELECT value FROM config WHERE name='end'), $now) -
|
||||
(SELECT value FROM config WHERE name='start')
|
||||
}]
|
||||
|
||||
set total 0
|
||||
foreach s {"" ready running done failed} { set S($s) 0 }
|
||||
@@ -315,7 +374,6 @@ if {[llength $argv]==1
|
||||
set srcdir [file dirname [file dirname $TRG(info_script)]]
|
||||
if {$S(running)>0} {
|
||||
puts "Running: "
|
||||
set now [clock_milliseconds]
|
||||
mydb eval {
|
||||
SELECT build, config, filename, time FROM script WHERE state='running'
|
||||
ORDER BY time
|
||||
@@ -411,8 +469,6 @@ proc dirs_allocDir {} {
|
||||
return $iRet
|
||||
}
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
|
||||
# Check that directory $dir exists. If it does not, create it. If
|
||||
# it does, delete its contents.
|
||||
#
|
||||
@@ -449,7 +505,16 @@ proc testset_patternlist {patternlist} {
|
||||
|
||||
set first [lindex $patternlist 0]
|
||||
|
||||
if {$first=="release"} {
|
||||
if {$first=="mdevtest"} {
|
||||
set patternlist [lrange $patternlist 1 end]
|
||||
|
||||
foreach b {All-Debug All-O0} {
|
||||
lappend testset [list $b build testfixture]
|
||||
lappend testset [list $b make fuzztest]
|
||||
testset_append testset $b veryquick $patternlist
|
||||
}
|
||||
|
||||
} elseif {$first=="release"} {
|
||||
set platform $::TRG(platform)
|
||||
|
||||
set patternlist [lrange $patternlist 1 end]
|
||||
@@ -634,9 +699,20 @@ proc make_new_testset {} {
|
||||
set state ""
|
||||
}
|
||||
|
||||
set priority [expr {$slow*2}]
|
||||
if {$c=="make"} { incr priority 3 }
|
||||
if {$c=="build"} { incr priority 1 }
|
||||
|
||||
if {$c=="make" || $c=="build"} {
|
||||
set jobtype $c
|
||||
} else {
|
||||
set jobtype "script"
|
||||
}
|
||||
|
||||
trdb eval {
|
||||
INSERT INTO script(build, config, filename, slow, state)
|
||||
VALUES ($b, $c, $s, $slow, $state)
|
||||
INSERT INTO script
|
||||
(build, config, filename, slow, state, priority, jobtype)
|
||||
VALUES ($b, $c, $s, $slow, $state, $priority, $jobtype)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -721,12 +797,7 @@ proc launch_another_job {iJob} {
|
||||
if {$b=="Zipvfs"} {
|
||||
set script [zipvfs_testrunner_script]
|
||||
} else {
|
||||
set cmd [info nameofexec]
|
||||
lappend cmd [file join $testdir releasetest_data.tcl]
|
||||
lappend cmd trscript
|
||||
if {$TRG(platform)=="win"} { lappend cmd -msvc }
|
||||
lappend cmd $b $srcdir
|
||||
set script [exec {*}$cmd]
|
||||
set script [trd_buildscript $b $srcdir [expr {$TRG(platform)=="win"}]]
|
||||
}
|
||||
|
||||
set fd [open [file join $builddir $TRG(make)] w]
|
||||
@@ -865,6 +936,8 @@ proc run_testset {} {
|
||||
one_line_report
|
||||
|
||||
r_write_db {
|
||||
set tm [clock_milliseconds]
|
||||
trdb eval { REPLACE INTO config VALUES('end', $tm ); }
|
||||
set nErr [trdb one {SELECT count(*) FROM script WHERE state='failed'}]
|
||||
if {$nErr>0} {
|
||||
puts "$nErr failures:"
|
||||
|
@@ -5,6 +5,7 @@ namespace eval trd {
|
||||
variable tcltest
|
||||
variable extra
|
||||
variable all_configs
|
||||
variable build
|
||||
|
||||
|
||||
# Tcl tests to run for various builds.
|
||||
@@ -35,6 +36,7 @@ namespace eval trd {
|
||||
set tcltest(win.Have-Not) veryquick
|
||||
set tcltest(win.Windows-Memdebug) veryquick
|
||||
set tcltest(win.Windows-Win32Heap) veryquick
|
||||
set tcltest(win.Windows-Sanitize) veryquick
|
||||
set tcltest(win.Default) full
|
||||
|
||||
# Extra [make xyz] tests that should be run for various builds.
|
||||
@@ -63,6 +65,7 @@ namespace eval trd {
|
||||
set extra(win.Stdcall) {fuzztest sourcetest}
|
||||
set extra(win.Windows-Memdebug) {fuzztest sourcetest}
|
||||
set extra(win.Windows-Win32Heap) {fuzztest sourcetest}
|
||||
set extra(win.Windows-Sanitize) fuzztest
|
||||
set extra(win.Have-Not) {fuzztest sourcetest}
|
||||
|
||||
# The following mirrors the set of test suites invoked by "all.test".
|
||||
@@ -75,6 +78,245 @@ namespace eval trd {
|
||||
inmemory_journal pcache0 pcache10 pcache50 pcache90
|
||||
pcache100 prepare mmap
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
# Start of build() definitions.
|
||||
#
|
||||
set build(Default) {
|
||||
-O2
|
||||
--disable-amalgamation --disable-shared
|
||||
--enable-session
|
||||
-DSQLITE_ENABLE_RBU
|
||||
}
|
||||
|
||||
# These two are used by [testrunner.tcl mdevtest].
|
||||
#
|
||||
set build(All-Debug) {
|
||||
--enable-debug --enable-all
|
||||
}
|
||||
set build(All-O0) {
|
||||
-O0 --enable-all
|
||||
}
|
||||
|
||||
set build(Sanitize) {
|
||||
CC=clang -fsanitize=address,undefined
|
||||
-DSQLITE_ENABLE_STAT4
|
||||
-DCONFIG_SLOWDOWN_FACTOR=5.0
|
||||
--enable-debug
|
||||
--enable-all
|
||||
}
|
||||
set build(Stdcall) {
|
||||
-DUSE_STDCALL=1
|
||||
-O2
|
||||
}
|
||||
|
||||
# The "Have-Not" configuration sets all possible -UHAVE_feature options
|
||||
# in order to verify that the code works even on platforms that lack
|
||||
# these support services.
|
||||
set build(Have-Not) {
|
||||
-DHAVE_FDATASYNC=0
|
||||
-DHAVE_GMTIME_R=0
|
||||
-DHAVE_ISNAN=0
|
||||
-DHAVE_LOCALTIME_R=0
|
||||
-DHAVE_LOCALTIME_S=0
|
||||
-DHAVE_MALLOC_USABLE_SIZE=0
|
||||
-DHAVE_STRCHRNUL=0
|
||||
-DHAVE_USLEEP=0
|
||||
-DHAVE_UTIME=0
|
||||
}
|
||||
set build(Unlock-Notify) {
|
||||
-O2
|
||||
-DSQLITE_ENABLE_UNLOCK_NOTIFY
|
||||
-DSQLITE_THREADSAFE
|
||||
-DSQLITE_TCL_DEFAULT_FULLMUTEX=1
|
||||
}
|
||||
set build(User-Auth) {
|
||||
-O2
|
||||
-DSQLITE_USER_AUTHENTICATION=1
|
||||
}
|
||||
set build(Secure-Delete) {
|
||||
-O2
|
||||
-DSQLITE_SECURE_DELETE=1
|
||||
-DSQLITE_SOUNDEX=1
|
||||
}
|
||||
set build(Update-Delete-Limit) {
|
||||
-O2
|
||||
-DSQLITE_DEFAULT_FILE_FORMAT=4
|
||||
-DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1
|
||||
-DSQLITE_ENABLE_STMT_SCANSTATUS
|
||||
-DSQLITE_LIKE_DOESNT_MATCH_BLOBS
|
||||
-DSQLITE_ENABLE_CURSOR_HINTS
|
||||
}
|
||||
set build(Check-Symbols) {
|
||||
-DSQLITE_MEMDEBUG=1
|
||||
-DSQLITE_ENABLE_FTS3_PARENTHESIS=1
|
||||
-DSQLITE_ENABLE_FTS3=1
|
||||
-DSQLITE_ENABLE_RTREE=1
|
||||
-DSQLITE_ENABLE_MEMSYS5=1
|
||||
-DSQLITE_ENABLE_MEMSYS3=1
|
||||
-DSQLITE_ENABLE_COLUMN_METADATA=1
|
||||
-DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1
|
||||
-DSQLITE_SECURE_DELETE=1
|
||||
-DSQLITE_SOUNDEX=1
|
||||
-DSQLITE_ENABLE_ATOMIC_WRITE=1
|
||||
-DSQLITE_ENABLE_MEMORY_MANAGEMENT=1
|
||||
-DSQLITE_ENABLE_OVERSIZE_CELL_CHECK=1
|
||||
-DSQLITE_ENABLE_STAT4
|
||||
-DSQLITE_ENABLE_STMT_SCANSTATUS
|
||||
--enable-fts5 --enable-session
|
||||
}
|
||||
set build(Debug-One) {
|
||||
--disable-shared
|
||||
-O2 -funsigned-char
|
||||
-DSQLITE_DEBUG=1
|
||||
-DSQLITE_MEMDEBUG=1
|
||||
-DSQLITE_MUTEX_NOOP=1
|
||||
-DSQLITE_TCL_DEFAULT_FULLMUTEX=1
|
||||
-DSQLITE_ENABLE_FTS3=1
|
||||
-DSQLITE_ENABLE_RTREE=1
|
||||
-DSQLITE_ENABLE_MEMSYS5=1
|
||||
-DSQLITE_ENABLE_COLUMN_METADATA=1
|
||||
-DSQLITE_ENABLE_STAT4
|
||||
-DSQLITE_ENABLE_HIDDEN_COLUMNS
|
||||
-DSQLITE_MAX_ATTACHED=125
|
||||
-DSQLITE_MUTATION_TEST
|
||||
--enable-fts5
|
||||
}
|
||||
set build(Debug-Two) {
|
||||
-DSQLITE_DEFAULT_MEMSTATUS=0
|
||||
-DSQLITE_MAX_EXPR_DEPTH=0
|
||||
--enable-debug
|
||||
}
|
||||
set build(Fast-One) {
|
||||
-O6
|
||||
-DSQLITE_ENABLE_FTS4=1
|
||||
-DSQLITE_ENABLE_RTREE=1
|
||||
-DSQLITE_ENABLE_STAT4
|
||||
-DSQLITE_ENABLE_RBU
|
||||
-DSQLITE_MAX_ATTACHED=125
|
||||
-DSQLITE_MAX_MMAP_SIZE=12884901888
|
||||
-DSQLITE_ENABLE_SORTER_MMAP=1
|
||||
-DLONGDOUBLE_TYPE=double
|
||||
--enable-session
|
||||
}
|
||||
set build(Device-One) {
|
||||
-O2
|
||||
-DSQLITE_DEBUG=1
|
||||
-DSQLITE_DEFAULT_AUTOVACUUM=1
|
||||
-DSQLITE_DEFAULT_CACHE_SIZE=64
|
||||
-DSQLITE_DEFAULT_PAGE_SIZE=1024
|
||||
-DSQLITE_DEFAULT_TEMP_CACHE_SIZE=32
|
||||
-DSQLITE_DISABLE_LFS=1
|
||||
-DSQLITE_ENABLE_ATOMIC_WRITE=1
|
||||
-DSQLITE_ENABLE_IOTRACE=1
|
||||
-DSQLITE_ENABLE_MEMORY_MANAGEMENT=1
|
||||
-DSQLITE_MAX_PAGE_SIZE=4096
|
||||
-DSQLITE_OMIT_LOAD_EXTENSION=1
|
||||
-DSQLITE_OMIT_PROGRESS_CALLBACK=1
|
||||
-DSQLITE_OMIT_VIRTUALTABLE=1
|
||||
-DSQLITE_ENABLE_HIDDEN_COLUMNS
|
||||
-DSQLITE_TEMP_STORE=3
|
||||
}
|
||||
set build(Device-Two) {
|
||||
-DSQLITE_4_BYTE_ALIGNED_MALLOC=1
|
||||
-DSQLITE_DEFAULT_AUTOVACUUM=1
|
||||
-DSQLITE_DEFAULT_CACHE_SIZE=1000
|
||||
-DSQLITE_DEFAULT_LOCKING_MODE=0
|
||||
-DSQLITE_DEFAULT_PAGE_SIZE=1024
|
||||
-DSQLITE_DEFAULT_TEMP_CACHE_SIZE=1000
|
||||
-DSQLITE_DISABLE_LFS=1
|
||||
-DSQLITE_ENABLE_FTS3=1
|
||||
-DSQLITE_ENABLE_MEMORY_MANAGEMENT=1
|
||||
-DSQLITE_ENABLE_RTREE=1
|
||||
-DSQLITE_MAX_COMPOUND_SELECT=50
|
||||
-DSQLITE_MAX_PAGE_SIZE=32768
|
||||
-DSQLITE_OMIT_TRACE=1
|
||||
-DSQLITE_TEMP_STORE=3
|
||||
-DSQLITE_THREADSAFE=2
|
||||
--enable-fts5 --enable-session
|
||||
}
|
||||
set build(Locking-Style) {
|
||||
-O2
|
||||
-DSQLITE_ENABLE_LOCKING_STYLE=1
|
||||
}
|
||||
set build(Apple) {
|
||||
-Os
|
||||
-DHAVE_GMTIME_R=1
|
||||
-DHAVE_ISNAN=1
|
||||
-DHAVE_LOCALTIME_R=1
|
||||
-DHAVE_PREAD=1
|
||||
-DHAVE_PWRITE=1
|
||||
-DHAVE_UTIME=1
|
||||
-DSQLITE_DEFAULT_CACHE_SIZE=1000
|
||||
-DSQLITE_DEFAULT_CKPTFULLFSYNC=1
|
||||
-DSQLITE_DEFAULT_MEMSTATUS=1
|
||||
-DSQLITE_DEFAULT_PAGE_SIZE=1024
|
||||
-DSQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS=1
|
||||
-DSQLITE_ENABLE_API_ARMOR=1
|
||||
-DSQLITE_ENABLE_AUTO_PROFILE=1
|
||||
-DSQLITE_ENABLE_FLOCKTIMEOUT=1
|
||||
-DSQLITE_ENABLE_FTS3=1
|
||||
-DSQLITE_ENABLE_FTS3_PARENTHESIS=1
|
||||
-DSQLITE_ENABLE_FTS3_TOKENIZER=1
|
||||
-DSQLITE_ENABLE_PERSIST_WAL=1
|
||||
-DSQLITE_ENABLE_PURGEABLE_PCACHE=1
|
||||
-DSQLITE_ENABLE_RTREE=1
|
||||
-DSQLITE_ENABLE_SNAPSHOT=1
|
||||
-DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1
|
||||
-DSQLITE_MAX_LENGTH=2147483645
|
||||
-DSQLITE_MAX_VARIABLE_NUMBER=500000
|
||||
-DSQLITE_NO_SYNC=1
|
||||
-DSQLITE_OMIT_AUTORESET=1
|
||||
-DSQLITE_OMIT_LOAD_EXTENSION=1
|
||||
-DSQLITE_PREFER_PROXY_LOCKING=1
|
||||
-DSQLITE_SERIES_CONSTRAINT_VERIFY=1
|
||||
-DSQLITE_THREADSAFE=2
|
||||
-DSQLITE_USE_URI=1
|
||||
-DSQLITE_WRITE_WALFRAME_PREBUFFERED=1
|
||||
-DUSE_GUARDED_FD=1
|
||||
-DUSE_PREAD=1
|
||||
--enable-fts5
|
||||
}
|
||||
set build(Extra-Robustness) {
|
||||
-DSQLITE_ENABLE_OVERSIZE_CELL_CHECK=1
|
||||
-DSQLITE_MAX_ATTACHED=62
|
||||
}
|
||||
set build(Devkit) {
|
||||
-DSQLITE_DEFAULT_FILE_FORMAT=4
|
||||
-DSQLITE_MAX_ATTACHED=30
|
||||
-DSQLITE_ENABLE_COLUMN_METADATA
|
||||
-DSQLITE_ENABLE_FTS4
|
||||
-DSQLITE_ENABLE_FTS5
|
||||
-DSQLITE_ENABLE_FTS4_PARENTHESIS
|
||||
-DSQLITE_DISABLE_FTS4_DEFERRED
|
||||
-DSQLITE_ENABLE_RTREE
|
||||
--enable-fts5
|
||||
}
|
||||
set build(No-lookaside) {
|
||||
-DSQLITE_TEST_REALLOC_STRESS=1
|
||||
-DSQLITE_OMIT_LOOKASIDE=1
|
||||
}
|
||||
set build(Valgrind) {
|
||||
-DSQLITE_ENABLE_STAT4
|
||||
-DSQLITE_ENABLE_FTS4
|
||||
-DSQLITE_ENABLE_RTREE
|
||||
-DSQLITE_ENABLE_HIDDEN_COLUMNS
|
||||
-DLONGDOUBLE_TYPE=double
|
||||
-DCONFIG_SLOWDOWN_FACTOR=8.0
|
||||
}
|
||||
|
||||
set build(Windows-Memdebug) {
|
||||
MEMDEBUG=1
|
||||
DEBUG=3
|
||||
}
|
||||
set build(Windows-Win32Heap) {
|
||||
WIN32HEAP=1
|
||||
DEBUG=4
|
||||
}
|
||||
set build(Windows-Sanitize) {
|
||||
ASAN=1
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +326,7 @@ proc trd_import {} {
|
||||
variable ::trd::tcltest
|
||||
variable ::trd::extra
|
||||
variable ::trd::all_configs
|
||||
variable ::trd::build
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,13 +349,13 @@ proc trd_builds {platform} {
|
||||
set ret
|
||||
}
|
||||
|
||||
proc trd_configs {platform build} {
|
||||
proc trd_configs {platform bld} {
|
||||
trd_import
|
||||
|
||||
set clist [list]
|
||||
|
||||
if {[info exists tcltest($platform.$build)]} {
|
||||
set clist $tcltest($platform.$build)
|
||||
if {[info exists tcltest($platform.$bld)]} {
|
||||
set clist $tcltest($platform.$bld)
|
||||
if {$clist=="all"} {
|
||||
set clist $all_configs
|
||||
} elseif {$clist=="all_plus_autovacuum_crash"} {
|
||||
@@ -123,12 +366,12 @@ proc trd_configs {platform build} {
|
||||
set clist
|
||||
}
|
||||
|
||||
proc trd_extras {platform build} {
|
||||
proc trd_extras {platform bld} {
|
||||
trd_import
|
||||
|
||||
set elist [list]
|
||||
if {[info exists extra($platform.$build)]} {
|
||||
set elist $extra($platform.$build)
|
||||
if {[info exists extra($platform.$bld)]} {
|
||||
set elist $extra($platform.$bld)
|
||||
}
|
||||
|
||||
set elist
|
||||
@@ -139,5 +382,180 @@ proc trd_all_configs {} {
|
||||
set all_configs
|
||||
}
|
||||
|
||||
proc trimscript {text} {
|
||||
set text [string map {"\n " "\n"} [string trim $text]]
|
||||
}
|
||||
|
||||
proc make_sh_script {srcdir opts cflags makeOpts configOpts} {
|
||||
|
||||
set tcldir [::tcl::pkgconfig get libdir,install]
|
||||
set myopts ""
|
||||
if {[info exists ::env(OPTS)]} {
|
||||
append myopts "# From environment variable:\n"
|
||||
append myopts "OPTS=$::env(OPTS)\n"
|
||||
}
|
||||
foreach o [lsort $opts] {
|
||||
append myopts "OPTS=\"\$OPTS $o\"\n"
|
||||
}
|
||||
|
||||
return [trimscript [subst -nocommands {
|
||||
set -e
|
||||
if [ "\$#" -ne 1 ] ; then
|
||||
echo "Usage: \$0 <target>"
|
||||
exit -1
|
||||
fi
|
||||
|
||||
SRCDIR="$srcdir"
|
||||
TCLDIR="$tcldir"
|
||||
|
||||
if [ ! -f Makefile ] ; then
|
||||
\$SRCDIR/configure --with-tcl=\$TCL $configOpts
|
||||
fi
|
||||
|
||||
$myopts
|
||||
CFLAGS="$cflags"
|
||||
|
||||
make \$1 "CFLAGS=\$CFLAGS" "OPTS=\$OPTS" $makeOpts
|
||||
}]]
|
||||
}
|
||||
|
||||
# Generate the text of a *.bat script.
|
||||
#
|
||||
proc make_bat_file {srcdir opts cflags makeOpts} {
|
||||
set srcdir [file nativename [file normalize $srcdir]]
|
||||
|
||||
return [trimscript [subst -nocommands {
|
||||
set TARGET=%1
|
||||
set TMP=%CD%
|
||||
nmake /f $srcdir\\Makefile.msc TOP="$srcdir" %TARGET% "CCOPTS=$cflags" "OPTS=$opts" $makeOpts
|
||||
}]]
|
||||
}
|
||||
|
||||
|
||||
# Generate the text of a shell script.
|
||||
#
|
||||
proc make_script {cfg srcdir bMsvc} {
|
||||
set opts [list] ;# OPTS value
|
||||
set cflags [expr {$bMsvc ? "-Zi" : "-g"}] ;# CFLAGS value
|
||||
set makeOpts [list] ;# Extra args for [make]
|
||||
set configOpts [list] ;# Extra args for [configure]
|
||||
|
||||
# Define either SQLITE_OS_WIN or SQLITE_OS_UNIX, as appropriate.
|
||||
if {$::tcl_platform(platform)=="windows"} {
|
||||
lappend opts -DSQLITE_OS_WIN=1
|
||||
} else {
|
||||
lappend opts -DSQLITE_OS_UNIX=1
|
||||
}
|
||||
|
||||
# Unless the configuration specifies -DHAVE_USLEEP=0, set -DHAVE_USLEEP=1.
|
||||
#
|
||||
if {[lsearch $cfg "-DHAVE_USLEEP=0"]<0} {
|
||||
lappend cfg -DHAVE_USLEEP=1
|
||||
}
|
||||
|
||||
# Loop through the parameters of the nominated configuration, updating
|
||||
# $opts, $cflags, $makeOpts and $configOpts along the way. Rules are as
|
||||
# follows:
|
||||
#
|
||||
# 1. If the parameter begins with "-D", add it to $opts.
|
||||
#
|
||||
# 2. If the parameter begins with "--" add it to $configOpts. Unless
|
||||
# this command is preparing a script for MSVC - then add an
|
||||
# equivalent to $makeOpts or $opts.
|
||||
#
|
||||
# 3. If the parameter begins with "-" add it to $cflags. If in MSVC
|
||||
# mode and the parameter is an -O<integer> option, instead add
|
||||
# an OPTIMIZATIONS=<integer> switch to $makeOpts.
|
||||
#
|
||||
# 4. If none of the above apply, add the parameter to $makeOpts
|
||||
#
|
||||
foreach param $cfg {
|
||||
|
||||
if {[string range $param 0 1]=="-D"} {
|
||||
lappend opts $param
|
||||
continue
|
||||
}
|
||||
|
||||
if {[string range $param 0 1]=="--"} {
|
||||
if {$bMsvc==0} {
|
||||
lappend configOpts $param
|
||||
} else {
|
||||
|
||||
switch -- $param {
|
||||
--disable-amalgamation {
|
||||
lappend makeOpts USE_AMALGAMATION=0
|
||||
}
|
||||
--disable-shared {
|
||||
lappend makeOpts USE_CRT_DLL=0 DYNAMIC_SHELL=0
|
||||
}
|
||||
--enable-fts5 {
|
||||
lappend opts -DSQLITE_ENABLE_FTS5
|
||||
}
|
||||
--enable-shared {
|
||||
lappend makeOpts USE_CRT_DLL=1 DYNAMIC_SHELL=1
|
||||
}
|
||||
--enable-session {
|
||||
lappend opts -DSQLITE_ENABLE_PREUPDATE_HOOK
|
||||
lappend opts -DSQLITE_ENABLE_SESSION
|
||||
}
|
||||
--enable-all {
|
||||
}
|
||||
--enable-debug {
|
||||
# lappend makeOpts OPTIMIZATIONS=0
|
||||
lappend opts -DSQLITE_DEBUG
|
||||
}
|
||||
default {
|
||||
error "Cannot translate $param for MSVC"
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if {[string range $param 0 0]=="-"} {
|
||||
if {$bMsvc && [regexp -- {^-O(\d+)$} $param -> level]} {
|
||||
lappend makeOpts OPTIMIZATIONS=$level
|
||||
} else {
|
||||
lappend cflags $param
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
lappend makeOpts $param
|
||||
}
|
||||
|
||||
if {$bMsvc==0} {
|
||||
set zRet [make_sh_script $srcdir $opts $cflags $makeOpts $configOpts]
|
||||
} else {
|
||||
set zRet [make_bat_file $srcdir $opts $cflags $makeOpts]
|
||||
}
|
||||
}
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# trd_buildscript CONFIG SRCDIR MSVC
|
||||
#
|
||||
# This command returns the full text of a script (either a shell script or
|
||||
# an ms-dos bat file) that may be used to build SQLite source code according
|
||||
# to a nominated configuration.
|
||||
#
|
||||
# Parameter CONFIG must be a configuration defined above in the ::trd::build
|
||||
# array. SRCDIR is the root directory of an SQLite source tree (the parent
|
||||
# directory of that containing this script). MSVC is a boolean - true to
|
||||
# use the MSVC compiler, false otherwise.
|
||||
#
|
||||
proc trd_buildscript {config srcdir bMsvc} {
|
||||
trd_import
|
||||
|
||||
# Ensure that the named configuration exists.
|
||||
if {![info exists build($config)]} {
|
||||
error "No such build config: $config"
|
||||
}
|
||||
|
||||
# Generate and return the script.
|
||||
return [make_script $build($config) $srcdir $bMsvc]
|
||||
}
|
||||
|
||||
|
||||
|
@@ -255,4 +255,17 @@ do_execsql_test upsert1-1100 {
|
||||
SELECT * FROM t1;
|
||||
} {1 22}
|
||||
|
||||
# 2023-08-17 dbsqlfuzz 9983e2c77634a8ccf33b5c91fa9982599de5f9e9
|
||||
# Bound parameters in the ON CONFLICT clause of an UPSERT.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test upsert1-1200 {
|
||||
CREATE TABLE t1(a INT, b INT);
|
||||
CREATE UNIQUE INDEX t1x ON t1(b+3);
|
||||
}
|
||||
sqlite3_db_config db ENABLE_QPSG 1
|
||||
do_catchsql_test upsert1-1210 {
|
||||
INSERT INTO t1(a,b) VALUES(1,2) ON CONFLICT(b+?1) DO NOTHING;
|
||||
} {1 {ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint}}
|
||||
|
||||
finish_test
|
||||
|
@@ -47,8 +47,12 @@
|
||||
# include <unistd.h>
|
||||
#else
|
||||
# include <io.h>
|
||||
# define R_OK 04
|
||||
# define access(f,m) _access((f),(m))
|
||||
# ifndef R_OK
|
||||
# define R_OK 04
|
||||
# endif
|
||||
# ifndef access
|
||||
# define access(f,m) _access((f),(m))
|
||||
# endif
|
||||
#endif
|
||||
typedef unsigned long long int u64;
|
||||
|
||||
|
Reference in New Issue
Block a user