Compare commits

..

58 Commits

Author SHA1 Message Date
drh 67276c648b When compiling with SQLITE_ALLOW_ROWID_IN_VIEW, if the RETURNING clause of
an UPDATE of a view specifies a rowid, then return NULL for the value of
that rowid.

FossilOrigin-Name: d38cfa6067ccd450c4fac183765c05ff247ecb49ccf172a68ef9d381577df84f
2024-04-05 11:28:30 +00:00
drh ff549b1384 Fix the xBestIndex method of the pragma virtual table so that it correctly
gives a higher cost to plans where the schema hidden parameter is
unconstrained.

FossilOrigin-Name: d68fb8b5dbb8305e00d2dd14d8fe6b3d9f67e2459102ff160d956a6b75ddc18e
2024-03-24 21:15:01 +00:00
drh 5b9ba67d8e Do not automatically assume that ROWID is NOT NULL when compiled with
SQLITE_ALLOW_ROWID_IN_VIEW.
dbsqlfuzz 31b38eeb63a4e1562de665078f52b7b47a7543cf

FossilOrigin-Name: b5d2dce18fcd00749a3efe8386df42fca103f86bd862f2610cfb05651ddb9d59
2024-03-24 16:42:12 +00:00
drh c2526e2c2d Fix a assert() that is incorrect, though harmless. Also add a test case.
FossilOrigin-Name: 57b0c984605d0f437b4930f6b994e15b80340c753d46a679b07d356c645856ea
2024-03-21 22:08:33 +00:00
drh 29ef48a097 Fix test cases for rtree and fts5. No changes to code.
FossilOrigin-Name: 633dca907488b721ec1b8e470904af73369c1b1225005038aacb3e8a78c6390c
2024-03-20 16:29:19 +00:00
drh 47f478c9da Have rtree avoid keeping a blob handle open following an error.
FossilOrigin-Name: 1303716a113c51e949acc46fbd01634ce0e5a016cbc2d01bb20dd03ffd1f28e0
2024-03-20 16:04:53 +00:00
drh a93344297f Following a ROLLBACK that reverts changes to an RTREE, any pending queries
against that same RTREE abort with code SQLITE_ABORT_ROLLBACK.
dbsqlfuzz de7d17b72d0e842352c998dd86a47b7d0f707be9.

FossilOrigin-Name: b26e5a500ebc358047eff79db61b5edfec319b95fbf8685e6a798c5e6c1923fb
2024-03-20 15:26:30 +00:00
drh b2bc4c9338 Back port various minor patches
FossilOrigin-Name: a1a5c427c2c5cfff1ffeb71b29c9f64121465334c6a3fde8213df1dc2a1228d4
2024-03-20 12:19:40 +00:00
drh d07908335d Automatically disable the DISTINCT optimization during query planning if the
ORDER BY clause exceeds 63 terms.
dbsqlfuzz afd1d61fc27d14938a0d78a50970fa1e9fbfee58.

FossilOrigin-Name: e8d5caef260b171b4df7f6166e191fc763e25be5b94fc1e097cd5c4ec05604e4
2024-03-20 11:36:26 +00:00
drh 76214b6661 Ignore COLLATE operators when determining whether the result of a subexpression
should be shallow-copied or deep-copied.

FossilOrigin-Name: dd58d1178f840f0249cb3d84f44c9da0335ca6a44f064f6ad6ec68ec621556c5
2024-03-20 11:30:40 +00:00
drh c5c26d7f59 Fix a harmless compiler warning in the randomjson.c extension.
FossilOrigin-Name: a4c93512345f498e3e9aa1673c368bb9b0939b21bd492411b7eff581cd9a709a
2024-03-20 11:25:33 +00:00
drh 27039a32d5 If a term of an ORDER BY or GROUP BY contains an aggregate function or column,
then it is not an alias that needs to be resolved, so don't try to.  This fixes
a harmless assertion found by dbsqlfuzz.

FossilOrigin-Name: e7ba2af5a1ae5d464ad4d4edfdf551bc237168e04784c07a229ba7b28c4f4695
2024-03-20 11:24:11 +00:00
drh 8276a5f336 Fix the SQLITE_ALLOW_ROWID_IN_VIEW bug-compatibility option so that it works
again.  Add the SQLITE_CONFIG_ROWID_IN_VIEW sqlite3_config() value
to optionally disable the bug-compatibility mode at start-time.  Enable
testing of SQLITE_ALLOW_ROWID_IN_VIEW.

FossilOrigin-Name: acc08353e27a960bf949cfc5f94e874a91e1c42fd7a26617dc24cf549fa9b120
2024-03-20 11:04:38 +00:00
drh 0febad8fdf Fix a problem involving infinities int the Kahan-Babushka-Neumaier summation algorithm.
FossilOrigin-Name: 0984e5cd2574780dc1952e3daebafba9ddbb3b4937325117b922fdad0652db57
2024-03-19 10:46:41 +00:00
drh 8d6a941353 Silently ignore redundant ON CONFLICT clauses in an UPSERT.
FossilOrigin-Name: e546d8c68539920ea7b88932e9553d908d6a1956b85e29518ee4f81035987403
2024-03-08 14:16:20 +00:00
drh da3c2bb7db In os_unix.c and os_win.c, do not allow xFetch() to return a pointer to a page buffer that is right at the end of the mapped region - if the database is corrupted in a specific way such a page buffer might be overread by several bytes.
FossilOrigin-Name: 198a1daae01dd9308f91eec1087279481ce0ff632bb3e5ab54cbf3738a903811
2024-01-23 16:21:07 +00:00
stephan 2295e72ef6 Update #ifdef checks in pager.c and util.c to account for [0462a2612d1fc1d0] to resolve the build problem reported in [forum:9819032aac|forum post 9819032aac].
FossilOrigin-Name: 7374c2342e66b352c2098d401e7660b18a0cdf1a69c24386953b1331c2afcbbf
2023-12-22 15:42:09 +00:00
drh 7722f9a60d When unable to resolve an identifier, change the Expr node into TK_NULL
rather than TK_COLUMN, to prevent any downstream misuse of the non-existent
column.

FossilOrigin-Name: 8f770d14d3dca5eb38faa89c4cba269233aa45cc4a56176fdae22f14974ceeb2
2023-12-19 13:00:21 +00:00
drh 1088fc8387 Avoid invoking sqlite3ExprColUsage() on an unresolve column reference.
FossilOrigin-Name: 6e0e2ee7c723582be5ad9126f5cd642c3cecf615c609bc0b87e914a6f5c0c904
2023-12-13 16:50:21 +00:00
stephan fe8d9f4287 Worker1 Promiser API: when multiple db connections are active then use the requested connection instead of always the first-opened connection. Bug reported in [forum:894c330e7f23b177|forum post 894c330e7f23b177].
FossilOrigin-Name: 3874e5a3282888b5b24835194d2f6c7b93f1ef456aa70013218b21038e831ba3
2023-12-12 17:55:20 +00:00
dan 1c6b0e5db9 Different fix for the fts5 COMMIT-following-OOM problem first fixed by [fba3129d]. This one does not cause problems if an fts5 table is renamed and then dropped within the same transaction.
FossilOrigin-Name: 67da596d82ec0ed3c679da3be9d7379c557cd2fb83d7d833556107caf31327f6
2023-12-11 13:48:30 +00:00
drh e467488d36 Increase the patch level to 3.44.3.
FossilOrigin-Name: bb4d35e2628320e187f96ca671cbbf68df51e423e93678b56f18983e93f91b9f
2023-11-29 02:53:53 +00:00
drh 0495cf05a0 Reference count the Table passed into the OP_VCheck opcode.
FossilOrigin-Name: 79e6496bb18246c29970a0da53f2178b6de36c5d1f50da881a6846f188e8c04d
2023-11-29 02:50:31 +00:00
drh c8f9803dc3 Version 3.44.2
FossilOrigin-Name: ebead0e7230cd33bcec9f95d2183069565b9e709bf745c9b5db65cc0cbf92c0f
2023-11-24 11:41:44 +00:00
drh b4b2be91dd Another assertion fault fix, similar to [a9443dbfbe25e588].
FossilOrigin-Name: f796da626b5c3b099cc246a8b46d92839922e34f398d673b0b03d7ee33a28a60
2023-11-23 12:12:54 +00:00
drh 6292bb4fc0 Fix harmless compiler warnings in debugging code.
FossilOrigin-Name: db40272c36c01d5eeb902daed2670d57ee858caae560785350aed2600b573c2d
2023-11-23 11:45:15 +00:00
drh 90d7893739 Fix an fts5 problem that could occur when mixing regular and secure delete operations on a single table.
FossilOrigin-Name: 25fb5a540b1a61e1d0ff3d74ad7135bc53eb3fbe9f5352f98dd22dc7edd063bb
2023-11-23 11:29:00 +00:00
drh efba33ed48 Increase the version number to 3.44.2.
FossilOrigin-Name: 73d3cb790950e317256f500e8bfd707a6156631628a80bcafce494e8bb1e1966
2023-11-23 11:21:20 +00:00
larrybr e6fa99aebd Fix output redirect bug reported in [forum:/forumposts/cbf4933cfeee74bb|the forum].
FossilOrigin-Name: 2ab256bc0bb351c16feaf0d4917ad9c3f55e39821cc7d319d86c6f0752188af7
2023-11-23 07:06:21 +00:00
stephan c028221c3f Correct the URL for loading sqlite3-worker1-bundler-friendly.mjs from sqlite3-worker1-promiser-bundler-friendly.js, so that the promiser can be used in bundler-using environments. Problem reported via email.
FossilOrigin-Name: b1128838f9508ba8e4b735a386c5dd42c1faf84705b95fb069ab724637341170
2023-11-22 17:13:27 +00:00
drh fef8c0b942 Version 3.44.1
FossilOrigin-Name: d295f48e8f367b066b881780c98bdf980a1d550397d5ba0b0e49842c95b3e8b4
2023-11-22 14:18:12 +00:00
larrybr 1c83877d82 Pickup minor stylistic changes related to console I/O and, for Windows builds, get fact of UTF-16 translation into the sign-on banner. (a straight cherry-pick)
FossilOrigin-Name: d7a59e79467cf7aa13291c58f1cc4c1e2a51494bdd28661039421868f61088bd
2023-11-21 18:46:17 +00:00
drh 1dda1e22c9 Back out an incorrect change to the sqlite3ExprCompareSkip() function from
long ago.

FossilOrigin-Name: 89658abbcd04e6f6d5a2139fa92091df1de72e56bdbb12aacebf9e9178c58e3b
2023-11-20 15:58:14 +00:00
larrybr 84548fbd21 Arrange to not compile unused console I/O function.
FossilOrigin-Name: 184a0cd2e855c5177948eaf754c82685e2fcd5a08488d4d3d7b5fc7537e007b4
2023-11-20 13:59:44 +00:00
drh 8fa99e9568 Convert an assert in OP_VCheck into a branch that aborts the opcode, as this
can happen on some very obscure conditions, as discovered by dbsqlfuzz.

FossilOrigin-Name: 0d5f68717c829d4066c6af925c3a71f673ea34f14b1805388d1bdef152864d52
2023-11-20 13:12:05 +00:00
drh 02726b172a Cherry pick additional assert() fixes from trunk into the branch-3.44 branch.
FossilOrigin-Name: 6d8a8b700237d738e7b16dd844cf2514f0df7e2275bd9eab8de0a780e3687298
2023-11-20 12:00:29 +00:00
drh 61d0a37cdf Fix an assert() in fts5 that could be true following an OOM or IO error in contentless-delete mode.
FossilOrigin-Name: 80a0bd7a692b7f08d0fddc5bc2a75e3c8146c54a08c19a70d0e1b6d0e1ac383e
2023-11-20 11:50:22 +00:00
larrybr 4ba9f44d18 Fix test 5.0 in shell1.test for Windows. (A double-quote wrapped single-quote needs no further treatment to be recognized as a single single-quote.)
FossilOrigin-Name: aaa73400c41f382bbbd4ea32ad196d271c7a5e800bfee9afd998037a14fc89b9
2023-11-19 17:33:51 +00:00
larrybr bd0d38f410 Merge changes to do Windows console I/O with UTF-16.
FossilOrigin-Name: f782054e7ccdfb421a73acde6994f5046b99884924a508316a0d4a0dc9b03318
2023-11-18 22:10:40 +00:00
drh eedca24422 Correct conditional compilation issue seen with MSVC in the Win32 mutex subsystem.
FossilOrigin-Name: 6c069c5d664dca7908167e5759f952e407382b2669b25191167ad8d8fb03daa2
2023-11-18 20:24:55 +00:00
larrybr 241677519a Cherrypick changes to simplify and make more rational how console I/O package features are selected.
FossilOrigin-Name: b20c9f1785e94af4b81dcbbc63c49a883ab4095ff251b19e814ab6ef7ff06f2b
2023-11-16 20:50:56 +00:00
larrybr 22402d7d05 Get Fiddle build to succeed. (It runs, too, but not from changes here.)
FossilOrigin-Name: 957ebaa2be3056371d679f7a00aeba242db34218fb839ffd1d1197cad0c4a510
2023-11-15 16:54:49 +00:00
larrybr c283f969aa Changes to console I/O for Fiddle build, to always defer to C library (as before.) A WIP, pending testing with Fiddle build.
FossilOrigin-Name: 45b8061e7568ccca164fe000f1f0a0d984b1c28fad530bc9fdea35793a0f40bc
2023-11-15 15:20:52 +00:00
larrybr 26b57aaed7 Cherry-pick some assert()s to cover misuse of *Put*() from 500+ shell.c callers.
FossilOrigin-Name: c1a53c28a4286c4c52fb78398d4dbf5c03de514a1fa9199bf0cfcd2cd3cc7cd9
2023-11-14 03:31:24 +00:00
larrybr 6edc7ab317 Manual merge of branch-3.44 with 3 sources affected/created by console-io-lib changes.
FossilOrigin-Name: 18ebcf117aad77fa968ff5c537c9b56c1342dea687377a72a02519412a6aa565
2023-11-13 17:45:13 +00:00
drh 937ea25bcc Remove an incorrect ALWAYS() and NEVER().
FossilOrigin-Name: 94f62093866823e013f976db8f80390bee2a9140f4cbec50d1ad8ded28f732ae
2023-11-13 12:05:09 +00:00
drh 2f51f78f97 Fix another problem with mixed join types and the RIGHT JOIN strength-reduction optimization.
FossilOrigin-Name: 8f01f8b260bf70f047a720f1e61e578e500b87bdc2e867f8a8a521068a56c70c
2023-11-10 21:03:37 +00:00
drh a048396674 Fix an obscure problem with the join-strength-reduction optimization that could occur when mixing LEFT and RIGHT joins in the same query.
FossilOrigin-Name: dcf1c1378130538f1820263b4e62d06067d5ab30c07e2584c5c1b5082ede0d56
2023-11-10 15:20:41 +00:00
stephan f78c986679 Expose the missing SQLITE_SUBTYPE to wasm.
FossilOrigin-Name: 7bebfe20e77a2b4edc47debede669fab5af9ed165e5feb59a532fb2c7475fcb0
2023-11-10 15:01:45 +00:00
drh 3414ff463a Ensure 8-byte alignment of data structues in sqlite3_database_file_object().
FossilOrigin-Name: 3cfcaafaff181c7945cc659ff6d58a0d2232d49830a259f0510d833a7a5a824b
2023-11-09 18:41:42 +00:00
stephan 5f61fa6789 Expose SQLITE_RESULT_SUBTYPE to wasm.
FossilOrigin-Name: fc03988650645f0b08f1a3fb85b9ff54a04e0d7d27ca9f063198e43260826278
2023-11-09 17:55:27 +00:00
drh 599e56af76 Add the SQLITE_RESULT_SUBTYPE flag for application-defined functions. Add
the -DSQLITE_STRICT_SUBTYPE=1 compile-time option that raises an error if
any function invokes sqlite3_result_subtype() without the SQLITE_RESULT_SUBTYPE
flag.  SQLITE_RESULT_SUBTYPE prevents an indexed value of that function from
being used to replace an equivalent expression, since the indexed expression
does not carry the subtype.

FossilOrigin-Name: 65a9cfc466d3d904af50fa5eba46d29c5a24e7dde06e5c50c03b343723be7441
2023-11-09 17:42:46 +00:00
drh 5e34405f74 JSON5 bug fix: Escape double-quotes that occur inside of single-quoted strings.
FossilOrigin-Name: 6cc57bb2ce92f64af59c569696d4fbd08183feffaeee560450d13370d60f96d5
2023-11-09 01:56:55 +00:00
drh 6d12b9f850 Update the documentation to the sqlite3_set_auxdata() and sqlite3_get_auxdata()
routines to make it clear that they do not work as one might expect when they
are called during query planning, instead of during query execution.  The JSON
routines misuse those interfaces, so add a special flag to JSON routines that
prevents them from being invoked during query planning.

FossilOrigin-Name: 36259009c5b581ea692e8c86f505783336e4615bb5134e3afd5498f10eb36239
2023-11-07 19:15:55 +00:00
drh a7dc704f70 Update the srctree-check.tcl script and child script so that they can be run
on a read-only source tree and so that if any inconsistencies are found, the
script returns a non-zero exit code and thus halts the build.

FossilOrigin-Name: a0cc7e8117abf03c8d0ab903f1f4b8ff48b6c0e6de85080c9d2a915fd1c16778
2023-11-06 19:08:46 +00:00
drh 9d8ad69b1f Fix an fts5 problem where a transaction consisting of (a) a DELETE on rowid X, (b) a prefix query, and (c) an INSERT on rowid X, could corrupt the index.
FossilOrigin-Name: 34af510a5615339f2963875eab94d4b07725e766c20819f82add19faa229d552
2023-11-06 19:01:25 +00:00
drh 11379c0809 Update the version number to 3.44.1
FossilOrigin-Name: 34f23c3d0d080fef82e3515ecb74257f68878c74fb0bdceac176a004aa1a84e9
2023-11-02 11:14:43 +00:00
drh d9369971ef CLI to compile with older MSVC compiler.
FossilOrigin-Name: c8bf4f7a6a4c4f0f8cd21de25918f4d96f6831a145af4fb63e4b5984f79613b2
2023-11-02 11:08:57 +00:00
122 changed files with 6418 additions and 9757 deletions
+12 -27
View File
@@ -710,21 +710,6 @@ fuzzcheck-asan$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP)
fuzzcheck-ubsan$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP)
$(LTLINK) -o $@ -fsanitize=undefined $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS)
# Usage: FUZZDB=filename make run-fuzzcheck
#
# Where filename is a fuzzcheck database, this target builds and runs
# fuzzcheck, fuzzcheck-asan, and fuzzcheck-ubsan on that database.
#
# FUZZDB can be a glob pattern of two or more databases. Example:
#
# FUZZDB=test/fuzzdata*.db make run-fuzzcheck
#
run-fuzzcheck: fuzzcheck$(TEXE) fuzzcheck-asan$(TEXE) fuzzcheck-ubsan$(TEXE)
@if test "$(FUZZDB)" = ""; then echo 'ERROR: No FUZZDB specified. Rerun with FUZZDB=filename'; exit 1; fi
./fuzzcheck$(TEXE) --spinner $(FUZZDB)
./fuzzcheck-asan$(TEXE) --spinner $(FUZZDB)
./fuzzcheck-ubsan$(TEXE) --spinner $(FUZZDB)
ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h
$(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \
$(TOP)/test/ossfuzz.c sqlite3.c $(TLIBS)
@@ -1150,21 +1135,21 @@ keywordhash.h: $(TOP)/tool/mkkeywordhash.c
# Source files that go into making shell.c
SHELL_SRC = \
$(TOP)/src/shell.c.in \
$(TOP)/ext/consio/console_io.c \
$(TOP)/ext/consio/console_io.h \
$(TOP)/ext/misc/appendvfs.c \
$(TOP)/ext/misc/appendvfs.c \
$(TOP)/ext/misc/completion.c \
$(TOP)/ext/misc/decimal.c \
$(TOP)/ext/misc/basexx.c \
$(TOP)/ext/misc/base64.c \
$(TOP)/ext/misc/base85.c \
$(TOP)/ext/consio/console_io.c \
$(TOP)/ext/consio/console_io.h \
$(TOP)/ext/misc/decimal.c \
$(TOP)/ext/misc/basexx.c \
$(TOP)/ext/misc/base64.c \
$(TOP)/ext/misc/base85.c \
$(TOP)/ext/misc/fileio.c \
$(TOP)/ext/misc/ieee754.c \
$(TOP)/ext/misc/regexp.c \
$(TOP)/ext/misc/series.c \
$(TOP)/ext/misc/ieee754.c \
$(TOP)/ext/misc/regexp.c \
$(TOP)/ext/misc/series.c \
$(TOP)/ext/misc/shathree.c \
$(TOP)/ext/misc/sqlar.c \
$(TOP)/ext/misc/uint.c \
$(TOP)/ext/misc/uint.c \
$(TOP)/ext/expert/sqlite3expert.c \
$(TOP)/ext/expert/sqlite3expert.h \
$(TOP)/ext/misc/zipfile.c \
@@ -1173,7 +1158,7 @@ SHELL_SRC = \
$(TOP)/ext/recover/dbdata.c \
$(TOP)/ext/recover/sqlite3recover.c \
$(TOP)/ext/recover/sqlite3recover.h \
$(TOP)/src/test_windirent.c
$(TOP)/src/test_windirent.c
shell.c: $(SHELL_SRC) $(TOP)/tool/mkshellc.tcl has_tclsh84
$(TCLSH_CMD) $(TOP)/tool/mkshellc.tcl >shell.c
+1 -1
View File
@@ -1 +1 @@
3.45.0
3.44.3
+1 -1
View File
@@ -19,7 +19,7 @@ dnl to configure the system for the local environment.
# so that we create the export library with the dll.
#-----------------------------------------------------------------------
AC_INIT([sqlite],[3.45.0])
AC_INIT([sqlite],[3.44.3])
#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
Vendored
+9 -9
View File
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for sqlite 3.45.0.
# Generated by GNU Autoconf 2.69 for sqlite 3.44.3.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -726,8 +726,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite'
PACKAGE_VERSION='3.45.0'
PACKAGE_STRING='sqlite 3.45.0'
PACKAGE_VERSION='3.44.3'
PACKAGE_STRING='sqlite 3.44.3'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -1472,7 +1472,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures sqlite 3.45.0 to adapt to many kinds of systems.
\`configure' configures sqlite 3.44.3 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1537,7 +1537,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.45.0:";;
short | recursive ) echo "Configuration of sqlite 3.44.3:";;
esac
cat <<\_ACEOF
@@ -1668,7 +1668,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
sqlite configure 3.45.0
sqlite configure 3.44.3
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2087,7 +2087,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by sqlite $as_me 3.45.0, which was
It was created by sqlite $as_me 3.44.3, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -12481,7 +12481,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by sqlite $as_me 3.45.0, which was
This file was extended by sqlite $as_me 3.44.3, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -12547,7 +12547,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
sqlite config.status 3.45.0
sqlite config.status 3.44.3
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
+1 -1
View File
@@ -74,7 +74,7 @@
# you don't need (for example BLT) by erasing or commenting out
# the corresponding code.
#
AC_INIT([sqlite],m4_esyscmd(cat VERSION | tr -d '\n'))
AC_INIT([sqlite],[m4_esyscmd(cat VERSION | tr -d '\n')])
dnl Make sure the local VERSION file matches this configure script
sqlite_version_sanity_check=`cat $srcdir/VERSION | tr -d '\n'`
+1 -13
View File
@@ -1,7 +1,7 @@
# 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-11-01:
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.
@@ -84,18 +84,6 @@ following minor changes:
<li> `set PATH=c:\tcl32\bin;%PATH%`
</ul>
## Building a DLL
The command the developers use for building the deliverable DLL on the
[download page](https://sqlite.org/download.html) is as follows:
> ~~~~
nmake /f Makefile.msc sqlite3.dll USE_NATIVE_LIBPATHS=1 "OPTS=-DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS4=1 -DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_JSON1=1 -DSQLITE_ENABLE_GEOPOLY=1 -DSQLITE_ENABLE_SESSION=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 -DSQLITE_ENABLE_SERIALIZE=1 -DSQLITE_ENABLE_MATH_FUNCTIONS=1"
~~~~
That command generates both the sqlite3.dll and sqlite3.def files. The same
command works for both 32-bit and 64-bit builds.
## Statically Linking The TCL Library
Some utility programs associated with SQLite need to be linked
+9 -69
View File
@@ -2,26 +2,6 @@
# The testrunner.tcl Script
<ul type=none>
<li> 1. <a href=#overview>Overview</a>
<li> 2. <a href=#binary_tests>Binary Tests</a>
<ul type=none>
<li> 2.1. <a href=#organization_tests>Organization of Tcl Tests</a>
<li> 2.2. <a href=#run_tests>Commands to Run Tests</a>
<li> 2.3. <a href=#binary_test_failures>Investigating Binary Test Failures</a>
</ul>
<li> 3. <a href=#source_code_tests>Source Tests</a>
<ul type=none>
<li> 3.1. <a href=#commands_to_run_tests>Commands to Run SQLite Tests</a>
<li> 3.2. <a href=#zipvfs_tests>Running ZipVFS Tests</a>
<li> 3.3. <a href=#source_code_test_failures>Investigating Source Code Test Failures</a>
</ul>
<li> 4. <a href=#testrunner_options>Extra testrunner.tcl Options</a>
# 4. Extra testrunner.tcl Options
<li> 5. <a href=#cpu_cores>Controlling CPU Core Utilization</a>
</ul>
<a name=overview></a>
# 1. Overview
testrunner.tcl is a Tcl script used to run multiple SQLite tests using
@@ -64,7 +44,6 @@ Sometimes testrunner.tcl uses the [testfixture] binary that it is run with
to run tests (see "Binary Tests" below). Sometimes it builds testfixture and
other binaries in specific configurations to test (see "Source Tests").
<a name=binary_tests></a>
# 2. Binary Tests
The commands described in this section all run various combinations of the Tcl
@@ -82,7 +61,6 @@ these tests is therefore:
The following sub-sections describe the various options that can be
passed to testrunner.tcl to test binary testfixture builds.
<a name=organization_tests></a>
## 2.1. Organization of Tcl Tests
Tcl tests are stored in files that match the pattern *\*.test*. They are
@@ -113,7 +91,6 @@ Running **all** tests is to run all tests in the full test set, plus a dozen
or so permutations. The specific permutations that are run as part of "all"
are defined in file *testrunner_data.tcl*.
<a name=run_tests></a>
## 2.2. Commands to Run Tests
To run the "veryquick" test set, use either of the following:
@@ -137,12 +114,6 @@ a specified pattern (e.g. all tests that start with "fts5"), either of:
./testfixture $TESTDIR/testrunner.tcl 'fts5*'
```
Strictly speaking, for a test to be run the pattern must match the script
filename, not including the directory, using the rules of Tcl's
\[string match\] command. Except that before the matching is done, any "%"
characters specified as part of the pattern are transformed to "\*".
To run "all" tests (full + permutations):
```
@@ -170,7 +141,6 @@ Or, if the failure occured as part of a permutation:
TODO: An example instead of "$PERMUTATION" and $PATH\_TO\_SCRIPT?
<a name=source_code_tests></a>
# 3. Source Code Tests
The commands described in this section invoke the C compiler to build
@@ -189,8 +159,7 @@ shell that supports SQLite 3.31.1 or newer via "package require sqlite3".
TODO: ./configure + Makefile.msc build systems.
<a name=commands_to_run_tests></a>
## 3.1. Commands to Run SQLite Tests
## Commands to Run SQLite Tests
The **mdevtest** command is equivalent to running the veryquick tests and
the [make fuzztest] target once for each of two --enable-all builds - one
@@ -232,18 +201,7 @@ of the specific tests run.
tclsh $TESTDIR/testrunner.tcl release
```
As with <a href=#source code tests>source code tests</a>, one or more patterns
may be appended to any of the above commands (mdevtest, sdevtest or release).
In that case only Tcl tests (no fuzz or other tests) that match the specified
pattern are run. For example, to run the just the Tcl rtree tests in all
builds and configurations supported by "release":
```
tclsh $TESTDIR/testrunner.tcl release rtree%
```
<a name=zipvfs_tests></a>
## 3.2. Running ZipVFS Tests
## Running ZipVFS Tests
testrunner.tcl can build a zipvfs-enabled testfixture and use it to run
tests from the Zipvfs project with the following command:
@@ -259,8 +217,7 @@ test both SQLite and Zipvfs with a single command:
tclsh $TESTDIR/testrunner.tcl --zipvfs $PATH_TO_ZIPVFS mdevtest
```
<a name=source_code_test_failures></a>
## 3.3. Investigating Source Code Test Failures
## Investigating Source Code Test Failures
Investigating a test failure that occurs during source code testing is a
two step process:
@@ -287,31 +244,9 @@ target to build. This may be used either to run a [make] command test directly,
or else to build a testfixture (or testfixture.exe) binary with which to
run a Tcl test script, as <a href=#binary_test_failures>described above</a>.
<a name=testrunner_options></a>
# 4. Extra testrunner.tcl Options
The testrunner.tcl script options in this section may be used with both source
code and binary tests.
The **--buildonly** option instructs testrunner.tcl just to build the binaries
required by a test, not to run any actual tests. For example:
```
# Build binaries required by release test.
tclsh $TESTDIR/testrunner.tcl --buildonly release"
```
The **--dryrun** option prevents testrunner.tcl from building any binaries
or running any tests. Instead, it just writes the shell commands that it
would normally execute into the testrunner.log file. Example:
```
# Log the shell commmands that make up the mdevtest test.
tclsh $TESTDIR/testrunner.tcl --dryrun mdevtest"
```
<a name=cpu_cores></a>
# 5. Controlling CPU Core Utilization
# 4. Controlling CPU Core Utilization
When running either binary or source code tests, testrunner.tcl reports the
number of jobs it intends to use to stdout. e.g.
@@ -342,3 +277,8 @@ testrunner.log and testrunner.db files:
+9 -8
View File
@@ -549,11 +549,12 @@ zSkipValidUtf8(const char *z, int nAccept, long ccm){
#endif /*!(defined(SQLITE_CIO_NO_UTF8SCAN)&&defined(SQLITE_CIO_NO_TRANSLATE))*/
#ifndef SQLITE_CIO_NO_TRANSLATE
# ifdef CONSIO_SPUTB
#ifdef CONSIO_SPUTB
SQLITE_INTERNAL_LINKAGE int
fPutbUtf8(FILE *pfO, const char *cBuf, int nAccept){
assert(pfO!=0);
# if CIO_WIN_WC_XLATE
# if CIO_WIN_WC_XLATE
PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */
PerStreamTags *ppst = getEmitStreamInfo(0, &pst, &pfO);
if( pstReachesConsole(ppst) ){
@@ -563,13 +564,13 @@ fPutbUtf8(FILE *pfO, const char *cBuf, int nAccept){
if( 0 == isKnownWritable(ppst->pf) ) restoreConsoleArb(ppst);
return rv;
}else {
# endif
return (int)fwrite(cBuf, 1, nAccept, pfO);
# if CIO_WIN_WC_XLATE
}
# endif
}
# endif
return (int)fwrite(cBuf, 1, nAccept, pfO);
# if CIO_WIN_WC_XLATE
}
# endif
}
#endif /* defined(CONSIO_SPUTB) */
SQLITE_INTERNAL_LINKAGE int
oPutbUtf8(const char *cBuf, int nAccept){
+1 -1
View File
@@ -166,8 +166,8 @@ SQLITE_INTERNAL_LINKAGE int ePutsUtf8(const char *z);
#ifdef CONSIO_SPUTB
SQLITE_INTERNAL_LINKAGE int
fPutbUtf8(FILE *pfOut, const char *cBuf, int nAccept);
/* Like fPutbUtf8 except stream is always the designated output. */
#endif
/* Like fPutbUtf8 except stream is always the designated output. */
SQLITE_INTERNAL_LINKAGE int
oPutbUtf8(const char *cBuf, int nAccept);
/* Like fPutbUtf8 except stream is always the designated error. */
-8
View File
@@ -211,14 +211,6 @@ static int fts5HighlightCb(
}
if( iPos==p->iRangeEnd ){
if( p->bOpen ){
if( p->iter.iStart>=0 && iPos>=p->iter.iStart ){
fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff);
p->iOff = iEndOff;
}
fts5HighlightAppend(&rc, p, p->zClose, -1);
p->bOpen = 0;
}
fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff);
p->iOff = iEndOff;
}
+10 -2
View File
@@ -357,6 +357,7 @@ struct Fts5Index {
/* Error state. */
int rc; /* Current error code */
int flushRc;
/* State used by the fts5DataXXX() functions. */
sqlite3_blob *pReader; /* RO incr-blob open on %_data table */
@@ -4002,6 +4003,7 @@ static void fts5IndexDiscardData(Fts5Index *p){
sqlite3Fts5HashClear(p->pHash);
p->nPendingData = 0;
p->nPendingRow = 0;
p->flushRc = SQLITE_OK;
}
p->nContentlessDelete = 0;
}
@@ -5584,6 +5586,10 @@ static void fts5FlushOneHash(Fts5Index *p){
*/
static void fts5IndexFlush(Fts5Index *p){
/* Unless it is empty, flush the hash table to disk */
if( p->flushRc ){
p->rc = p->flushRc;
return;
}
if( p->nPendingData || p->nContentlessDelete ){
assert( p->pHash );
fts5FlushOneHash(p);
@@ -5592,6 +5598,8 @@ static void fts5IndexFlush(Fts5Index *p){
p->nPendingData = 0;
p->nPendingRow = 0;
p->nContentlessDelete = 0;
}else if( p->nPendingData || p->nContentlessDelete ){
p->flushRc = p->rc;
}
}
}
@@ -7251,7 +7259,7 @@ static void fts5IndexIntegrityCheckEmpty(
}
static void fts5IntegrityCheckPgidx(Fts5Index *p, Fts5Data *pLeaf){
int iTermOff = 0;
i64 iTermOff = 0;
int ii;
Fts5Buffer buf1 = {0,0,0};
@@ -7260,7 +7268,7 @@ static void fts5IntegrityCheckPgidx(Fts5Index *p, Fts5Data *pLeaf){
ii = pLeaf->szLeaf;
while( ii<pLeaf->nn && p->rc==SQLITE_OK ){
int res;
int iOff;
i64 iOff;
int nIncr;
ii += fts5GetVarint32(&pLeaf->p[ii], nIncr);
+12 -25
View File
@@ -118,7 +118,7 @@ struct Fts5FullTable {
Fts5Global *pGlobal; /* Global (connection wide) data */
Fts5Cursor *pSortCsr; /* Sort data from this cursor */
int iSavepoint; /* Successful xSavepoint()+1 */
int bInSavepoint;
#ifdef SQLITE_DEBUG
struct Fts5TransactionState ts;
#endif
@@ -1573,7 +1573,10 @@ static int fts5SpecialInsert(
}else if( 0==sqlite3_stricmp("flush", zCmd) ){
rc = sqlite3Fts5FlushToDisk(&pTab->p);
}else{
rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
rc = sqlite3Fts5FlushToDisk(&pTab->p);
if( rc==SQLITE_OK ){
rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
}
if( rc==SQLITE_OK ){
rc = sqlite3Fts5ConfigSetValue(pTab->p.pConfig, zCmd, pVal, &bError);
}
@@ -2615,9 +2618,7 @@ static int fts5RenameMethod(
){
int rc;
Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
pTab->bInSavepoint = 1;
rc = sqlite3Fts5StorageRename(pTab->pStorage, zName);
pTab->bInSavepoint = 0;
return rc;
}
@@ -2634,26 +2635,12 @@ int sqlite3Fts5FlushToDisk(Fts5Table *pTab){
static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
int rc = SQLITE_OK;
char *zSql = 0;
fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint);
if( pTab->bInSavepoint==0 ){
zSql = sqlite3_mprintf("INSERT INTO %Q.%Q(%Q) VALUES('flush')",
pTab->p.pConfig->zDb, pTab->p.pConfig->zName, pTab->p.pConfig->zName
);
if( zSql ){
pTab->bInSavepoint = 1;
rc = sqlite3_exec(pTab->p.pConfig->db, zSql, 0, 0, 0);
pTab->bInSavepoint = 0;
sqlite3_free(zSql);
}else{
rc = SQLITE_NOMEM;
}
if( rc==SQLITE_OK ){
pTab->iSavepoint = iSavepoint+1;
}
rc = sqlite3Fts5FlushToDisk((Fts5Table*)pVtab);
if( rc==SQLITE_OK ){
pTab->iSavepoint = iSavepoint+1;
}
return rc;
}
@@ -2685,8 +2672,8 @@ static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){
int rc = SQLITE_OK;
fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint);
fts5TripCursors(pTab);
pTab->p.pConfig->pgsz = 0;
if( (iSavepoint+1)<=pTab->iSavepoint ){
pTab->p.pConfig->pgsz = 0;
rc = sqlite3Fts5StorageRollback(pTab->pStorage);
}
return rc;
@@ -2914,7 +2901,7 @@ static int fts5ShadowName(const char *zName){
** if anything is found amiss. Return a NULL pointer if everything is
** OK.
*/
static int fts5Integrity(
static int fts5IntegrityMethod(
sqlite3_vtab *pVtab, /* the FTS5 virtual table to check */
const char *zSchema, /* Name of schema in which this table lives */
const char *zTabname, /* Name of the table itself */
@@ -2972,7 +2959,7 @@ static int fts5Init(sqlite3 *db){
/* xRelease */ fts5ReleaseMethod,
/* xRollbackTo */ fts5RollbackToMethod,
/* xShadowName */ fts5ShadowName,
/* xIntegrity */ fts5Integrity
/* xIntegrity */ fts5IntegrityMethod
};
int rc;
+26 -69
View File
@@ -229,12 +229,6 @@ static const unsigned char sqlite3Utf8Trans1[] = {
#endif /* ifndef SQLITE_AMALGAMATION */
#define FTS5_SKIP_UTF8(zIn) { \
if( ((unsigned char)(*(zIn++)))>=0xc0 ){ \
while( (((unsigned char)*zIn) & 0xc0)==0x80 ){ zIn++; } \
} \
}
typedef struct Unicode61Tokenizer Unicode61Tokenizer;
struct Unicode61Tokenizer {
unsigned char aTokenChar[128]; /* ASCII range token characters */
@@ -1270,7 +1264,6 @@ static int fts5PorterTokenize(
typedef struct TrigramTokenizer TrigramTokenizer;
struct TrigramTokenizer {
int bFold; /* True to fold to lower-case */
int iFoldParam; /* Parameter to pass to Fts5UnicodeFold() */
};
/*
@@ -1297,7 +1290,6 @@ static int fts5TriCreate(
}else{
int i;
pNew->bFold = 1;
pNew->iFoldParam = 0;
for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
const char *zArg = azArg[i+1];
if( 0==sqlite3_stricmp(azArg[i], "case_sensitive") ){
@@ -1306,21 +1298,10 @@ static int fts5TriCreate(
}else{
pNew->bFold = (zArg[0]=='0');
}
}else if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){
rc = SQLITE_ERROR;
}else{
pNew->iFoldParam = (zArg[0]!='0') ? 2 : 0;
}
}else{
rc = SQLITE_ERROR;
}
}
if( pNew->iFoldParam!=0 && pNew->bFold==0 ){
rc = SQLITE_ERROR;
}
if( rc!=SQLITE_OK ){
fts5TriDelete((Fts5Tokenizer*)pNew);
pNew = 0;
@@ -1343,62 +1324,40 @@ static int fts5TriTokenize(
TrigramTokenizer *p = (TrigramTokenizer*)pTok;
int rc = SQLITE_OK;
char aBuf[32];
char *zOut = aBuf;
int ii;
const unsigned char *zIn = (const unsigned char*)pText;
const unsigned char *zEof = &zIn[nText];
u32 iCode;
int aStart[3]; /* Input offset of each character in aBuf[] */
UNUSED_PARAM(unusedFlags);
/* Populate aBuf[] with the characters for the first trigram. */
for(ii=0; ii<3; ii++){
do {
aStart[ii] = zIn - (const unsigned char*)pText;
READ_UTF8(zIn, zEof, iCode);
if( iCode==0 ) return SQLITE_OK;
if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam);
}while( iCode==0 );
WRITE_UTF8(zOut, iCode);
}
/* At the start of each iteration of this loop:
**
** aBuf: Contains 3 characters. The 3 characters of the next trigram.
** zOut: Points to the byte following the last character in aBuf.
** aStart[3]: Contains the byte offset in the input text corresponding
** to the start of each of the three characters in the buffer.
*/
assert( zIn<=zEof );
while( 1 ){
int iNext; /* Start of character following current tri */
const char *z1;
char *zOut = aBuf;
int iStart = zIn - (const unsigned char*)pText;
const unsigned char *zNext;
/* Read characters from the input up until the first non-diacritic */
do {
iNext = zIn - (const unsigned char*)pText;
READ_UTF8(zIn, zEof, iCode);
if( iCode==0 ) break;
zNext = zIn;
if( zIn<zEof ){
if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0);
WRITE_UTF8(zOut, iCode);
READ_UTF8(zIn, zEof, iCode);
if( iCode==0 ) break;
if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam);
}while( iCode==0 );
/* Pass the current trigram back to fts5 */
rc = xToken(pCtx, 0, aBuf, zOut-aBuf, aStart[0], iNext);
if( iCode==0 || rc!=SQLITE_OK ) break;
/* Remove the first character from buffer aBuf[]. Append the character
** with codepoint iCode. */
z1 = aBuf;
FTS5_SKIP_UTF8(z1);
memmove(aBuf, z1, zOut - z1);
zOut -= (z1 - aBuf);
WRITE_UTF8(zOut, iCode);
/* Update the aStart[] array */
aStart[0] = aStart[1];
aStart[1] = aStart[2];
aStart[2] = iNext;
}else{
break;
}
if( zIn<zEof ){
if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0);
WRITE_UTF8(zOut, iCode);
READ_UTF8(zIn, zEof, iCode);
if( iCode==0 ) break;
if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0);
WRITE_UTF8(zOut, iCode);
}else{
break;
}
rc = xToken(pCtx, 0, aBuf, zOut-aBuf, iStart, iStart + zOut-aBuf);
if( rc!=SQLITE_OK ) break;
zIn = zNext;
}
return rc;
@@ -1421,9 +1380,7 @@ int sqlite3Fts5TokenizerPattern(
){
if( xCreate==fts5TriCreate ){
TrigramTokenizer *p = (TrigramTokenizer*)pTok;
if( p->iFoldParam==0 ){
return p->bFold ? FTS5_PATTERN_LIKE : FTS5_PATTERN_GLOB;
}
return p->bFold ? FTS5_PATTERN_LIKE : FTS5_PATTERN_GLOB;
}
return FTS5_PATTERN_NONE;
}
+229 -1
View File
@@ -966,6 +966,234 @@ do_catchsql_test 6.2 {
UPDATE t1 SET content=randomblob(500) WHERE t1;
} {1 {constraint failed}}
#-------------------------------------------------------------------------
reset_db
do_test 9.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
.open --hexdb
| size 32768 pagesize 4096 filename crash-c76a16c24c8ba6.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 08 .....@ ........
| 32: 00 00 00 02 00 00 00 01 00 00 00 09 00 00 00 04 ................
| 96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36 ...............6
| 112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 0d 92 00 00 00 00 ...k............
| 3472: 00 00 22 08 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet
| 3488: 32 74 32 08 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE
| 3504: 20 74 32 28 78 29 56 07 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta
| 3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c
| 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB
| 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k
| 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v)
| 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[.
| 3600: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d
| 3616: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize
| 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't
| 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN
| 3664: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE
| 3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21 Y, sz BLOB)^...!
| 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont
| 3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52 entt1_content.CR
| 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c
| 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG
| 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
| 3776: 63 30 2c 20 63 31 2c 20 63 32 29 69 04 07 17 19 c0, c1, c2)i....
| 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt
| 3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42 1_idx.CREATE TAB
| 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi
| 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P
| 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid
| 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT
| 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t
| 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61 ablet1_datat1_da
| 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE
| 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT
| 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY
| 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8..
| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR
| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB
| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5
| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c).........
| page 3 offset 8192
| 0: 0d 00 00 00 03 0c 94 00 0f e6 0f ef 0c 94 00 00 ................
| 3216: 00 00 00 00 86 4a 84 80 80 80 80 01 04 00 8d 18 .....J..........
| 3232: 00 00 03 2b 02 30 30 01 02 06 01 02 06 01 02 06 ...+.00.........
| 3248: 1f 02 03 01 02 03 01 02 03 01 08 32 30 31 36 30 ...........20160
| 3264: 36 30 39 01 02 07 01 02 07 01 02 07 01 01 34 01 609...........4.
| 3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 04 01 02 ..........5.....
| 3296: 04 01 02 04 02 07 30 30 30 30 30 30 30 1c 02 04 ......0000000...
| 3312: 01 02 04 01 02 04 01 06 62 69 6e 61 72 79 03 06 ........binary..
| 3328: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 3344: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 3360: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 3376: 03 06 01 02 02 03 06 01 02 02 01 08 63 6f 6d 70 ............comp
| 3392: 69 6c 65 72 01 02 02 01 02 02 01 02 02 01 06 64 iler...........d
| 3408: 62 73 74 61 74 07 02 03 01 02 03 01 02 03 02 04 bstat...........
| 3424: 65 62 75 67 04 02 02 01 02 02 01 02 02 01 06 65 ebug...........e
| 3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 02 02 01 02 nable...........
| 3456: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
| 3472: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
| 3488: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
| 3504: 02 01 02 02 02 08 78 74 65 6e 73 69 6f 6e 1f 02 ......xtension..
| 3520: 04 01 02 04 01 02 04 01 04 66 74 73 34 0a 02 03 .........fts4...
| 3536: 01 02 03 01 02 03 04 01 35 0d 02 03 01 02 03 01 ........5.......
| 3552: 02 03 01 03 67 63 63 01 02 03 01 02 03 01 02 03 ....gcc.........
| 3568: 02 06 65 6f 70 6f 6c 79 10 02 03 01 02 03 01 02 ..eopoly........
| 3584: 03 01 05 6a 73 6f 6e 31 13 02 03 01 02 03 01 02 ...json1........
| 3600: 03 01 04 6c 6f 61 64 1f 02 03 01 02 03 01 02 03 ...load.........
| 3616: 01 03 6d 61 78 1c 02 02 01 02 02 01 02 02 02 05 ..max...........
| 3632: 65 6d 6f 72 79 1c 02 03 01 02 03 01 02 03 04 04 emory...........
| 3648: 73 79 73 35 16 02 03 01 02 03 01 02 03 01 06 6e sys5...........n
| 3664: 6f 63 61 73 65 02 06 01 02 02 03 06 01 02 02 03 ocase...........
| 3680: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 3696: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 3712: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 3728: 02 01 04 6f 6d 69 74 1f 02 02 01 02 02 01 02 02 ...omit.........
| 3744: 01 05 72 74 72 65 65 19 02 03 01 02 03 01 02 03 ..rtree.........
| 3760: 04 02 69 6d 01 06 01 02 02 03 06 01 02 02 03 06 ..im............
| 3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 3792: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 3824: 01 0a 74 68 72 65 61 64 73 61 66 65 03 57 34 56 ..threadsafe.W4V
| 3840: 94 64 91 46 85 84 04 76 74 61 62 07 02 04 01 02 .d.F...vtab.....
| 3856: 04 01 02 04 01 01 78 01 06 01 01 02 01 06 01 01 ......x.........
| 3872: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 10 02 ................
| 3888: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3904: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 3920: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 3936: 01 02 01 06 01 01 10 01 06 01 01 02 01 06 01 01 ................
| 3952: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 3968: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3984: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 4000: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 4016: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 4032: 02 01 06 01 01 02 01 06 01 01 02 04 15 13 0c 0c ................
| 4048: 12 44 13 11 0f 47 13 0f 0c 0e 11 10 0f 0e 10 0f .D...G..........
| 4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 24 24 0f D..@.......$Z$$.
| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............
| page 4 offset 12288
| 0: 0a 00 00 00 01 0f fa 00 00 00 00 00 00 00 00 00 ................
| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................
| page 5 offset 16384
| 0: 0d 00 00 00 24 0c 0a 00 0f d8 0f af 0f 86 0f 74 ....$..........t
| 16: 0f 61 0f 4e 0f 2f 0f 0f 0e ef 0e d7 0e be 0e a5 .a.N./..........
| 32: 0e 8d 0e 74 0e 5b 0e 40 0e 24 0e 08 0d ef 0d d5 ...t.[.@.$......
| 48: 0d bb 0d a0 0d 84 0d 68 0d 4f 0d 35 0d 1b 0c fb .......h.O.5....
| 64: 0c da 0c b9 0c 99 0c 78 0c 57 0c 3e 0c 24 0c 0a .......x.W.>.$..
| 3072: 00 00 00 00 00 00 00 00 00 00 18 24 05 00 25 0f ...........$..%.
| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI
| 3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 NARY.#..%..THREA
| 3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 45 17 22 DSAFE=0XNOCASE..
| 3136: 05 00 25 0f 17 54 48 52 45 41 44 53 31 46 45 3d ..%..THREADS1FE=
| 3152: 30 58 52 64 52 49 4d 1f 21 05 00 33 0f 19 4f 4d 0XRdRIM.!..3..OM
| 3168: 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 4f IT LOAD EXTENSIO
| 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O
| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 MIT LOAD EXTENSI
| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3..
| 3232: 4f 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMIT LOAD EXTENS
| 3248: 49 4f 4e 58 52 54 52 49 4d 1f 1e 05 00 33 0f 19 IONXRTRIM....3..
| 3264: 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30 MAX MEMORY=50000
| 3280: 30 30 30 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f 000XBINARY....3.
| 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 .MAX MEMORY=5000
| 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 33 0000XNOCASE....3
| 3328: 0f 17 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 ..MAX MEMORY=500
| 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25 00000XRTRIM....%
| 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB
| 3376: 49 4e 41 52 59 18 1a 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
| 3392: 4c 45 20 52 54 52 45 45 58 4e 4f 43 41 53 45 17 LE RTREEXNOCASE.
| 3408: 19 05 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52 ...%..ENABLE RTR
| 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E
| 3440: 4e 41 42 4b 45 20 4d 45 4d 53 59 53 35 58 42 49 NABKE MEMSYS5XBI
| 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL
| 3472: 42 60 2d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 B`-EMSYS5XNOCASE
| 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 45 ....)..ENABLE ME
| 3504: 4d 53 59 53 35 58 52 54 52 49 4d 18 15 05 00 25 MSYS5XRTRIM....%
| 3520: 0f 19 45 4e 41 42 4c 45 20 4a 53 4f 4e 31 58 42 ..ENABLE JSON1XB
| 3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
| 3552: 4c 45 20 4a 53 4f 4e 31 58 4e 4f 43 41 53 45 17 LE JSON1XNOCASE.
| 3568: 13 05 00 25 0f 17 45 4e 41 42 4c 45 20 4a 53 4f ...%..ENABLE JSO
| 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45 N1XRTRIM....)..E
| 3600: 4e 41 42 4c 45 20 47 45 4f 50 4f 4c 59 58 42 49 NABLE GEOPOLYXBI
| 3616: 4e 41 52 59 1a 11 05 00 39 0f 19 45 4e 41 42 4c NARY....9..ENABL
| 3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 43 41 53 45 E GEOPOLYXNOCASE
| 3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45 ....)..ENABLE GE
| 3664: 4f 50 4f 4c 59 58 52 54 52 49 4d 17 0f 05 00 23 OPOLYXRTRIM....#
| 3680: 0f 19 45 4e 41 42 4c 45 20 46 54 53 35 58 42 49 ..ENABLE FTS5XBI
| 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c NARY....#..ENABL
| 3712: 45 20 46 54 53 35 58 4e 4f 43 41 53 45 16 0d 05 E FTS5XNOCASE...
| 3728: 00 23 0f 17 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X
| 3744: 52 54 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB
| 3760: 4c 45 20 46 54 53 34 58 42 49 4e 41 52 59 17 0b LE FTS4XBINARY..
| 3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 34 ..#..ENABLE FTS4
| 3792: 58 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e XNOCASE....#..EN
| 3808: 41 42 4c 45 20 46 54 53 34 58 52 54 52 49 4d 1e ABLE FTS4XRTRIM.
| 3824: 09 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
| 3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAT VTABXBINARY.
| 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
| 3872: 54 41 54 20 56 54 24 15 48 4e 4f 43 41 53 45 1d TAT VT$.HNOCASE.
| 3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
| 3904: 54 41 54 20 56 54 41 42 58 52 54 52 49 4d 11 06 TAT VTABXRTRIM..
| 3920: 05 00 17 0f 19 44 45 42 55 47 58 42 49 4e 41 52 .....DEBUGXBINAR
| 3936: 59 11 05 05 00 17 0f 19 44 45 42 55 47 58 4e 4f Y.......DEBUGXNO
| 3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 47 CASE.......DEBUG
| 3968: 58 52 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d XRTRIM'...C..COM
| 3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PILER=gcc-5.4.0
| 4000: 32 30 31 36 30 36 30 39 58 42 49 4e 41 52 59 27 20160609XBINARY'
| 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3c 67 ...C..COMPILER<g
| 4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 36 30 cc-5.4.0 2016060
| 4048: 39 58 4e 4f 43 41 53 45 26 01 05 00 43 0f 17 43 9XNOCASE&...C..C
| 4064: 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e OMPILER=gcc-5.4.
| 4080: 30 20 32 30 31 36 30 36 30 39 58 52 54 52 49 4d 0 20160609XRTRIM
| page 6 offset 20480
| 0: 0d 00 00 00 24 0e e0 00 0f f8 0f f0 0f e8 0f e0 ....$...........
| 16: 0f d8 0f d0 0f c8 0f c0 0f b8 0f b0 0f a8 0f a0 ................
| 32: 1f 98 0f 90 0f 88 0f 80 0f 78 0f 70 0f 68 0f 60 .........x.p.h.`
| 48: 0f 58 0f 50 0f 48 0f 40 0f 38 0f 30 0f 28 0f 20 .X.P.H.@.8.0.(.
| 64: 0f 18 0f 10 0f 08 0f 00 0e f8 0e f0 0e e8 0e e0 ................
| 3808: 06 24 03 00 12 02 01 01 06 23 03 00 12 02 01 01 .$.......#......
| 3824: 06 22 03 00 12 02 01 01 06 21 03 00 12 03 01 01 .........!......
| 3840: 06 20 03 00 12 03 01 01 06 1f 03 00 12 03 01 01 . ..............
| 3856: 06 1e 03 00 12 03 01 01 06 1d 03 00 12 03 01 01 ................
| 3872: 06 1c 03 00 12 03 01 01 06 1b 03 00 12 02 01 01 ................
| 3888: 06 1a 03 00 12 02 01 01 06 19 03 00 12 02 01 01 ................
| 3904: 06 18 03 00 12 02 01 01 06 17 03 00 12 02 01 01 ................
| 3920: 06 15 f3 00 12 02 01 01 06 15 03 00 12 02 01 01 ................
| 3936: 06 14 03 00 12 02 01 01 06 13 03 00 12 02 01 01 ................
| 3952: 06 12 03 00 12 02 01 01 06 11 03 00 12 02 01 01 ................
| 3968: 06 10 03 00 12 02 01 01 06 0f 03 00 12 02 01 01 ................
| 3984: 06 0e 03 00 12 02 01 01 06 0d 03 00 12 02 01 01 ................
| 4000: 06 0c 03 00 12 02 01 01 06 0b 03 00 12 02 01 01 ................
| 4016: 06 0a 03 00 12 02 01 01 06 09 03 00 12 03 01 01 ................
| 4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01 ................
| 4048: 06 06 03 00 12 01 01 01 06 05 03 00 12 01 01 01 ................
| 4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01 ................
| 4080: 06 02 03 00 12 06 01 01 06 01 03 00 12 06 01 01 ................
| page 7 offset 24576
| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................
| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
| page 8 offset 28672
| 0: 0d 00 00 00 03 0f d6 00 0f f4 0f e9 0f d6 00 00 ................
| 4048: 00 00 00 00 00 00 11 03 02 2b 69 6e 74 65 67 72 .........+integr
| 4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62 ity-check....reb
| 4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 00 00 00 00 uild....opti....
| end crash-c76a16c24c8ba6.db
}]} {}
#.testctrl prng_seed 1 db
#.testctrl internal_functions
#.testctrl json_selfcheck on
#
do_execsql_test 9.1 {
UPDATE t1 SET b=quote(zeroblob(current_date)) WHERE t1 MATCH 't*';
SAVEPOINT a;
UPDATE t1 SET b=quote(zeroblob(current_date)) WHERE t1 MATCH 't*';
INSERT INTO t1(t1,rank) VALUES('secure-delete',1);
}
do_catchsql_test 9.2 {
DELETE FROM t1;
} {1 {database disk image is malformed}}
sqlite3_fts5_may_be_corrupt 0
finish_test
+35 -1
View File
@@ -91,7 +91,6 @@ do_execsql_test 2.2.1 {
INSERT INTO vt0(c0) VALUES ('xyz');
}
breakpoint
do_execsql_test 2.2.2 {
ALTER TABLE t0 RENAME TO t1;
}
@@ -500,6 +499,41 @@ do_execsql_test 17.5 {
SELECT c0 FROM t0 WHERE c0 GLOB '*faul*';
} {assertionfaultproblem}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 18.0 {
BEGIN;
CREATE VIRTUAL TABLE t1 USING fts5(text);
ALTER TABLE t1 RENAME TO t2;
}
do_execsql_test 18.1 {
DROP TABLE t2;
}
do_execsql_test 18.2 {
COMMIT;
}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 19.0 {
CREATE VIRTUAL TABLE t1 USING fts5(text);
CREATE TABLE t2(text);
BEGIN;
INSERT INTO t1 VALUES('one');
INSERT INTO t1 VALUES('two');
INSERT INTO t1 VALUES('three');
INSERT INTO t1 VALUES('one');
INSERT INTO t1 VALUES('two');
INSERT INTO t1 VALUES('three');
SAVEPOINT one;
INSERT INTO t2 VALUES('one');
INSERT INTO t2 VALUES('two');
INSERT INTO t2 VALUES('three');
ROLLBACK TO one;
COMMIT;
}
finish_test
-89
View File
@@ -1,89 +0,0 @@
# 2023 Nov 03
#
# 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.
#
#***********************************************************************
#
# Tests focusing on the built-in fts5 tokenizers.
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5tokenizer2
# If SQLITE_ENABLE_FTS5 is defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
sqlite3_fts5_create_tokenizer db tst get_tst_tokenizer
proc get_tst_tokenizer {args} {
return "tst_tokenizer"
}
proc tst_tokenizer {flags txt} {
set token ""
set lTok [list]
foreach c [split $txt {}] {
if {$token==""} {
append token $c
} else {
set t1 [string is upper $token]
set t2 [string is upper $c]
if {$t1!=$t2} {
lappend lTok $token
set token ""
}
append token $c
}
}
if {$token!=""} { lappend lTok $token }
set iOff 0
foreach t $lTok {
set n [string length $t]
sqlite3_fts5_token $t $iOff [expr $iOff+$n]
incr iOff $n
}
}
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(t, tokenize=tst);
}
do_execsql_test 1.1 {
INSERT INTO t1 VALUES('AAdontBBmess');
}
do_execsql_test 1.2 {
SELECT snippet(t1, 0, '>', '<', '...', 4) FROM t1('BB');
} {AAdont>BB<mess}
do_execsql_test 1.3 {
SELECT highlight(t1, 0, '>', '<') FROM t1('BB');
} {AAdont>BB<mess}
do_execsql_test 1.4 {
SELECT highlight(t1, 0, '>', '<') FROM t1('AA');
} {>AA<dontBBmess}
do_execsql_test 1.5 {
SELECT highlight(t1, 0, '>', '<') FROM t1('dont');
} {AA>dont<BBmess}
do_execsql_test 1.6 {
SELECT highlight(t1, 0, '>', '<') FROM t1('mess');
} {AAdontBB>mess<}
do_execsql_test 1.7 {
SELECT highlight(t1, 0, '>', '<') FROM t1('BB mess');
} {AAdont>BBmess<}
finish_test
-109
View File
@@ -1,109 +0,0 @@
# 2023 October 24
#
# 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.
#
#*************************************************************************
#
# Tests for the fts5 "trigram" tokenizer.
#
source [file join [file dirname [info script]] fts5_common.tcl]
ifcapable !fts5 { finish_test ; return }
set ::testprefix fts5trigram2
do_execsql_test 1.0 "
CREATE VIRTUAL TABLE t1 USING fts5(y, tokenize='trigram remove_diacritics 1');
INSERT INTO t1 VALUES('abc\u0303defghijklm');
INSERT INTO t1 VALUES('a\u0303b\u0303c\u0303defghijklm');
"
do_execsql_test 1.1 {
SELECT highlight(t1, 0, '(', ')') FROM t1('abc');
} [list \
"(abc\u0303)defghijklm" \
"(a\u0303b\u0303c\u0303)defghijklm" \
]
do_execsql_test 1.2 {
SELECT highlight(t1, 0, '(', ')') FROM t1('bcde');
} [list \
"a(bc\u0303de)fghijklm" \
"a\u0303(b\u0303c\u0303de)fghijklm" \
]
do_execsql_test 1.3 {
SELECT highlight(t1, 0, '(', ')') FROM t1('cdef');
} [list \
"ab(c\u0303def)ghijklm" \
"a\u0303b\u0303(c\u0303def)ghijklm" \
]
do_execsql_test 1.4 {
SELECT highlight(t1, 0, '(', ')') FROM t1('def');
} [list \
"abc\u0303(def)ghijklm" \
"a\u0303b\u0303c\u0303(def)ghijklm" \
]
#-------------------------------------------------------------------------
do_catchsql_test 2.0 {
CREATE VIRTUAL TABLE t2 USING fts5(
z, tokenize='trigram case_sensitive 1 remove_diacritics 1'
);
} {1 {error in tokenizer constructor}}
do_execsql_test 2.1 {
CREATE VIRTUAL TABLE t2 USING fts5(
z, tokenize='trigram case_sensitive 0 remove_diacritics 1'
);
}
do_execsql_test 2.2 "
INSERT INTO t2 VALUES('\u00E3bcdef');
INSERT INTO t2 VALUES('b\u00E3cdef');
INSERT INTO t2 VALUES('bc\u00E3def');
INSERT INTO t2 VALUES('bcd\u00E3ef');
"
do_execsql_test 2.3 {
SELECT highlight(t2, 0, '(', ')') FROM t2('abc');
} "(\u00E3bc)def"
do_execsql_test 2.4 {
SELECT highlight(t2, 0, '(', ')') FROM t2('bac');
} "(b\u00E3c)def"
do_execsql_test 2.5 {
SELECT highlight(t2, 0, '(', ')') FROM t2('bca');
} "(bc\u00E3)def"
do_execsql_test 2.6 "
SELECT highlight(t2, 0, '(', ')') FROM t2('\u00E3bc');
" "(\u00E3bc)def"
#-------------------------------------------------------------------------
do_execsql_test 3.0 {
CREATE VIRTUAL TABLE t3 USING fts5(
z, tokenize='trigram remove_diacritics 1'
);
} {}
do_execsql_test 3.1 "
INSERT INTO t3 VALUES ('\u0303abc\u0303');
"
do_execsql_test 3.2 {
SELECT highlight(t3, 0, '(', ')') FROM t3('abc');
} "\u0303(abc\u0303)"
#-------------------------------------------------------------------------
do_execsql_test 4.0 {
CREATE VIRTUAL TABLE t4 USING fts5(z, tokenize=trigram);
} {}
breakpoint
do_execsql_test 4.1 {
INSERT INTO t4 VALUES('ABCD');
} {}
finish_test
+4 -11
View File
@@ -35,8 +35,6 @@ $(dir.bld.c):
javac.flags ?= -Xlint:unchecked -Xlint:deprecation
java.flags ?=
javac.flags += -encoding utf8
# -------------^^^^^^^^^^^^^^ required for Windows builds
jnicheck ?= 1
ifeq (1,$(jnicheck))
java.flags += -Xcheck:jni
@@ -81,7 +79,6 @@ $(bin.version-info): $(dir.tool)/version-info.c $(sqlite3.h) $(dir.top)/Makefile
# 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)/annotation/%,\
Experimental.java \
NotNull.java \
Nullable.java \
) $(patsubst %,$(dir.src.capi)/%,\
@@ -94,7 +91,7 @@ JAVA_FILES.main := $(patsubst %,$(dir.src.jni)/annotation/%,\
CollationNeededCallback.java \
CommitHookCallback.java \
ConfigLogCallback.java \
ConfigSqlLogCallback.java \
ConfigSqllogCallback.java \
NativePointerHolder.java \
OutputPointer.java \
PrepareMultiCallback.java \
@@ -113,7 +110,6 @@ JAVA_FILES.main := $(patsubst %,$(dir.src.jni)/annotation/%,\
WindowFunction.java \
XDestroyCallback.java \
sqlite3.java \
sqlite3_blob.java \
sqlite3_context.java \
sqlite3_stmt.java \
sqlite3_value.java \
@@ -124,7 +120,6 @@ JAVA_FILES.main := $(patsubst %,$(dir.src.jni)/annotation/%,\
Sqlite.java \
SqliteException.java \
ValueHolder.java \
WindowFunction.java \
)
JAVA_FILES.unittest := $(patsubst %,$(dir.src.jni)/%,\
@@ -164,13 +159,12 @@ endif
CLASS_FILES :=
define CLASSFILE_DEPS
all: $(1).class
$(1).class: $(1).java
CLASS_FILES += $(1).class
endef
$(foreach B,$(basename \
$(JAVA_FILES.main) $(JAVA_FILES.unittest) $(JAVA_FILES.tester)),\
$(eval $(call CLASSFILE_DEPS,$(B))))
$(CLASS_FILES): $(MAKEFILE)
$(CLASS_FILES): $(JAVA_FILES) $(MAKEFILE)
$(bin.javac) $(javac.flags) -h $(dir.bld.c) -cp $(classpath) $(JAVA_FILES)
#.PHONY: classfiles
@@ -232,8 +226,7 @@ SQLITE_OPT += -DSQLITE_ENABLE_RTREE \
-DSQLITE_ENABLE_OFFSET_SQL_FUNC \
-DSQLITE_ENABLE_PREUPDATE_HOOK \
-DSQLITE_ENABLE_NORMALIZE \
-DSQLITE_ENABLE_SQLLOG \
-DSQLITE_ENABLE_COLUMN_METADATA
-DSQLITE_ENABLE_SQLLOG
endif
ifeq (1,$(opt.debug))
@@ -323,7 +316,7 @@ test-one: $(test.deps)
$(bin.java) $(test.flags.jvm) org.sqlite.jni.wrapper1.Tester2 $(Tester2.flags)
test-sqllog: $(test.deps)
@echo "Testing with -sqllog..."
$(bin.java) $(test.flags.jvm) org.sqlite.jni.capi.Tester1 $(Tester1.flags) -sqllog
$(bin.java) $(test.flags.jvm) -sqllog
test-mt: $(test.deps)
@echo "Testing in multi-threaded mode:";
$(bin.java) $(test.flags.jvm) org.sqlite.jni.capi.Tester1 \
+19 -22
View File
@@ -16,8 +16,9 @@ Technical support is available in the 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. The JNI
bindings released with version 3.43 are a "tech preview." Once
finalized, strong backward compatibility guarantees will apply.
bindings released with version 3.43 are a "tech preview" and 3.44
will be "final," at which point strong backward compatibility
guarantees will apply.
Project goals/requirements:
@@ -42,13 +43,11 @@ Non-goals:
- Creation of high-level OO wrapper APIs. Clients are free to create
them off of the C-style API.
- Virtual tables are unlikely to be supported due to the amount of
glue code needed to fit them into Java.
- Support for mixed-mode operation, where client code accesses SQLite
both via the Java-side API and the C API via their own native
code. Such cases would be a minefield of potential mis-interactions
between this project's JNI bindings and mixed-mode client code.
code. In such cases, proxy functionalities (primarily callback
handler wrappers of all sorts) may fail because the C-side use of
the SQLite APIs will bypass those proxies.
Hello World
@@ -124,13 +123,15 @@ sensible default argument values. In all such cases they are thin
proxies around the corresponding C APIs and do not introduce new
semantics.
In a few cases, Java-specific capabilities have been added in
In some very few cases, Java-specific capabilities have been added in
new APIs, all of which have "_java" somewhere in their names.
Examples include:
- `sqlite3_result_java_object()`
- `sqlite3_column_java_object()`
- `sqlite3_column_java_casted()`
- `sqlite3_value_java_object()`
- `sqlite3_value_java_casted()`
which, as one might surmise, collectively enable the passing of
arbitrary Java objects from user-defined SQL functions through to the
@@ -149,9 +150,6 @@ pending statements have been closed. Be aware that Java garbage
collection _cannot_ close a database or finalize a prepared statement.
Those things require explicit API calls.
Classes for which it is sensible support Java's `AutoCloseable`
interface so can be used with try-with-resources constructs.
Golden Rule #2: _Never_ Throw from Callbacks (Unless...)
------------------------------------------------------------------------
@@ -161,15 +159,14 @@ retain C-like semantics. For example, they are not permitted to throw
or propagate exceptions and must return error information (if any) via
result codes or `null`. The only cases where the C-style APIs may
throw is through client-side misuse, e.g. passing in a null where it
may cause a `NullPointerException`. The APIs clearly mark function
parameters which should not be null, but does not generally actively
defend itself against such misuse. Some C-style APIs explicitly accept
`null` as a no-op for usability's sake, and some of the JNI APIs
deliberately return an error code, instead of segfaulting, when passed
a `null`.
shouldn't be used. The APIs clearly mark function parameters which
should not be null, but does not actively defend itself against such
misuse. Some C-style APIs explicitly accept `null` as a no-op for
usability's sake, and some of the JNI APIs deliberately return an
error code, instead of segfaulting, when passed a `null`.
Client-defined callbacks _must never throw exceptions_ unless _very
explitly documented_ as being throw-safe. Exceptions are generally
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. In some cases, callback handlers are permitted to throw, in
@@ -295,14 +292,14 @@ int sqlite3_create_function(sqlite3 db, String funcName, int nArgs,
`SQLFunction` is not used directly, but is instead instantiated via
one of its three subclasses:
- `ScalarFunction` implements simple scalar functions using but a
- `SQLFunction.Scalar` implements simple scalar functions using but a
single callback.
- `AggregateFunction` implements aggregate functions using two
- `SQLFunction.Aggregate` implements aggregate functions using two
callbacks.
- `WindowFunction` implements window functions using four
- `SQLFunction.Window` implements window functions using four
callbacks.
Search [`Tester1.java`](/file/ext/jni/src/org/sqlite/jni/capi/Tester1.java) for
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
File diff suppressed because it is too large Load Diff
+26 -108
View File
@@ -427,6 +427,8 @@ extern "C" {
#define org_sqlite_jni_capi_CApi_SQLITE_OPEN_EXRESCODE 33554432L
#undef org_sqlite_jni_capi_CApi_SQLITE_PREPARE_PERSISTENT
#define org_sqlite_jni_capi_CApi_SQLITE_PREPARE_PERSISTENT 1L
#undef org_sqlite_jni_capi_CApi_SQLITE_PREPARE_NORMALIZE
#define org_sqlite_jni_capi_CApi_SQLITE_PREPARE_NORMALIZE 2L
#undef org_sqlite_jni_capi_CApi_SQLITE_PREPARE_NO_VTAB
#define org_sqlite_jni_capi_CApi_SQLITE_PREPARE_NO_VTAB 4L
#undef org_sqlite_jni_capi_CApi_SQLITE_OK
@@ -705,12 +707,8 @@ extern "C" {
#define org_sqlite_jni_capi_CApi_SQLITE_DETERMINISTIC 2048L
#undef org_sqlite_jni_capi_CApi_SQLITE_DIRECTONLY
#define org_sqlite_jni_capi_CApi_SQLITE_DIRECTONLY 524288L
#undef org_sqlite_jni_capi_CApi_SQLITE_SUBTYPE
#define org_sqlite_jni_capi_CApi_SQLITE_SUBTYPE 1048576L
#undef org_sqlite_jni_capi_CApi_SQLITE_INNOCUOUS
#define org_sqlite_jni_capi_CApi_SQLITE_INNOCUOUS 2097152L
#undef org_sqlite_jni_capi_CApi_SQLITE_RESULT_SUBTYPE
#define org_sqlite_jni_capi_CApi_SQLITE_RESULT_SUBTYPE 16777216L
#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_SCAN_UNIQUE
#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_SCAN_UNIQUE 1L
#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_EQ
@@ -777,22 +775,6 @@ JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_init
JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1java_1uncache_1thread
(JNIEnv *, jclass);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_jni_supports_nio
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1jni_1supports_1nio
(JNIEnv *, jclass);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_jni_db_error
* Signature: (Lorg/sqlite/jni/capi/sqlite3;ILjava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1jni_1db_1error
(JNIEnv *, jclass, jobject, jint, jstring);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_aggregate_context
@@ -889,14 +871,6 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1int64
JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1java_1object
(JNIEnv *, jclass, jlong, jint, jobject);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_bind_nio_buffer
* Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;ILjava/nio/ByteBuffer;II)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1nio_1buffer
(JNIEnv *, jclass, jobject, jint, jobject, jint, jint);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_bind_null
@@ -1001,14 +975,6 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1blob_1open
JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1blob_1read
(JNIEnv *, jclass, jlong, jbyteArray, jint);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_blob_read_nio_buffer
* Signature: (JILjava/nio/ByteBuffer;II)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1blob_1read_1nio_1buffer
(JNIEnv *, jclass, jlong, jint, jobject, jint, jint);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_blob_reopen
@@ -1025,14 +991,6 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1blob_1reopen
JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1blob_1write
(JNIEnv *, jclass, jlong, jbyteArray, jint);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_blob_write_nio_buffer
* Signature: (JILjava/nio/ByteBuffer;II)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1blob_1write_1nio_1buffer
(JNIEnv *, jclass, jlong, jint, jobject, jint, jint);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_busy_handler
@@ -1129,14 +1087,6 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1bytes16
JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1count
(JNIEnv *, jclass, jlong);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_column_database_name
* Signature: (JI)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1database_1name
(JNIEnv *, jclass, jlong, jint);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_column_decltype
@@ -1169,14 +1119,6 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1int
JNIEXPORT jlong JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1int64
(JNIEnv *, jclass, jobject, jint);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_column_java_object
* Signature: (JI)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1java_1object
(JNIEnv *, jclass, jlong, jint);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_column_name
@@ -1187,11 +1129,11 @@ JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1name
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_column_nio_buffer
* Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;I)Ljava/nio/ByteBuffer;
* Method: sqlite3_column_database_name
* Signature: (JI)Ljava/lang/String;
*/
JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1nio_1buffer
(JNIEnv *, jclass, jobject, jint);
JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1database_1name
(JNIEnv *, jclass, jlong, jint);
/*
* Class: org_sqlite_jni_capi_CApi
@@ -1283,26 +1225,26 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1complete
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_config__enable
* Method: sqlite3_config
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1config_1_1enable
JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1config__I
(JNIEnv *, jclass, jint);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_config__CONFIG_LOG
* Signature: (Lorg/sqlite/jni/capi/ConfigLogCallback;)I
* Method: sqlite3_config
* Signature: (Lorg/sqlite/jni/capi/ConfigSqllogCallback;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1config_1_1CONFIG_1LOG
JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1config__Lorg_sqlite_jni_capi_ConfigSqllogCallback_2
(JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_config__SQLLOG
* Signature: (Lorg/sqlite/jni/capi/ConfigSqlLogCallback;)I
* Method: sqlite3_config
* Signature: (Lorg/sqlite/jni/capi/ConfigLogCallback;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1config_1_1SQLLOG
JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1config__Lorg_sqlite_jni_capi_ConfigLogCallback_2
(JNIEnv *, jclass, jobject);
/*
@@ -1452,9 +1394,9 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1extended_1errcode
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_extended_result_codes
* Signature: (Lorg/sqlite/jni/capi/sqlite3;Z)I
* Signature: (Lorg/sqlite/jni/capi/sqlite3;Z)Z
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1extended_1result_1codes
JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1extended_1result_1codes
(JNIEnv *, jclass, jobject, jboolean);
/*
@@ -1737,6 +1679,14 @@ JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1error_1nom
JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1error_1code
(JNIEnv *, jclass, jobject, jint);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_result_null
* Signature: (Lorg/sqlite/jni/capi/sqlite3_context;)V
*/
JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1null
(JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_result_int
@@ -1761,30 +1711,6 @@ JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1int64
JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1java_1object
(JNIEnv *, jclass, jobject, jobject);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_result_nio_buffer
* Signature: (Lorg/sqlite/jni/capi/sqlite3_context;Ljava/nio/ByteBuffer;II)V
*/
JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1nio_1buffer
(JNIEnv *, jclass, jobject, jobject, jint, jint);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_result_null
* Signature: (Lorg/sqlite/jni/capi/sqlite3_context;)V
*/
JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1null
(JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_result_subtype
* Signature: (Lorg/sqlite/jni/capi/sqlite3_context;I)V
*/
JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1subtype
(JNIEnv *, jclass, jobject, jint);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_result_value
@@ -1924,10 +1850,10 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1status64
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_step
* Signature: (J)I
* Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1step
(JNIEnv *, jclass, jlong);
(JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_capi_CApi
@@ -2137,14 +2063,6 @@ JNIEXPORT jlong JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1int64
JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1java_1object
(JNIEnv *, jclass, jlong);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_value_nio_buffer
* Signature: (Lorg/sqlite/jni/capi/sqlite3_value;)Ljava/nio/ByteBuffer;
*/
JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1nio_1buffer
(JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_capi_CApi
* Method: sqlite3_value_nochange
@@ -1,30 +0,0 @@
/*
** 2023-09-27
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file houses the Experimental annotation for the sqlite3 C API.
*/
package org.sqlite.jni.annotation;
import java.lang.annotation.*;
/**
This annotation is for flagging methods, constructors, and types
which are expressly experimental and subject to any amount of
change or outright removal. Client code should not rely on such
features.
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
@Target({
ElementType.METHOD,
ElementType.CONSTRUCTOR,
ElementType.TYPE
})
public @interface Experimental{}
@@ -9,22 +9,21 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file houses the NotNull annotation for the sqlite3 C API.
** This file houses the NotNull annotaion for the sqlite3 C API.
*/
package org.sqlite.jni.annotation;
import java.lang.annotation.*;
/**
This annotation is for flagging parameters which may not legally be
null or point to closed/finalized C-side resources.
<p>In the case of Java types which map directly to C struct types
(e.g. {@link org.sqlite.jni.capi.sqlite3}, {@link
org.sqlite.jni.capi.sqlite3_stmt}, and {@link
org.sqlite.jni.capi.sqlite3_context}), a closed/finalized resource
is also considered to be null for purposes this annotation because
the C-side effect of passing such a handle is the same as if null
is passed.</p>
(e.g. {@link org.sqlite.jni.sqlite3}, {@link
org.sqlite.jni.sqlite3_stmt}, and {@link
org.sqlite.jni.sqlite3_context}), a closed/finalized resource is
also considered to be null for purposes this annotation because the
C-side effect of passing such a handle is the same as if null is
passed.</p>
<p>When used in the context of Java interfaces which are called
from the C APIs, this annotation communicates that the C API will
@@ -32,23 +31,12 @@ import java.lang.annotation.*;
<p>Passing a null, for this annotation's definition of null, for
any parameter marked with this annoation specifically invokes
undefined behavior (see below).</p>
undefined behavior.</p>
<p>Passing 0 (i.e. C NULL) or a negative value for any long-type
parameter marked with this annoation specifically invokes undefined
behavior (see below). Such values are treated as C pointers in the
JNI layer.</p>
<p><b>Undefined behaviour:</b> the JNI build uses the {@code
SQLITE_ENABLE_API_ARMOR} build flag, meaning that the C code
invoked with invalid NULL pointers and the like will not invoke
undefined behavior in the conventional C sense, but may, for
example, return result codes which are not documented for the
affected APIs or may otherwise behave unpredictably. In no known
cases will such arguments result in C-level code dereferencing a
NULL pointer or accessing out-of-bounds (or otherwise invalid)
memory. In other words, they may cause unexpected behavior but
should never cause an outright crash or security issue.</p>
behavior. Such values are treated as C pointers in the JNI
layer.</p>
<p>Note that the C-style API does not throw any exceptions on its
own because it has a no-throw policy in order to retain its C-style
@@ -60,12 +48,12 @@ import java.lang.annotation.*;
code.</p>
<p>This annotation is solely for the use by the classes in the
org.sqlite.jni package and subpackages, but is made public so that
org.sqlite package and subpackages, but is made public so that
javadoc will link to it from the annotated functions. It is not
part of the public API and client-level code must not rely on
it.</p>
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.PARAMETER)
@java.lang.annotation.Documented
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE)
@java.lang.annotation.Target(java.lang.annotation.ElementType.PARAMETER)
public @interface NotNull{}
@@ -9,10 +9,9 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file houses the Nullable annotation for the sqlite3 C API.
** This file houses the Nullable annotaion for the sqlite3 C API.
*/
package org.sqlite.jni.annotation;
import java.lang.annotation.*;
/**
This annotation is for flagging parameters which may legally be
@@ -27,7 +26,7 @@ import java.lang.annotation.*;
annotated functions. It is not part of the public API and
client-level code must not rely on it.
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.PARAMETER)
@java.lang.annotation.Documented
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE)
@java.lang.annotation.Target(java.lang.annotation.ElementType.PARAMETER)
public @interface Nullable{}
@@ -42,75 +42,9 @@ public abstract class AggregateFunction<T> implements SQLFunction {
*/
public void xDestroy() {}
/**
PerContextState assists aggregate and window functions in
managing their accumulator state across calls to the UDF's
callbacks.
<p>T must be of a type which can be legally stored as a value in
java.util.HashMap<KeyType,T>.
<p>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.
<p>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.
<p>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 {@link AggregateFunction} and {@link
WindowFunction} 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 the given context 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.
<p>The caller is obligated to eventually call
takeAggregateState() to clear the mapping.
*/
public ValueHolder<T> getAggregateState(sqlite3_context cx, T initialValue){
final Long key = cx.getAggregateContext(true);
ValueHolder<T> rc = null==key ? null : map.get(key);
if( null==rc ){
map.put(key, 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(false));
return null==h ? null : h.value;
}
}
/** Per-invocation state for the UDF. */
private final PerContextState<T> map = new PerContextState<>();
private final SQLFunction.PerContextState<T> map =
new SQLFunction.PerContextState<>();
/**
To be called from the implementation's xStep() method, as well
@@ -20,8 +20,7 @@ import org.sqlite.jni.annotation.*;
public interface AuthorizerCallback extends CallbackProxy {
/**
Must function as described for the C-level
sqlite3_set_authorizer() callback. If it throws, the error is
converted to a db-level error and the exception is suppressed.
sqlite3_set_authorizer() callback.
*/
int call(int opId, @Nullable String s1, @Nullable String s2,
@Nullable String s3, @Nullable String s4);
File diff suppressed because it is too large Load Diff
@@ -24,9 +24,8 @@ package org.sqlite.jni.capi;
propagated. For callback interfaces which support returning error
info to the core, the JNI binding will convert any exceptions to
C-level error information. For callback interfaces which do not
support returning error information, all exceptions will
necessarily be suppressed in order to retain the C-style no-throw
semantics and avoid invoking undefined behavior in the C layer.
support, all exceptions will necessarily be suppressed in order to
retain the C-style no-throw semantics.
<p>Callbacks of this style follow a common naming convention:
@@ -21,9 +21,8 @@ public interface CollationNeededCallback extends CallbackProxy {
Has the same semantics as the C-level sqlite3_create_collation()
callback.
<p>Because the C API has no mechanism for reporting errors
from this callbacks, any exceptions thrown by this callback
are suppressed.
<p>If it throws, the exception message is passed on to the db and
the exception is suppressed.
*/
void call(sqlite3 db, int eTextRep, String collationName);
int call(sqlite3 db, int eTextRep, String collationName);
}
@@ -19,8 +19,7 @@ package org.sqlite.jni.capi;
public interface CommitHookCallback extends CallbackProxy {
/**
Works as documented for the C-level sqlite3_commit_hook()
callback. If it throws, the exception is translated into
a db-level error.
callback. Must not throw.
*/
int call();
}
@@ -16,10 +16,10 @@ package org.sqlite.jni.capi;
/**
A callback for use with sqlite3_config().
*/
public interface ConfigSqlLogCallback {
public interface ConfigSqllogCallback {
/**
Must function as described for a C-level callback for
{@link CApi#sqlite3_config(ConfigSqlLogCallback)}, with the slight signature change.
{@link CApi#sqlite3_config(ConfigSqllogCallback)}, with the slight signature change.
*/
void call(sqlite3 db, String msg, int msgType );
}
@@ -228,26 +228,4 @@ public final class OutputPointer {
/** Sets the current value. */
public final void set(byte[] v){value = v;}
}
/**
Output pointer for use with native routines which return
blobs via java.nio.ByteBuffer.
See {@link org.sqlite.jni.capi.CApi#sqlite3_jni_supports_nio}
*/
public static final class ByteBuffer {
/**
This is public for ease of use. Accessors are provided for
consistency with the higher-level types.
*/
public java.nio.ByteBuffer value;
/** Initializes with the value null. */
public ByteBuffer(){this(null);}
/** Initializes with the value v. */
public ByteBuffer(java.nio.ByteBuffer v){value = v;}
/** Returns the current value. */
public final java.nio.ByteBuffer get(){return value;}
/** Sets the current value. */
public final void set(java.nio.ByteBuffer v){value = v;}
}
}
@@ -25,10 +25,7 @@ public interface PrepareMultiCallback extends CallbackProxy {
sqlite3_prepare_multi() will _not_ finalize st - it is up
to the call() implementation how st is handled.
Must return 0 on success or an SQLITE_... code on error. If it
throws, sqlite3_prepare_multi() will transform the exception into
a db-level error in order to retain the C-style error semantics
of the API.
Must return 0 on success or an SQLITE_... code on error.
See the {@link Finalize} class for a wrapper which finalizes the
statement after calling a proxy PrepareMultiCallback.
@@ -40,7 +37,7 @@ public interface PrepareMultiCallback extends CallbackProxy {
any sqlite3_stmt passed to its callback.
*/
public static final class Finalize implements PrepareMultiCallback {
private final PrepareMultiCallback p;
private PrepareMultiCallback p;
/**
p is the proxy to call() when this.call() is called.
*/
@@ -19,8 +19,7 @@ package org.sqlite.jni.capi;
public interface PreupdateHookCallback extends CallbackProxy {
/**
Must function as described for the C-level sqlite3_preupdate_hook()
callback. If it throws, the exception is translated to a
db-level error and the exception is suppressed.
callback.
*/
void call(sqlite3 db, int op, String dbName, String dbTable,
long iKey1, long iKey2 );
@@ -18,9 +18,8 @@ package org.sqlite.jni.capi;
*/
public interface RollbackHookCallback extends CallbackProxy {
/**
Must function as documented for the C-level sqlite3_rollback_hook()
callback. If it throws, the exception is translated into
a db-level error.
Works as documented for the C-level sqlite3_rollback_hook()
callback.
*/
void call();
}
@@ -33,4 +33,71 @@ package org.sqlite.jni.capi;
*/
public interface SQLFunction {
/**
PerContextState assists aggregate and window functions in
managing their accumulator state across calls to the UDF's
callbacks.
<p>T must be of a type which can be legally stored as a value in
java.util.HashMap<KeyType,T>.
<p>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.
<p>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.
<p>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 {@link AggregateFunction} and {@link
WindowFunction} 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 the given context 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.
<p>The caller is obligated to eventually call
takeAggregateState() to clear the mapping.
*/
public ValueHolder<T> getAggregateState(sqlite3_context cx, T initialValue){
final Long key = cx.getAggregateContext(true);
ValueHolder<T> rc = null==key ? null : map.get(key);
if( null==rc ){
map.put(key, 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(false));
return null==h ? null : h.value;
}
}
}
+63 -281
View File
@@ -38,14 +38,6 @@ import java.util.concurrent.Future;
@java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD})
@interface SingleThreadOnly{}
/**
Annotation for Tester1 tests which must only be run if
sqlite3_jni_supports_nio() is true.
*/
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD})
@interface RequiresJniNio{}
public class Tester1 implements Runnable {
//! True when running in multi-threaded mode.
private static boolean mtMode = false;
@@ -54,7 +46,7 @@ public class Tester1 implements Runnable {
//! True to shuffle the order of the tests.
private static boolean shuffle = false;
//! True to dump the list of to-run tests to stdout.
private static int listRunTests = 0;
private static boolean listRunTests = false;
//! True to squelch all out() and outln() output.
private static boolean quietMode = false;
//! Total number of runTests() calls.
@@ -335,7 +327,7 @@ public class Tester1 implements Runnable {
rc = sqlite3_prepare_v3(db, "INSERT INTO t2(a) VALUES(1),(2),(3)",
0, outStmt);
SQLITE_PREPARE_NORMALIZE, outStmt);
affirm(0 == rc);
stmt = outStmt.get();
affirm(0 != stmt.getNativePointer());
@@ -390,15 +382,6 @@ public class Tester1 implements Runnable {
stmt = prepare(db, "SELECT a FROM t ORDER BY a DESC;");
affirm( sqlite3_stmt_readonly(stmt) );
affirm( !sqlite3_stmt_busy(stmt) );
if( sqlite3_compileoption_used("ENABLE_COLUMN_METADATA") ){
/* Unlike in native C code, JNI won't trigger an
UnsatisfiedLinkError until these are called (on Linux, at
least). */
affirm("t".equals(sqlite3_column_table_name(stmt,0)));
affirm("main".equals(sqlite3_column_database_name(stmt,0)));
affirm("a".equals(sqlite3_column_origin_name(stmt,0)));
}
int total2 = 0;
while( SQLITE_ROW == sqlite3_step(stmt) ){
affirm( sqlite3_stmt_busy(stmt) );
@@ -494,7 +477,6 @@ public class Tester1 implements Runnable {
stmt = prepare(db, "SELECT a FROM t ORDER BY a DESC;");
StringBuilder sbuf = new StringBuilder();
n = 0;
final boolean tryNio = sqlite3_jni_supports_nio();
while( SQLITE_ROW == sqlite3_step(stmt) ){
final sqlite3_value sv = sqlite3_value_dup(sqlite3_column_value(stmt,0));
final String txt = sqlite3_column_text16(stmt, 0);
@@ -509,15 +491,6 @@ public class Tester1 implements Runnable {
StandardCharsets.UTF_8)) );
affirm( txt.length() == sqlite3_value_bytes16(sv)/2 );
affirm( txt.equals(sqlite3_value_text16(sv)) );
if( tryNio ){
java.nio.ByteBuffer bu = sqlite3_value_nio_buffer(sv);
byte ba[] = sqlite3_value_blob(sv);
affirm( ba.length == bu.capacity() );
int i = 0;
for( byte b : ba ){
affirm( b == bu.get(i++) );
}
}
sqlite3_value_free(sv);
++n;
}
@@ -575,79 +548,6 @@ public class Tester1 implements Runnable {
sqlite3_close_v2(db);
}
@RequiresJniNio
private void testBindByteBuffer(){
/* TODO: these tests need to be much more extensive to check the
begin/end range handling. */
java.nio.ByteBuffer zeroCheck =
java.nio.ByteBuffer.allocateDirect(0);
affirm( null != zeroCheck );
zeroCheck = null;
sqlite3 db = createNewDb();
execSql(db, "CREATE TABLE t(a)");
final java.nio.ByteBuffer buf = java.nio.ByteBuffer.allocateDirect(10);
buf.put((byte)0x31)/*note that we'll skip this one*/
.put((byte)0x32)
.put((byte)0x33)
.put((byte)0x34)
.put((byte)0x35)/*we'll skip this one too*/;
final int expectTotal = buf.get(1) + buf.get(2) + buf.get(3);
sqlite3_stmt stmt = prepare(db, "INSERT INTO t(a) VALUES(?);");
affirm( SQLITE_ERROR == sqlite3_bind_blob(stmt, 1, buf, -1, 0),
"Buffer offset may not be negative." );
affirm( 0 == sqlite3_bind_blob(stmt, 1, buf, 1, 3) );
affirm( SQLITE_DONE == sqlite3_step(stmt) );
sqlite3_finalize(stmt);
stmt = prepare(db, "SELECT a FROM t;");
int total = 0;
affirm( SQLITE_ROW == sqlite3_step(stmt) );
byte blob[] = sqlite3_column_blob(stmt, 0);
java.nio.ByteBuffer nioBlob =
sqlite3_column_nio_buffer(stmt, 0);
affirm(3 == blob.length);
affirm(blob.length == nioBlob.capacity());
affirm(blob.length == nioBlob.limit());
int i = 0;
for(byte b : blob){
affirm( i<=3 );
affirm(b == buf.get(1 + i));
affirm(b == nioBlob.get(i));
++i;
total += b;
}
affirm( SQLITE_DONE == sqlite3_step(stmt) );
sqlite3_finalize(stmt);
affirm(total == expectTotal);
SQLFunction func =
new ScalarFunction(){
public void xFunc(sqlite3_context cx, sqlite3_value[] args){
sqlite3_result_blob(cx, buf, 1, 3);
}
};
affirm( 0 == sqlite3_create_function(db, "myfunc", -1, SQLITE_UTF8, func) );
stmt = prepare(db, "SELECT myfunc()");
affirm( SQLITE_ROW == sqlite3_step(stmt) );
blob = sqlite3_column_blob(stmt, 0);
affirm(3 == blob.length);
i = 0;
total = 0;
for(byte b : blob){
affirm( i<=3 );
affirm(b == buf.get(1 + i++));
total += b;
}
affirm( SQLITE_DONE == sqlite3_step(stmt) );
sqlite3_finalize(stmt);
affirm(total == expectTotal);
sqlite3_close_v2(db);
}
private void testSql(){
sqlite3 db = createNewDb();
sqlite3_stmt stmt = prepare(db, "SELECT 1");
@@ -693,9 +593,9 @@ public class Tester1 implements Runnable {
};
final CollationNeededCallback collLoader = new CollationNeededCallback(){
@Override
public void call(sqlite3 dbArg, int eTextRep, String collationName){
public int call(sqlite3 dbArg, int eTextRep, String collationName){
affirm(dbArg == db/* as opposed to a temporary object*/);
sqlite3_create_collation(dbArg, "reversi", eTextRep, myCollation);
return sqlite3_create_collation(dbArg, "reversi", eTextRep, myCollation);
}
};
int rc = sqlite3_collation_needed(db, collLoader);
@@ -903,17 +803,13 @@ public class Tester1 implements Runnable {
affirm( 0==rc );
int n = 0;
if( SQLITE_ROW == sqlite3_step(stmt) ){
affirm( testResult.value == sqlite3_column_java_object(stmt, 0) );
affirm( testResult.value == sqlite3_column_java_object(stmt, 0, sqlite3.class) );
affirm( null == sqlite3_column_java_object(stmt, 0, sqlite3_stmt.class) );
affirm( null == sqlite3_column_java_object(stmt,1) );
final sqlite3_value v = sqlite3_column_value(stmt, 0);
affirm( testResult.value == sqlite3_value_java_object(v) );
affirm( testResult.value == sqlite3_value_java_object(v, sqlite3.class) );
affirm( testResult.value == sqlite3_value_java_casted(v, sqlite3.class) );
affirm( testResult.value ==
sqlite3_value_java_object(v, testResult.value.getClass()) );
affirm( testResult.value == sqlite3_value_java_object(v, Object.class) );
affirm( null == sqlite3_value_java_object(v, String.class) );
sqlite3_value_java_casted(v, testResult.value.getClass()) );
affirm( testResult.value == sqlite3_value_java_casted(v, Object.class) );
affirm( null == sqlite3_value_java_casted(v, String.class) );
++n;
}
sqlite3_finalize(stmt);
@@ -928,28 +824,15 @@ public class Tester1 implements Runnable {
// To confirm that xFinal() is called with no aggregate state
// when the corresponding result set is empty.
new ValueHolder<>(false);
final ValueHolder<sqlite3_value[]> neverEverDoThisInClientCode = new ValueHolder<>(null);
final ValueHolder<sqlite3_context> neverEverDoThisInClientCode2 = new ValueHolder<>(null);
SQLFunction func = new AggregateFunction<Integer>(){
@Override
public void xStep(sqlite3_context cx, sqlite3_value[] args){
if( null==neverEverDoThisInClientCode.value ){
/* !!!NEVER!!! hold a reference to an sqlite3_value or
sqlite3_context object like this in client code! They
are ONLY legal for the duration of their single
call. We do it here ONLY to test that the defenses
against clients doing this are working. */
neverEverDoThisInClientCode.value = args;
}
final ValueHolder<Integer> agg = this.getAggregateState(cx, 0);
agg.value += sqlite3_value_int(args[0]);
affirm( agg == this.getAggregateState(cx, 0) );
}
@Override
public void xFinal(sqlite3_context cx){
if( null==neverEverDoThisInClientCode2.value ){
neverEverDoThisInClientCode2.value = cx;
}
final Integer v = this.takeAggregateState(cx);
if(null == v){
xFinalNull.value = true;
@@ -974,10 +857,6 @@ public class Tester1 implements Runnable {
}
affirm( 1==n );
affirm(!xFinalNull.value);
affirm( null!=neverEverDoThisInClientCode.value );
affirm( null!=neverEverDoThisInClientCode2.value );
affirm( 0<neverEverDoThisInClientCode.value.length );
affirm( 0==neverEverDoThisInClientCode2.value.getNativePointer() );
sqlite3_reset(stmt);
affirm( 1==sqlite3_stmt_status(stmt, SQLITE_STMTSTATUS_RUN, false) );
// Ensure that the accumulator is reset on subsequent calls...
@@ -1046,6 +925,7 @@ public class Tester1 implements Runnable {
"ORDER BY x ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING"+
") AS sum_y "+
"FROM twin ORDER BY x;");
affirm( 0 == rc );
int n = 0;
while( SQLITE_ROW == sqlite3_step(stmt) ){
final String s = sqlite3_column_text16(stmt, 0);
@@ -1148,48 +1028,48 @@ public class Tester1 implements Runnable {
@SingleThreadOnly /* because threads inherently break this test */
private static void testBusy(){
final String dbName = "_busy-handler.db";
final OutputPointer.sqlite3 outDb = new OutputPointer.sqlite3();
final OutputPointer.sqlite3_stmt outStmt = new OutputPointer.sqlite3_stmt();
int rc = sqlite3_open(dbName, outDb);
++metrics.dbOpen;
affirm( 0 == rc );
final sqlite3 db1 = outDb.get();
execSql(db1, "CREATE TABLE IF NOT EXISTS t(a)");
rc = sqlite3_open(dbName, outDb);
++metrics.dbOpen;
affirm( 0 == rc );
affirm( outDb.get() != db1 );
final sqlite3 db2 = outDb.get();
affirm( "main".equals( sqlite3_db_name(db1, 0) ) );
rc = sqlite3_db_config(db1, SQLITE_DBCONFIG_MAINDBNAME, "foo");
affirm( sqlite3_db_filename(db1, "foo").endsWith(dbName) );
affirm( "foo".equals( sqlite3_db_name(db1, 0) ) );
final ValueHolder<Integer> xBusyCalled = new ValueHolder<>(0);
BusyHandlerCallback handler = new BusyHandlerCallback(){
@Override public int call(int n){
//outln("busy handler #"+n);
return n > 2 ? 0 : ++xBusyCalled.value;
}
};
rc = sqlite3_busy_handler(db2, handler);
affirm(0 == rc);
// Force a locked condition...
execSql(db1, "BEGIN EXCLUSIVE");
rc = sqlite3_prepare_v2(db2, "SELECT * from t", outStmt);
affirm( SQLITE_BUSY == rc);
affirm( null == outStmt.get() );
affirm( 3 == xBusyCalled.value );
sqlite3_close_v2(db1);
sqlite3_close_v2(db2);
try{
final OutputPointer.sqlite3 outDb = new OutputPointer.sqlite3();
final OutputPointer.sqlite3_stmt outStmt = new OutputPointer.sqlite3_stmt();
int rc = sqlite3_open(dbName, outDb);
++metrics.dbOpen;
affirm( 0 == rc );
final sqlite3 db1 = outDb.get();
execSql(db1, "CREATE TABLE IF NOT EXISTS t(a)");
rc = sqlite3_open(dbName, outDb);
++metrics.dbOpen;
affirm( 0 == rc );
affirm( outDb.get() != db1 );
final sqlite3 db2 = outDb.get();
affirm( "main".equals( sqlite3_db_name(db1, 0) ) );
rc = sqlite3_db_config(db1, SQLITE_DBCONFIG_MAINDBNAME, "foo");
affirm( sqlite3_db_filename(db1, "foo").endsWith(dbName) );
affirm( "foo".equals( sqlite3_db_name(db1, 0) ) );
affirm( SQLITE_MISUSE == sqlite3_db_config(db1, 0, 0, null) );
final ValueHolder<Integer> xBusyCalled = new ValueHolder<>(0);
BusyHandlerCallback handler = new BusyHandlerCallback(){
@Override public int call(int n){
//outln("busy handler #"+n);
return n > 2 ? 0 : ++xBusyCalled.value;
}
};
rc = sqlite3_busy_handler(db2, handler);
affirm(0 == rc);
// Force a locked condition...
execSql(db1, "BEGIN EXCLUSIVE");
rc = sqlite3_prepare_v2(db2, "SELECT * from t", outStmt);
affirm( SQLITE_BUSY == rc);
affirm( null == outStmt.get() );
affirm( 3 == xBusyCalled.value );
sqlite3_close_v2(db1);
sqlite3_close_v2(db2);
}finally{
try{(new java.io.File(dbName)).delete();}
catch(Exception e){/* ignore */}
final java.io.File f = new java.io.File(dbName);
f.delete();
}catch(Exception e){
/* ignore */
}
}
@@ -1213,7 +1093,6 @@ public class Tester1 implements Runnable {
private void testCommitHook(){
final sqlite3 db = createNewDb();
sqlite3_extended_result_codes(db, true);
final ValueHolder<Integer> counter = new ValueHolder<>(0);
final ValueHolder<Integer> hookResult = new ValueHolder<>(0);
final CommitHookCallback theHook = new CommitHookCallback(){
@@ -1256,7 +1135,7 @@ public class Tester1 implements Runnable {
affirm( 5 == counter.value );
hookResult.value = SQLITE_ERROR;
int rc = execSql(db, false, "BEGIN; update t set a='j' where a='i'; COMMIT;");
affirm( SQLITE_CONSTRAINT_COMMITHOOK == rc );
affirm( SQLITE_CONSTRAINT == rc );
affirm( 6 == counter.value );
sqlite3_close_v2(db);
}
@@ -1475,9 +1354,6 @@ public class Tester1 implements Runnable {
authRc.value = SQLITE_DENY;
int rc = execSql(db, false, "UPDATE t SET a=2");
affirm( SQLITE_AUTH==rc );
sqlite3_set_authorizer(db, null);
rc = execSql(db, false, "UPDATE t SET a=2");
affirm( 0==rc );
// TODO: expand these tests considerably
sqlite3_close(db);
}
@@ -1539,7 +1415,7 @@ public class Tester1 implements Runnable {
val.value = 0;
final AutoExtensionCallback ax2 = new AutoExtensionCallback(){
@Override public int call(sqlite3 db){
@Override public synchronized int call(sqlite3 db){
++val.value;
return 0;
}
@@ -1750,7 +1626,7 @@ public class Tester1 implements Runnable {
sqlite3_finalize(stmt);
b = sqlite3_blob_open(db, "main", "t", "a",
sqlite3_last_insert_rowid(db), 0);
sqlite3_last_insert_rowid(db), 1);
affirm( null!=b );
rc = sqlite3_blob_reopen(b, 2);
affirm( 0==rc );
@@ -1760,86 +1636,6 @@ public class Tester1 implements Runnable {
affirm( 100==tgt[0] && 101==tgt[1] && 102==tgt[2], "DEF" );
rc = sqlite3_blob_close(b);
affirm( 0==rc );
if( !sqlite3_jni_supports_nio() ){
outln("WARNING: skipping tests for ByteBuffer-using sqlite3_blob APIs ",
"because this platform lacks that support.");
sqlite3_close_v2(db);
return;
}
/* Sanity checks for the java.nio.ByteBuffer-taking overloads of
sqlite3_blob_read/write(). */
execSql(db, "UPDATE t SET a=zeroblob(10)");
b = sqlite3_blob_open(db, "main", "t", "a", 1, 1);
affirm( null!=b );
java.nio.ByteBuffer bb = java.nio.ByteBuffer.allocateDirect(10);
for( byte i = 0; i < 10; ++i ){
bb.put((int)i, (byte)(48+i & 0xff));
}
rc = sqlite3_blob_write(b, 1, bb, 1, 10);
affirm( rc==SQLITE_ERROR, "b length < (srcOffset + bb length)" );
rc = sqlite3_blob_write(b, -1, bb);
affirm( rc==SQLITE_ERROR, "Target offset may not be negative" );
rc = sqlite3_blob_write(b, 0, bb, -1, -1);
affirm( rc==SQLITE_ERROR, "Source offset may not be negative" );
rc = sqlite3_blob_write(b, 1, bb, 1, 8);
affirm( rc==0 );
// b's contents: 0 49 50 51 52 53 54 55 56 0
// ascii: 0 '1' '2' '3' '4' '5' '6' '7' '8' 0
byte br[] = new byte[10];
java.nio.ByteBuffer bbr =
java.nio.ByteBuffer.allocateDirect(bb.limit());
rc = sqlite3_blob_read( b, br, 0 );
affirm( rc==0 );
rc = sqlite3_blob_read( b, bbr );
affirm( rc==0 );
java.nio.ByteBuffer bbr2 = sqlite3_blob_read_nio_buffer(b, 0, 12);
affirm( null==bbr2, "Read size is too big");
bbr2 = sqlite3_blob_read_nio_buffer(b, -1, 3);
affirm( null==bbr2, "Source offset is negative");
bbr2 = sqlite3_blob_read_nio_buffer(b, 5, 6);
affirm( null==bbr2, "Read pos+size is too big");
bbr2 = sqlite3_blob_read_nio_buffer(b, 4, 7);
affirm( null==bbr2, "Read pos+size is too big");
bbr2 = sqlite3_blob_read_nio_buffer(b, 4, 6);
affirm( null!=bbr2 );
java.nio.ByteBuffer bbr3 =
java.nio.ByteBuffer.allocateDirect(2 * bb.limit());
java.nio.ByteBuffer bbr4 =
java.nio.ByteBuffer.allocateDirect(5);
rc = sqlite3_blob_read( b, bbr3 );
affirm( rc==0 );
rc = sqlite3_blob_read( b, bbr4 );
affirm( rc==0 );
affirm( sqlite3_blob_bytes(b)==bbr3.limit() );
affirm( 5==bbr4.limit() );
sqlite3_blob_close(b);
affirm( 0==br[0] );
affirm( 0==br[9] );
affirm( 0==bbr.get(0) );
affirm( 0==bbr.get(9) );
affirm( bbr2.limit() == 6 );
affirm( 0==bbr3.get(0) );
{
Exception ex = null;
try{ bbr3.get(11); }
catch(Exception e){ex = e;}
affirm( ex instanceof IndexOutOfBoundsException,
"bbr3.limit() was reset by read()" );
ex = null;
}
affirm( 0==bbr4.get(0) );
for( int i = 1; i < 9; ++i ){
affirm( br[i] == 48 + i );
affirm( br[i] == bbr.get(i) );
affirm( br[i] == bbr3.get(i) );
if( i>3 ){
affirm( br[i] == bbr2.get(i-4) );
}
if( i < bbr4.limit() ){
affirm( br[i] == bbr4.get(i) );
}
}
sqlite3_close_v2(db);
}
@@ -1852,13 +1648,9 @@ public class Tester1 implements Runnable {
};
final List<sqlite3_stmt> liStmt = new ArrayList<sqlite3_stmt>();
final PrepareMultiCallback proxy = new PrepareMultiCallback.StepAll();
final ValueHolder<String> toss = new ValueHolder<>(null);
PrepareMultiCallback m = new PrepareMultiCallback() {
@Override public int call(sqlite3_stmt st){
liStmt.add(st);
if( null!=toss.value ){
throw new RuntimeException(toss.value);
}
return proxy.call(st);
}
};
@@ -1868,10 +1660,6 @@ public class Tester1 implements Runnable {
for( sqlite3_stmt st : liStmt ){
sqlite3_finalize(st);
}
toss.value = "This is an exception.";
rc = sqlite3_prepare_multi(db, "SELECT 1", m);
affirm( SQLITE_ERROR==rc );
affirm( sqlite3_errmsg(db).indexOf(toss.value)>0 );
sqlite3_close_v2(db);
}
@@ -1910,7 +1698,7 @@ public class Tester1 implements Runnable {
mlist = new ArrayList<>( testMethods.subList(0, testMethods.size()) );
java.util.Collections.shuffle(mlist);
}
if( (!fromThread && listRunTests>0) || listRunTests>1 ){
if( listRunTests ){
synchronized(this.getClass()){
if( !fromThread ){
out("Initial test"," list: ");
@@ -1972,11 +1760,8 @@ public class Tester1 implements Runnable {
-naps: sleep small random intervals between tests in order to add
some chaos for cross-thread contention.
-list-tests: outputs the list of tests being run, minus some
which are hard-coded. In multi-threaded mode, use this twice to
to emit the list run by each thread (which may differ from the initial
list, in particular if -shuffle is used).
which are hard-coded. This is noisy in multi-threaded mode.
-fail: forces an exception to be thrown during the test run. Use
with -shuffle to make its appearance unpredictable.
@@ -2005,7 +1790,7 @@ public class Tester1 implements Runnable {
}else if(arg.equals("shuffle")){
shuffle = true;
}else if(arg.equals("list-tests")){
++listRunTests;
listRunTests = true;
}else if(arg.equals("fail")){
forceFail = true;
}else if(arg.equals("sqllog")){
@@ -2024,7 +1809,7 @@ public class Tester1 implements Runnable {
if( sqlLog ){
if( sqlite3_compileoption_used("ENABLE_SQLLOG") ){
final ConfigSqlLogCallback log = new ConfigSqlLogCallback() {
final ConfigSqllogCallback log = new ConfigSqllogCallback() {
@Override public void call(sqlite3 db, String msg, int op){
switch(op){
case 0: outln("Opening db: ",db); break;
@@ -2035,7 +1820,7 @@ public class Tester1 implements Runnable {
};
int rc = sqlite3_config( log );
affirm( 0==rc );
rc = sqlite3_config( (ConfigSqlLogCallback)null );
rc = sqlite3_config( (ConfigSqllogCallback)null );
affirm( 0==rc );
rc = sqlite3_config( log );
affirm( 0==rc );
@@ -2073,20 +1858,18 @@ public class Tester1 implements Runnable {
if( forceFail ){
testMethods.add(m);
}
}else if( m.isAnnotationPresent( RequiresJniNio.class )
&& !sqlite3_jni_supports_nio() ){
outln("Skipping test for lack of JNI java.nio.ByteBuffer support: ",
name,"()\n");
++nSkipped;
}else if( !m.isAnnotationPresent( ManualTest.class ) ){
if( nThread>1 && m.isAnnotationPresent( SingleThreadOnly.class ) ){
out("Skipping test in multi-thread mode: ",name,"()\n");
++nSkipped;
if( 0==nSkipped++ ){
out("Skipping tests in multi-thread mode:");
}
out(" "+name+"()");
}else if( name.startsWith("test") ){
testMethods.add(m);
}
}
}
if( nSkipped>0 ) out("\n");
}
final long timeStart = System.currentTimeMillis();
@@ -2118,7 +1901,6 @@ public class Tester1 implements Runnable {
sqlite3_libversion_number(),"\n",
sqlite3_libversion(),"\n",SQLITE_SOURCE_ID,"\n",
"SQLITE_THREADSAFE=",sqlite3_threadsafe());
outln("JVM NIO support? ",sqlite3_jni_supports_nio() ? "YES" : "NO");
final boolean showLoopCount = (nRepeat>1 && nThread>1);
if( showLoopCount ){
outln("Running ",nRepeat," loop(s) with ",nThread," thread(s) each.");
@@ -19,8 +19,7 @@ package org.sqlite.jni.capi;
public interface UpdateHookCallback extends CallbackProxy {
/**
Must function as described for the C-level sqlite3_update_hook()
callback. If it throws, the exception is translated into
a db-level error.
callback.
*/
void call(int opId, String dbName, String tableName, long rowId);
}
@@ -9,16 +9,14 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the ValueHolder utility class for the sqlite3
** JNI bindings.
** This file contains a set of tests for the sqlite3 JNI bindings.
*/
package org.sqlite.jni.capi;
/**
A helper class which simply holds a single value. Its primary use
is for communicating values out of anonymous classes, as doing so
requires a "final" reference, as well as communicating aggregate
SQL function state across calls to such functions.
requires a "final" reference.
*/
public class ValueHolder<T> {
public T value;
+1 -1
View File
@@ -38,6 +38,6 @@ public final class sqlite3 extends NativePointerHolder<sqlite3>
}
@Override public void close(){
CApi.sqlite3_close_v2(this);
CApi.sqlite3_close_v2(this.clearNativePointer());
}
}
@@ -25,6 +25,7 @@ public final class sqlite3_blob extends NativePointerHolder<sqlite3_blob>
private sqlite3_blob(){}
@Override public void close(){
CApi.sqlite3_blob_close(this);
CApi.sqlite3_blob_close(this.clearNativePointer());
}
}
@@ -25,6 +25,6 @@ public final class sqlite3_stmt extends NativePointerHolder<sqlite3_stmt>
private sqlite3_stmt(){}
@Override public void close(){
CApi.sqlite3_finalize(this);
CApi.sqlite3_finalize(this.clearNativePointer());
}
}
@@ -12,6 +12,10 @@
** This file is part of the wrapper1 interface for sqlite3.
*/
package org.sqlite.jni.wrapper1;
import org.sqlite.jni.capi.CApi;
import org.sqlite.jni.annotation.*;
import org.sqlite.jni.capi.sqlite3_context;
import org.sqlite.jni.capi.sqlite3_value;
/**
EXPERIMENTAL/INCOMPLETE/UNTESTED
@@ -47,75 +51,9 @@ public abstract class AggregateFunction<T> implements SqlFunction {
*/
public void xDestroy() {}
/**
PerContextState assists aggregate and window functions in
managing their accumulator state across calls to the UDF's
callbacks.
<p>T must be of a type which can be legally stored as a value in
java.util.HashMap<KeyType,T>.
<p>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.
<p>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.
<p>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 {@link AggregateFunction} and {@link
WindowFunction} 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 the given context 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.
<p>The caller is obligated to eventually call
takeAggregateState() to clear the mapping.
*/
public ValueHolder<T> getAggregateState(SqlFunction.Arguments args, T initialValue){
final Long key = args.getContext().getAggregateContext(true);
ValueHolder<T> rc = null==key ? null : map.get(key);
if( null==rc ){
map.put(key, 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 with the arguments' aggregate context 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(SqlFunction.Arguments args){
final ValueHolder<T> h = map.remove(args.getContext().getAggregateContext(false));
return null==h ? null : h.value;
}
}
/** Per-invocation state for the UDF. */
private final PerContextState<T> map = new PerContextState<>();
private final SqlFunction.PerContextState<T> map =
new SqlFunction.PerContextState<>();
/**
To be called from the implementation's xStep() method, as well
@@ -22,14 +22,6 @@ import org.sqlite.jni.capi.sqlite3_value;
*/
public interface SqlFunction {
public static final int DETERMINISTIC = CApi.SQLITE_DETERMINISTIC;
public static final int INNOCUOUS = CApi.SQLITE_INNOCUOUS;
public static final int DIRECTONLY = CApi.SQLITE_DIRECTONLY;
public static final int SUBTYPE = CApi.SQLITE_SUBTYPE;
public static final int RESULT_SUBTYPE = CApi.SQLITE_RESULT_SUBTYPE;
public static final int UTF8 = CApi.SQLITE_UTF8;
public static final int UTF16 = CApi.SQLITE_UTF16;
/**
The Arguments type is an abstraction on top of the lower-level
UDF function argument types. It provides _most_ of the functionality
@@ -53,118 +45,12 @@ public interface SqlFunction {
*/
Arguments(sqlite3_context cx, sqlite3_value args[]){
this.cx = cx;
this.args = args==null ? new sqlite3_value[0] : args;
this.args = args==null ? new sqlite3_value[0] : args;;
this.length = this.args.length;
}
/**
Returns the sqlite3_value at the given argument index or throws
an IllegalArgumentException exception if ndx is out of range.
*/
private sqlite3_value valueAt(int ndx){
if(ndx<0 || ndx>=args.length){
throw new IllegalArgumentException(
"SQL function argument index "+ndx+" is out of range."
);
}
return args[ndx];
}
//! Returns the underlying sqlite3_context for these arguments.
sqlite3_context getContext(){return cx;}
/**
Returns the Sqlite (db) object associated with this UDF call,
or null if the UDF is somehow called without such an object or
the db has been closed in an untimely manner (e.g. closed by a
UDF call).
*/
public Sqlite getDb(){
return Sqlite.fromNative( CApi.sqlite3_context_db_handle(cx) );
}
public int getArgCount(){ return args.length; }
public int getInt(int argNdx){return CApi.sqlite3_value_int(valueAt(argNdx));}
public long getInt64(int argNdx){return CApi.sqlite3_value_int64(valueAt(argNdx));}
public double getDouble(int argNdx){return CApi.sqlite3_value_double(valueAt(argNdx));}
public byte[] getBlob(int argNdx){return CApi.sqlite3_value_blob(valueAt(argNdx));}
public byte[] getText(int argNdx){return CApi.sqlite3_value_text(valueAt(argNdx));}
public String getText16(int argNdx){return CApi.sqlite3_value_text16(valueAt(argNdx));}
public int getBytes(int argNdx){return CApi.sqlite3_value_bytes(valueAt(argNdx));}
public int getBytes16(int argNdx){return CApi.sqlite3_value_bytes16(valueAt(argNdx));}
public Object getObject(int argNdx){return CApi.sqlite3_value_java_object(valueAt(argNdx));}
public <T> T getObject(int argNdx, Class<T> type){
return CApi.sqlite3_value_java_object(valueAt(argNdx), type);
}
public int getType(int argNdx){return CApi.sqlite3_value_type(valueAt(argNdx));}
public int getSubtype(int argNdx){return CApi.sqlite3_value_subtype(valueAt(argNdx));}
public int getNumericType(int argNdx){return CApi.sqlite3_value_numeric_type(valueAt(argNdx));}
public int getNoChange(int argNdx){return CApi.sqlite3_value_nochange(valueAt(argNdx));}
public boolean getFromBind(int argNdx){return CApi.sqlite3_value_frombind(valueAt(argNdx));}
public int getEncoding(int argNdx){return CApi.sqlite3_value_encoding(valueAt(argNdx));}
public void resultInt(int v){ CApi.sqlite3_result_int(cx, v); }
public void resultInt64(long v){ CApi.sqlite3_result_int64(cx, v); }
public void resultDouble(double v){ CApi.sqlite3_result_double(cx, v); }
public void resultError(String msg){CApi.sqlite3_result_error(cx, msg);}
public void resultError(Exception e){CApi.sqlite3_result_error(cx, e);}
public void resultErrorTooBig(){CApi.sqlite3_result_error_toobig(cx);}
public void resultErrorCode(int rc){CApi.sqlite3_result_error_code(cx, rc);}
public void resultObject(Object o){CApi.sqlite3_result_java_object(cx, o);}
public void resultNull(){CApi.sqlite3_result_null(cx);}
/**
Analog to sqlite3_result_value(), using the Value object at the
given argument index.
*/
public void resultArg(int argNdx){CApi.sqlite3_result_value(cx, valueAt(argNdx));}
public void resultSubtype(int subtype){CApi.sqlite3_result_subtype(cx, subtype);}
public void resultZeroBlob(long n){
// Throw on error? If n is too big,
// sqlite3_result_error_toobig() is automatically called.
CApi.sqlite3_result_zeroblob64(cx, n);
}
public void resultBlob(byte[] blob){CApi.sqlite3_result_blob(cx, blob);}
public void resultText(byte[] utf8){CApi.sqlite3_result_text(cx, utf8);}
public void resultText(String txt){CApi.sqlite3_result_text(cx, txt);}
public void resultText16(byte[] utf16){CApi.sqlite3_result_text16(cx, utf16);}
public void resultText16(String txt){CApi.sqlite3_result_text16(cx, txt);}
/**
Callbacks should invoke this on OOM errors, instead of throwing
OutOfMemoryError, because the latter cannot be propagated
through the C API.
*/
public void resultNoMem(){CApi.sqlite3_result_error_nomem(cx);}
/**
Analog to sqlite3_set_auxdata() but throws if argNdx is out of
range.
*/
public void setAuxData(int argNdx, Object o){
/* From the API docs: https://www.sqlite.org/c3ref/get_auxdata.html
The value of the N parameter to these interfaces should be
non-negative. Future enhancements may make use of negative N
values to define new kinds of function caching behavior.
*/
valueAt(argNdx);
CApi.sqlite3_set_auxdata(cx, argNdx, o);
}
/**
Analog to sqlite3_get_auxdata() but throws if argNdx is out of
range.
*/
public Object getAuxData(int argNdx){
valueAt(argNdx);
return CApi.sqlite3_get_auxdata(cx, argNdx);
}
/**
Represents a single SqlFunction argument. Primarily intended
Wrapper for a single SqlFunction argument. Primarily intended
for use with the Arguments class's Iterable interface.
*/
public final static class Arg {
@@ -186,7 +72,7 @@ public interface SqlFunction {
public int getBytes(){return a.getBytes(ndx);}
public int getBytes16(){return a.getBytes16(ndx);}
public Object getObject(){return a.getObject(ndx);}
public <T> T getObject(Class<T> type){ return a.getObject(ndx, type); }
public <T> T getObjectCasted(Class<T> type){ return a.getObjectCasted(ndx, type); }
public int getType(){return a.getType(ndx);}
public Object getAuxData(){return a.getAuxData(ndx);}
public void setAuxData(Object o){a.setAuxData(ndx, o);}
@@ -201,6 +87,147 @@ public interface SqlFunction {
return java.util.Arrays.stream(proxies).iterator();
}
/**
Returns the sqlite3_value at the given argument index or throws
an IllegalArgumentException exception if ndx is out of range.
*/
private sqlite3_value valueAt(int ndx){
if(ndx<0 || ndx>=args.length){
throw new IllegalArgumentException(
"SQL function argument index "+ndx+" is out of range."
);
}
return args[ndx];
}
sqlite3_context getContext(){return cx;}
public int getArgCount(){ return args.length; }
public int getInt(int arg){return CApi.sqlite3_value_int(valueAt(arg));}
public long getInt64(int arg){return CApi.sqlite3_value_int64(valueAt(arg));}
public double getDouble(int arg){return CApi.sqlite3_value_double(valueAt(arg));}
public byte[] getBlob(int arg){return CApi.sqlite3_value_blob(valueAt(arg));}
public byte[] getText(int arg){return CApi.sqlite3_value_text(valueAt(arg));}
public String getText16(int arg){return CApi.sqlite3_value_text16(valueAt(arg));}
public int getBytes(int arg){return CApi.sqlite3_value_bytes(valueAt(arg));}
public int getBytes16(int arg){return CApi.sqlite3_value_bytes16(valueAt(arg));}
public Object getObject(int arg){return CApi.sqlite3_value_java_object(valueAt(arg));}
public <T> T getObjectCasted(int arg, Class<T> type){
return CApi.sqlite3_value_java_casted(valueAt(arg), type);
}
public int getType(int arg){return CApi.sqlite3_value_type(valueAt(arg));}
public int getSubtype(int arg){return CApi.sqlite3_value_subtype(valueAt(arg));}
public int getNumericType(int arg){return CApi.sqlite3_value_numeric_type(valueAt(arg));}
public int getNoChange(int arg){return CApi.sqlite3_value_nochange(valueAt(arg));}
public boolean getFromBind(int arg){return CApi.sqlite3_value_frombind(valueAt(arg));}
public int getEncoding(int arg){return CApi.sqlite3_value_encoding(valueAt(arg));}
public void resultInt(int v){ CApi.sqlite3_result_int(cx, v); }
public void resultInt64(long v){ CApi.sqlite3_result_int64(cx, v); }
public void resultDouble(double v){ CApi.sqlite3_result_double(cx, v); }
public void resultError(String msg){CApi.sqlite3_result_error(cx, msg);}
public void resultError(Exception e){CApi.sqlite3_result_error(cx, e);}
public void resultErrorTooBig(){CApi.sqlite3_result_error_toobig(cx);}
public void resultErrorCode(int rc){CApi.sqlite3_result_error_code(cx, rc);}
public void resultObject(Object o){CApi.sqlite3_result_java_object(cx, o);}
public void resultNull(){CApi.sqlite3_result_null(cx);}
public void resultArg(int argNdx){CApi.sqlite3_result_value(cx, valueAt(argNdx));}
public void resultZeroBlob(long n){
// Throw on error? If n is too big,
// sqlite3_result_error_toobig() is automatically called.
CApi.sqlite3_result_zeroblob64(cx, n);
}
public void resultBlob(byte[] blob){CApi.sqlite3_result_blob(cx, blob);}
public void resultText(byte[] utf8){CApi.sqlite3_result_text(cx, utf8);}
public void resultText(String txt){CApi.sqlite3_result_text(cx, txt);}
public void resultText16(byte[] utf16){CApi.sqlite3_result_text16(cx, utf16);}
public void resultText16(String txt){CApi.sqlite3_result_text16(cx, txt);}
public void setAuxData(int arg, Object o){
/* From the API docs: https://www.sqlite.org/c3ref/get_auxdata.html
The value of the N parameter to these interfaces should be
non-negative. Future enhancements may make use of negative N
values to define new kinds of function caching behavior.
*/
valueAt(arg);
CApi.sqlite3_set_auxdata(cx, arg, o);
}
public Object getAuxData(int arg){
valueAt(arg);
return CApi.sqlite3_get_auxdata(cx, arg);
}
}
/**
PerContextState assists aggregate and window functions in
managing their accumulator state across calls to the UDF's
callbacks.
<p>T must be of a type which can be legally stored as a value in
java.util.HashMap<KeyType,T>.
<p>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.
<p>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.
<p>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 {@link AggregateFunction} and {@link
WindowFunction} 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 the given context 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.
<p>The caller is obligated to eventually call
takeAggregateState() to clear the mapping.
*/
public ValueHolder<T> getAggregateState(SqlFunction.Arguments args, T initialValue){
final Long key = args.getContext().getAggregateContext(true);
ValueHolder<T> rc = null==key ? null : map.get(key);
if( null==rc ){
map.put(key, 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 with the arguments' aggregate context 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(SqlFunction.Arguments args){
final ValueHolder<T> h = map.remove(args.getContext().getAggregateContext(false));
return null==h ? null : h.value;
}
}
/**
@@ -208,7 +235,7 @@ public interface SqlFunction {
for use with the org.sqlite.jni.capi.ScalarFunction interface.
*/
static final class ScalarAdapter extends org.sqlite.jni.capi.ScalarFunction {
private final ScalarFunction impl;
final ScalarFunction impl;
ScalarAdapter(ScalarFunction impl){
this.impl = impl;
}
@@ -234,9 +261,8 @@ public interface SqlFunction {
Internal-use adapter for wrapping this package's AggregateFunction
for use with the org.sqlite.jni.capi.AggregateFunction interface.
*/
static /*cannot be final without duplicating the whole body in WindowAdapter*/
class AggregateAdapter extends org.sqlite.jni.capi.AggregateFunction {
private final AggregateFunction impl;
static final class AggregateAdapter extends org.sqlite.jni.capi.AggregateFunction {
final AggregateFunction impl;
AggregateAdapter(AggregateFunction impl){
this.impl = impl;
}
@@ -256,9 +282,8 @@ public interface SqlFunction {
}
/**
As for the xFinal() argument of the C API's
sqlite3_create_function(). If the proxied function throws, it
is translated into a sqlite3_result_error().
As for the xFinal() argument of the C API's sqlite3_create_function().
If the proxied function throws, it is translated into a sqlite3_result_error().
*/
public void xFinal(sqlite3_context cx){
try{
@@ -273,46 +298,4 @@ public interface SqlFunction {
}
}
/**
Internal-use adapter for wrapping this package's WindowFunction
for use with the org.sqlite.jni.capi.WindowFunction interface.
*/
static final class WindowAdapter extends AggregateAdapter {
private final WindowFunction impl;
WindowAdapter(WindowFunction impl){
super(impl);
this.impl = impl;
}
/**
Proxies this.impl.xInverse(), adapting the call arguments to that
function's signature. If the proxied function throws, it is
translated to sqlite_result_error() with the exception's
message.
*/
public void xInverse(sqlite3_context cx, sqlite3_value[] args){
try{
impl.xInverse( new SqlFunction.Arguments(cx, args) );
}catch(Exception e){
CApi.sqlite3_result_error(cx, e);
}
}
/**
As for the xValue() argument of the C API's sqlite3_create_window_function().
If the proxied function throws, it is translated into a sqlite3_result_error().
*/
public void xValue(sqlite3_context cx){
try{
impl.xValue( new SqlFunction.Arguments(cx, null) );
}catch(Exception e){
CApi.sqlite3_result_error(cx, e);
}
}
public void xDestroy(){
impl.xDestroy();
}
}
}
File diff suppressed because it is too large Load Diff
@@ -12,7 +12,7 @@
** This file is part of the wrapper1 interface for sqlite3.
*/
package org.sqlite.jni.wrapper1;
import org.sqlite.jni.capi.CApi;
import static org.sqlite.jni.capi.CApi.*;
import org.sqlite.jni.capi.sqlite3;
/**
@@ -22,10 +22,10 @@ import org.sqlite.jni.capi.sqlite3;
and C via JNI.
*/
public final class SqliteException extends java.lang.RuntimeException {
private int errCode = CApi.SQLITE_ERROR;
private int xerrCode = CApi.SQLITE_ERROR;
private int errOffset = -1;
private int sysErrno = 0;
int errCode = SQLITE_ERROR;
int xerrCode = SQLITE_ERROR;
int errOffset = -1;
int sysErrno = 0;
/**
Records the given error string and uses SQLITE_ERROR for both the
@@ -38,31 +38,28 @@ public final class SqliteException extends java.lang.RuntimeException {
/**
Uses sqlite3_errstr(sqlite3ResultCode) for the error string and
sets both the error code and extended error code to the given
value. This approach includes no database-level information and
systemErrno() will be 0, so is intended only for use with sqlite3
APIs for which a result code is not an error but which the
higher-level wrapper should treat as one.
value.
*/
public SqliteException(int sqlite3ResultCode){
super(CApi.sqlite3_errstr(sqlite3ResultCode));
super(sqlite3_errstr(sqlite3ResultCode));
errCode = xerrCode = sqlite3ResultCode;
}
/**
Records the current error state of db (which must not be null and
must refer to an opened db object). Note that this does not close
must refer to an opened db object). Note that this does NOT close
the db.
Design note: closing the db on error is really only useful during
Design note: closing the db on error is likely only useful during
a failed db-open operation, and the place(s) where that can
happen are inside this library, not client-level code.
*/
SqliteException(sqlite3 db){
super(CApi.sqlite3_errmsg(db));
errCode = CApi.sqlite3_errcode(db);
xerrCode = CApi.sqlite3_extended_errcode(db);
errOffset = CApi.sqlite3_error_offset(db);
sysErrno = CApi.sqlite3_system_errno(db);
super(sqlite3_errmsg(db));
errCode = sqlite3_errcode(db);
xerrCode = sqlite3_extended_errcode(db);
errOffset = sqlite3_error_offset(db);
sysErrno = sqlite3_system_errno(db);
}
/**
@@ -74,7 +71,7 @@ public final class SqliteException extends java.lang.RuntimeException {
}
public SqliteException(Sqlite.Stmt stmt){
this(stmt.getDb());
this( stmt.db() );
}
public int errcode(){ return errCode; }
File diff suppressed because it is too large Load Diff
@@ -9,13 +9,13 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the ValueHolder utility class.
** This file contains a set of tests for the sqlite3 JNI bindings.
*/
package org.sqlite.jni.wrapper1;
/**
A helper class which simply holds a single value. Its primary use
is for communicating values out of anonymous callbacks, as doing so
is for communicating values out of anonymous classes, as doing so
requires a "final" reference.
*/
public class ValueHolder<T> {
@@ -1,42 +0,0 @@
/*
** 2023-10-16
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file is part of the wrapper1 interface for sqlite3.
*/
package org.sqlite.jni.wrapper1;
/**
A SqlFunction implementation for window functions. The T type
represents the type of data accumulated by this function while it
works. e.g. a SUM()-like UDF might use Integer or Long and a
CONCAT()-like UDF might use a StringBuilder or a List<String>.
*/
public abstract class WindowFunction<T> extends AggregateFunction<T> {
/**
As for the xInverse() argument of the C API's
sqlite3_create_window_function(). If this function throws, the
exception is reported via sqlite3_result_error().
*/
public abstract void xInverse(SqlFunction.Arguments args);
/**
As for the xValue() argument of the C API's
sqlite3_create_window_function(). If this function throws, it is
translated into sqlite3_result_error().
Note that the passed-in object will not actually contain any
arguments for xValue() but will contain the context object needed
for setting the call's result or error state.
*/
public abstract void xValue(SqlFunction.Arguments args);
}
+1 -1
View File
@@ -52,7 +52,7 @@ static unsigned int prngInt(Prng *p){
}
static const char *azJsonAtoms[] = {
/* JSON /* JSON-5 */
/* JSON JSON-5 */
"0", "0",
"1", "1",
"-1", "-1",
+27 -11
View File
@@ -170,6 +170,7 @@ struct Rtree {
u32 nBusy; /* Current number of users of this structure */
i64 nRowEst; /* Estimated number of rows in this table */
u32 nCursor; /* Number of open cursors */
u32 iGeneration; /* Cursors with smaller iGeneration are stale */
u32 nNodeRef; /* Number RtreeNodes with positive nRef */
char *zReadAuxSql; /* SQL for statement to read aux data */
@@ -286,6 +287,7 @@ struct RtreeCursor {
u8 atEOF; /* True if at end of search */
u8 bPoint; /* True if sPoint is valid */
u8 bAuxValid; /* True if pReadAux is valid */
u32 iGeneration; /* Stale if too small */
int iStrategy; /* Copy of idxNum search parameter */
int nConstraint; /* Number of entries in aConstraint */
RtreeConstraint *aConstraint; /* Search constraints. */
@@ -694,11 +696,9 @@ static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){
** Clear the Rtree.pNodeBlob object
*/
static void nodeBlobReset(Rtree *pRtree){
if( pRtree->pNodeBlob && pRtree->inWrTrans==0 && pRtree->nCursor==0 ){
sqlite3_blob *pBlob = pRtree->pNodeBlob;
pRtree->pNodeBlob = 0;
sqlite3_blob_close(pBlob);
}
sqlite3_blob *pBlob = pRtree->pNodeBlob;
pRtree->pNodeBlob = 0;
sqlite3_blob_close(pBlob);
}
/*
@@ -742,7 +742,6 @@ static int nodeAcquire(
&pRtree->pNodeBlob);
}
if( rc ){
nodeBlobReset(pRtree);
*ppNode = 0;
/* If unable to open an sqlite3_blob on the desired row, that can only
** be because the shadow tables hold erroneous data. */
@@ -802,6 +801,7 @@ static int nodeAcquire(
}
*ppNode = pNode;
}else{
nodeBlobReset(pRtree);
if( pNode ){
pRtree->nNodeRef--;
sqlite3_free(pNode);
@@ -1087,6 +1087,7 @@ static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
if( pCsr ){
memset(pCsr, 0, sizeof(RtreeCursor));
pCsr->base.pVtab = pVTab;
pCsr->iGeneration = pRtree->iGeneration;
rc = SQLITE_OK;
pRtree->nCursor++;
}
@@ -1135,7 +1136,9 @@ static int rtreeClose(sqlite3_vtab_cursor *cur){
sqlite3_finalize(pCsr->pReadAux);
sqlite3_free(pCsr);
pRtree->nCursor--;
nodeBlobReset(pRtree);
if( pRtree->nCursor==0 && pRtree->inWrTrans==0 ){
nodeBlobReset(pRtree);
}
return SQLITE_OK;
}
@@ -1627,6 +1630,9 @@ static int rtreeStepToLeaf(RtreeCursor *pCur){
int eInt;
RtreeSearchPoint x;
if( pCur->iGeneration<pRtree->iGeneration ){
return SQLITE_ABORT_ROLLBACK;
}
eInt = pRtree->eCoordType==RTREE_COORD_INT32;
while( (p = rtreeSearchPointFirst(pCur))!=0 && p->iLevel>0 ){
u8 *pCellData;
@@ -1854,6 +1860,7 @@ static int rtreeFilter(
/* Reset the cursor to the same state as rtreeOpen() leaves it in. */
resetCursor(pCsr);
pCsr->iGeneration = pRtree->iGeneration;
pCsr->iStrategy = idxNum;
if( idxNum==1 ){
@@ -3219,8 +3226,7 @@ constraint:
*/
static int rtreeBeginTransaction(sqlite3_vtab *pVtab){
Rtree *pRtree = (Rtree *)pVtab;
assert( pRtree->inWrTrans==0 );
pRtree->inWrTrans++;
pRtree->inWrTrans = 1;
return SQLITE_OK;
}
@@ -3234,6 +3240,16 @@ static int rtreeEndTransaction(sqlite3_vtab *pVtab){
nodeBlobReset(pRtree);
return SQLITE_OK;
}
static int rtreeRollback(sqlite3_vtab *pVtab){
Rtree *pRtree = (Rtree *)pVtab;
pRtree->iGeneration++;
return rtreeEndTransaction(pVtab);
}
static int rtreeRollbackTo(sqlite3_vtab *pVtab, int notUsed){
Rtree *pRtree = (Rtree *)pVtab;
pRtree->iGeneration++;
return SQLITE_OK;
}
/*
** The xRename method for rtree module virtual tables.
@@ -3352,12 +3368,12 @@ static sqlite3_module rtreeModule = {
rtreeBeginTransaction, /* xBegin - begin transaction */
rtreeEndTransaction, /* xSync - sync transaction */
rtreeEndTransaction, /* xCommit - commit transaction */
rtreeEndTransaction, /* xRollback - rollback transaction */
rtreeRollback, /* xRollback - rollback transaction */
0, /* xFindFunction - function overloading */
rtreeRename, /* xRename - rename the table */
rtreeSavepoint, /* xSavepoint */
0, /* xRelease */
0, /* xRollbackTo */
rtreeRollbackTo, /* xRollbackTo */
rtreeShadowName, /* xShadowName */
rtreeIntegrity /* xIntegrity */
};
+163
View File
@@ -0,0 +1,163 @@
# 2024-02-03
#
# 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.
#
#***********************************************************************
#
# ROLLBACK in the middle of an RTREE query
#
if {![info exists testdir]} {
set testdir [file join [file dirname [info script]] .. .. test]
}
source $testdir/tester.tcl
set testprefix rtreeJ
ifcapable !rtree {
finish_test
return
}
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING rtree(id, x1, x2);
INSERT INTO t1 VALUES(1, 1, 1), (2, 2, 2);
} {}
do_execsql_test 1.1 {
SELECT * FROM t1
} {1 1.0 1.0 2 2.0 2.0}
# If a ROLLBACK occurs that backs out changes to the RTREE, then
# all pending queries to the RTREE are aborted.
#
do_test 1.2 {
db eval {
BEGIN;
INSERT INTO t1 VALUES(3, 3, 3);
INSERT INTO t1 VALUES(4, 4, 4);
}
set rc [catch {
db eval { SELECT * FROM t1 } {
if {$id==1} {
db eval { ROLLBACK }
}
lappend res $id $x1 $x2
}
} msg]
list $rc $msg
} {1 {abort due to ROLLBACK}}
do_execsql_test 1.3 {
SELECT * FROM t1;
} {1 1.0 1.0 2 2.0 2.0}
# A COMMIT of changes to the RTREE does not affect pending queries
#
do_test 1.4 {
set res {}
db eval {
BEGIN;
INSERT INTO t1 VALUES(5, 5, 5);
INSERT INTO t1 VALUES(6, 6, 6);
}
db eval { SELECT * FROM t1 } {
if {$id==1} {
db eval { COMMIT }
}
lappend res $id $x1 $x2
}
set res
} {1 1.0 1.0 2 2.0 2.0 5 5.0 5.0 6 6.0 6.0}
do_execsql_test 1.5 {
SELECT * FROM t1;
} {1 1.0 1.0 2 2.0 2.0 5 5.0 5.0 6 6.0 6.0}
do_execsql_test 1.6 {
DELETE FROM t1;
INSERT INTO t1 VALUES(1,1,1),(2,2,2),(3,3,3),(4,4,4);
CREATE TABLE t2(x);
SELECT * FROM t1;
} {1 1.0 1.0 2 2.0 2.0 3 3.0 3.0 4 4.0 4.0}
# A rollback that does not affect the rtree table because
# the rtree table has not been written to does not cause
# a query abort.
#
do_test 1.7 {
set res {}
db eval {
BEGIN;
INSERT INTO t2(x) VALUES(12345);
}
db eval { SELECT * FROM t1 } {
if {$id==1} {
db eval { ROLLBACK }
}
lappend res $id $x1 $x2
}
set res
} {1 1.0 1.0 2 2.0 2.0 3 3.0 3.0 4 4.0 4.0}
# ROLLBACK TO that affects the RTREE does cause a query abort.
#
do_test 1.8 {
db eval {
DELETE FROM t1 WHERE rowid>1;
BEGIN;
DELETE FROM t2;
INSERT INTO t2(x) VALUES(23456);
SAVEPOINT 'one';
INSERT INTO t1 VALUES(2,2,2),(3,3,3);
}
set rc [catch {
db eval { SELECT * FROM t1 } {
if {$id==1} {
db eval { ROLLBACK TO 'one'; }
}
lappend res $id $x1 $x2
}
} msg]
list $rc $msg
} {1 {abort due to ROLLBACK}}
do_execsql_test 1.9 {
COMMIT;
SELECT * FROM t1;
} {1 1.0 1.0}
# ROLLBACK TO that does not affect the RTREE does not cause a query abort.
#
do_execsql_test 1.10 {
DELETE FROM t1;
INSERT INTO t1 VALUES(1,1,1),(2,2,2),(3,3,3);
BEGIN;
DELETE FROM t2;
INSERT INTO t2(x) VALUES(34567);
SAVEPOINT 'one';
INSERT INTO t2(x) VALUES('a string');
SELECT * FROM t1;
} {1 1.0 1.0 2 2.0 2.0 3 3.0 3.0}
do_test 1.11 {
set rc [catch {
set res {}
db eval { SELECT * FROM t1 } {
if {$id==2} {
# db eval { ROLLBACK TO 'one'; }
}
lappend res $id $x1 $x2
}
set res
} msg]
list $rc $msg
} {0 {1 1.0 1.0 2 2.0 2.0 3 3.0 3.0}}
do_execsql_test 1.12 {
COMMIT;
SELECT * FROM t1;
} {1 1.0 1.0 2 2.0 2.0 3 3.0 3.0}
finish_test
@@ -63,7 +63,6 @@ _sqlite3_file_control
_sqlite3_finalize
_sqlite3_free
_sqlite3_get_auxdata
_sqlite3_get_autocommit
_sqlite3_initialize
_sqlite3_keyword_count
_sqlite3_keyword_name
-1
View File
@@ -188,7 +188,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
["sqlite3_file_control", "int", "sqlite3*", "string", "int", "*"],
["sqlite3_finalize", "int", "sqlite3_stmt*"],
["sqlite3_free", undefined,"*"],
["sqlite3_get_autocommit", "int", "sqlite3*"],
["sqlite3_get_auxdata", "*", "sqlite3_context*", "int"],
["sqlite3_initialize", undefined],
/*["sqlite3_interrupt", undefined, "sqlite3*"
+1 -32
View File
@@ -62,7 +62,7 @@
```
{
type: string, // one of: 'open', 'close', 'exec', 'export', 'config-get'
type: string, // one of: 'open', 'close', 'exec', 'config-get'
messageId: OPTIONAL arbitrary value. The worker will copy it as-is
into response messages to assist in client-side dispatching.
@@ -325,37 +325,6 @@
passed only a string), noting that options.resultRows and
options.columnNames may be populated by the call to db.exec().
====================================================================
"export" the current db
To export the underlying database as a byte array...
Message format:
```
{
type: "export",
messageId: ...as above...,
dbId: ...as above...
}
```
Response:
```
{
type: "export",
messageId: ...as above...,
dbId: ...as above...
result: {
byteArray: Uint8Array (as per sqlite3_js_db_export()),
filename: the db filename,
mimetype: "application/x-sqlite3"
}
}
```
*/
globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
sqlite3.initWorker1API = function(){
@@ -199,10 +199,11 @@ globalThis.sqlite3Worker1Promiser = function callee(config = callee.defaultConfi
msg = Object.create(null);
msg.type = arguments[0];
msg.args = arguments[1];
msg.dbId = msg.args.dbId;
}else{
toss("Invalid arugments for sqlite3Worker1Promiser()-created factory.");
}
if(!msg.dbId) msg.dbId = dbId;
if(!msg.dbId && msg.type!=='open') msg.dbId = dbId;
msg.messageId = genMsgId(msg);
msg.departureTime = performance.now();
const proxy = Object.create(null);
+1 -1
View File
@@ -22,7 +22,7 @@ const tryOpfsVfs = async function(sqlite3){
const opfs = sqlite3.opfs;
log("tryOpfsVfs()");
if(!sqlite3.opfs){
const e = new Error("OPFS is not available.");
const e = toss("OPFS is not available.");
error(e);
throw e;
}
+24 -6
View File
@@ -1688,7 +1688,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
wasm.sqlite3_wasm_vfs_unlink(0, filename);
}
}
}/*sqlite3_js_posix_create_file()*/)
}/*sqlite3_js_vfs_create_file()*/)
////////////////////////////////////////////////////////////////////
.t({
@@ -2605,6 +2605,28 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
}
}
}/*kvvfs sanity checks*/)
.t({
name: 'kvvfs sqlite3_js_vfs_create_file()',
predicate: ()=>"kvvfs does not currently support this",
test: function(sqlite3){
let db;
try {
db = new this.JDb(this.kvvfsDbFile);
const exp = capi.sqlite3_js_db_export(db);
db.close();
this.kvvfsUnlink();
capi.sqlite3_js_vfs_create_file("kvvfs", this.kvvfsDbFile, exp);
db = new this.JDb(filename);
T.assert(6 === db.selectValue('select count(*) from kvvfs'));
}finally{
db.close();
this.kvvfsUnlink();
}
delete this.kvvfsDbFile;
delete this.kvvfsUnlink;
delete this.JDb;
}
}/*kvvfs sqlite3_js_vfs_create_file()*/)
;/* end kvvfs tests */
////////////////////////////////////////////////////////////////////////
@@ -2622,17 +2644,13 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
T.assert( 0 === rc /*void pointer*/ );
// Commit hook...
T.assert( 0!=capi.sqlite3_get_autocommit(db) );
db.exec("BEGIN; SELECT 1; COMMIT");
T.assert(0 === countCommit,
"No-op transactions (mostly) do not trigger commit hook.");
db.exec("BEGIN EXCLUSIVE; SELECT 1; COMMIT");
T.assert(1 === countCommit,
"But EXCLUSIVE transactions do.");
db.transaction((d)=>{
T.assert( 0==capi.sqlite3_get_autocommit(db) );
d.exec("create table t(a)");
});
db.transaction((d)=>{d.exec("create table t(a)");});
T.assert(2 === countCommit);
// Rollback hook:
+120 -120
View File
@@ -1,13 +1,13 @@
C Enhance\sjson_set()\sand\sjson_insert()\sso\sthat\sthey\screate\smissing\nsubstructure.
D 2023-11-30T19:06:27.003
C When\scompiling\swith\sSQLITE_ALLOW_ROWID_IN_VIEW,\sif\sthe\sRETURNING\sclause\sof\nan\sUPDATE\sof\sa\sview\sspecifies\sa\srowid,\sthen\sreturn\sNULL\sfor\sthe\svalue\sof\nthat\srowid.
D 2024-04-05T11:28:30.003
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F Makefile.in 890caf094636c308bc981032baf8f9208bf307755f9197ae4218a9fbcec2e449
F Makefile.in bddd493839ce057414b19cd405293363f7efb7a73a3d8f6d2ed1b59943ddfcb1
F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6
F Makefile.msc 59bb36dba001f0b38212be0794fb838f25371008b180929bcf08aa799694c168
F README.md 963d30019abf0cc06b263cd2824bce022893f3f93a531758f6f04ff2194a16a8
F VERSION 73573d4545343f001bf5dc5461173a7c78c203dd046cabcf99153878cf25d3a6
F VERSION f0eb9cf12b1e93e08b432d291700cf3070520acf5ff61179b8255692796479af
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
@@ -22,7 +22,7 @@ F autoconf/configure.ac ec7fa914c5e74ff212fe879f9bb6918e1234497e05facfb641f30c4d
F autoconf/tea/Makefile.in 106a96f2f745d41a0f6193f1de98d7355830b65d45032c18cd7c90295ec24196
F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873
F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43
F autoconf/tea/configure.ac 4c32b08691a5b296206b38422b53b92b65be3d3f6b3dd6552a50981a61f5acda
F autoconf/tea/configure.ac cb76419c9517a5ea0352f54d04e7fc76ddc458802977dd018bf7d0525b4d374a
F autoconf/tea/doc/sqlite3.n e1fe45d4f5286ee3d0ccc877aca2a0def488e9bb
F autoconf/tea/license.terms 13bd403c9610fd2b76ece0ab50c4c5eda933d523
F autoconf/tea/pkgIndex.tcl.in b9eb6dd37f64e08e637d576b3c83259814b9cddd78bec4af2e5abfc6c5c750ce
@@ -33,15 +33,15 @@ F autoconf/tea/win/nmakehlp.c b01f822eabbe1ed2b64e70882d97d48402b42d2689a1ea0034
F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6
F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559
F configure bcb1042e92775424a1021d2f4c89c78a699a6225df01fa8c593df7df0be6ad10 x
F configure.ac f25bd7843120f2c2b8bc9db5a92b0502bbdd28e68907415c3d42fc8e57c657b9
F configure 2a61e83abe68a86bf6fe114887c659275b83d2561d5aa7445aec621b6ca239b8 x
F configure.ac de31fea7d975bb7ebafbe0e2190a855cc80d48558bf0c9a6578a1836daf1cd3a
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
F doc/compile-for-windows.md 50b27d77be96195c66031a3181cb8684ed822327ea834e07f9c014213e5e3bcf
F doc/compile-for-windows.md 922ba580d210a1f1bd3ef9d0413121556f9b5714fb5c01e664d980f85fa4ac8c
F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347bb123ce1ea4f
F doc/lemon.html 44a53a1d2b42d7751f7b2f478efb23c978e258d794bfd172442307a755b9fa44
F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710
F doc/testrunner.md 8d36ec692cf4994bb66d84a4645b9afa1ce9d47dc12cbf8d437c5a5fb6ddeedb
F doc/testrunner.md 2434864be2219d4f0b6ffc99d0a2172d531c4ca4345340776f67ad4edd90dc90
F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a
F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc14046bc49df56
F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a
@@ -50,8 +50,8 @@ F ext/README.md fd5f78013b0a2bc6f0067afb19e6ad040e89a10179b4f6f03eee58fac5f169bd
F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91
F ext/async/sqlite3async.c 6f247666b495c477628dd19364d279c78ea48cd90c72d9f9b98ad1aff3294f94
F ext/async/sqlite3async.h 46b47c79357b97ad85d20d2795942c0020dc20c532114a49808287f04aa5309a
F ext/consio/console_io.c 097323f60037d70523421f0248958d2280851f8ff2f9a443d4ee1474c4769118 x
F ext/consio/console_io.h 3228dff1717481202a24f6dcf45ce0b75e7a778bf6877089518a44e1473b76a3
F ext/consio/console_io.c e048bd69f3a357a4b6b5da01c504728631d944ad5735ad83c44800c80a91e978 x
F ext/consio/console_io.h d18bcc50f4e4d42b65be8fecba72918364ae77182c86360aca842e44b823384e
F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3
F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4
F ext/expert/expert1.test 0dd5cb096d66bed593e33053a3b364f6ef52ed72064bf5cf298364636dbf3cd6
@@ -91,18 +91,18 @@ F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a0
F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
F ext/fts5/fts5.h 05501612cc655504c5dce8ba765ab621d50fc478490089beaa0d75e00b23e520
F ext/fts5/fts5Int.h 78a63cc0795186cde5384816a9403a68c65774b35d952e05b81a1b4b158e07c8
F ext/fts5/fts5_aux.c ee770eec0af8646db9e18fc01a0dad7345b5f5e8cbba236704cfae2d777022ad
F ext/fts5/fts5_aux.c 35c4101613eff86902877a4dedd9400b07922e412cbdd637b45041dce2fd5388
F ext/fts5/fts5_buffer.c 3001fbabb585d6de52947b44b455235072b741038391f830d6b729225eeaf6a5
F ext/fts5/fts5_config.c 054359543566cbff1ba65a188330660a5457299513ac71c53b3a07d934c7b081
F ext/fts5/fts5_expr.c bd3b81ce669c4104e34ffe66570af1999a317b142c15fccb112de9fb0caa57a6
F ext/fts5/fts5_hash.c 076058f93327051952a752dc765df1acfe783eb11b419b30652aa1fc1f987902
F ext/fts5/fts5_index.c 458cbed8a3e17617cbf7e80cdfb7612000b9bb3781f286b345fb9655858658cf
F ext/fts5/fts5_main.c a07ed863b8bd9e6fefb62db2fd40a3518eb30a5f7dcfda5be915dd2db45efa2f
F ext/fts5/fts5_index.c 47a121697c7d832fbc82269c30710bc1e5c3f02785395cad3e64fec47dfb18ae
F ext/fts5/fts5_main.c a08a7d07990bd3118dc8ce2dc0c62fc4503c1f0a6a0ee8b8db9e9c559fa3f820
F ext/fts5/fts5_storage.c 5d10b9bdcce5b90656cad13c7d12ad4148677d4b9e3fca0481fca56d6601426d
F ext/fts5/fts5_tcl.c b1445cbe69908c411df8084a10b2485500ac70a9c747cdc8cda175a3da59d8ae
F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee
F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a9aa85d36f3b
F ext/fts5/fts5_tokenize.c 83cfcede3898001cab84432a36ce1503e3080cf9b1c682b022ec82e267ea4c13
F ext/fts5/fts5_tokenize.c 5e251efb0f1af99a25ed50010ba6b1ad1250aca5921af1988fdcabe5ebc3cb43
F ext/fts5/fts5_unicode2.c eca63dbc797f8ff0572e97caf4631389c0ab900d6364861b915bdd4735973f00
F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80
F ext/fts5/fts5_vocab.c aed56169ae5c1aa9b8189c779ffeef04ed516d3c712c06914e6d91a6759f4e4a
@@ -145,7 +145,7 @@ F ext/fts5/test/fts5corrupt.test b6d4034b682bb3387bc44c510c71b3c67d4349e4df13949
F ext/fts5/test/fts5corrupt2.test 99e7e23a58b4d89eb7167c6de1669cbc595cd3c79ab333e0eb56405473319e77
F ext/fts5/test/fts5corrupt3.test 7da9895dafa404efd20728f66ff4b94399788bdc042c36fe2689801bba2ccd78
F ext/fts5/test/fts5corrupt4.test f4c08e2182a48d8b70975fd869ee5391855c06d8a0ff87b6a2529e7c5a88a1d3
F ext/fts5/test/fts5corrupt5.test 38a238df26c4de471e1c4b98f8de6c902bc692577a1c08d0ff4f2251f3559644
F ext/fts5/test/fts5corrupt5.test 2a2eac2885702a951973ad19bf72c60e998263d7130f0ef910f5ede3a3a99635
F ext/fts5/test/fts5corrupt6.test bf8eeae07825b088b9665d9d8e4accbd8dc9bf3cb85b6c64cf6c9e18ccc420a4
F ext/fts5/test/fts5corrupt7.test 80ad7f683a8bda2404731bb77e8c3dbbb620c1f6cc583cca8239f6accd6338c0
F ext/fts5/test/fts5delete.test 619295b20dbc1d840b403ee07c878f52378849c3c02e44f2ee143b3e978a0aa7
@@ -182,7 +182,7 @@ F ext/fts5/test/fts5limits.test 8ab67cf5d311c124b6ceb0062d0297767176df4572d955fc
F ext/fts5/test/fts5matchinfo.test 10c9a6f7fe61fb132299c4183c012770b10c4d5c2f2edb6df0b6607f683d737a
F ext/fts5/test/fts5merge.test e92a8db28b45931e7a9c7b1bbd36101692759d00274df74d83fd29d25d53b3a6
F ext/fts5/test/fts5merge2.test 3ebad1a59d6ad3fb66eff6523a09e95dc6367cbefb3cd73196801dea0425c8e2
F ext/fts5/test/fts5misc.test 5ca82f2a5ee016b0842043155d1382f98a34d0d86b2791165a44d7807f6e0f54
F ext/fts5/test/fts5misc.test 89dc46e37951b7f6653809f4abf6b1ca2f1fa62259efaf719339288f76fb6be9
F ext/fts5/test/fts5multi.test a15bc91cdb717492e6e1b66fec1c356cb57386b980c7ba5af1915f97fe878581
F ext/fts5/test/fts5multiclient.test 5ff811c028d6108045ffef737f1e9f05028af2458e456c0937c1d1b8dea56d45
F ext/fts5/test/fts5near.test 211477940142d733ac04fad97cb24095513ab2507073a99c2765c3ddd2ef58bd
@@ -219,9 +219,7 @@ F ext/fts5/test/fts5synonym2.test 8f891fc49cc1e8daed727051e77e1f42849c784a6a54be
F ext/fts5/test/fts5tok1.test 1f7817499f5971450d8c4a652114b3d833393c8134e32422d0af27884ffe9cef
F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2
F ext/fts5/test/fts5tokenizer.test ac3c9112b263a639fb0508ae73a3ee886bf4866d2153771a8e8a20c721305a43
F ext/fts5/test/fts5tokenizer2.test cb5428c7cfb3b6a74b7adfcde65506e329112003e8dffa7501d01c2d18d02569
F ext/fts5/test/fts5trigram.test 6c4e37864f3e7d90673db5563d9736d7e40080ab94d10ebdffa94c1b77941da0
F ext/fts5/test/fts5trigram2.test 9fe4207f8a4241747aff1005258b564958588d21bfd240d6cd4c2e955d31c156
F ext/fts5/test/fts5ubsan.test 783d5a8d13ebfa169e634940228db54540780e3ba7a87ad1e4510e61440bf64b
F ext/fts5/test/fts5umlaut.test a42fe2fe6387c40c49ab27ccbd070e1ae38e07f38d05926482cc0bccac9ad602
F ext/fts5/test/fts5unicode.test 17056f4efe6b0a5d4f41fdf7a7dc9af2873004562eaa899d40633b93dc95f5a9
@@ -241,50 +239,49 @@ 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 59eb05f2a363bdfac8d15d66bed624bfe1ff289229184f3861b95f98a19cf4b2
F ext/jni/README.md d899789a9082a07b99bf30b1bbb6204ae57c060efcaa634536fa669323918f42
F ext/jni/GNUmakefile 5c3ac326bf3853486ebe0d70819abc790cc65c412182ce4ebd5012b008d9b059
F ext/jni/README.md ef9ac115e97704ea995d743b4a8334e23c659e5534c3b64065a5405256d5f2f4
F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa
F ext/jni/src/c/sqlite3-jni.c 6040c0de97644a1fb14bb589ee9f2f4208f6e6b165d14a0e33ed24945b118838
F ext/jni/src/c/sqlite3-jni.h 913ab8e8fee432ae40f0e387c8231118d17053714703f5ded18202912a8a3fbf
F ext/jni/src/org/sqlite/jni/annotation/Experimental.java 8603498634e41d0f7c70f661f64e05df64376562ea8f126829fd1e0cdd47e82b
F ext/jni/src/org/sqlite/jni/annotation/NotNull.java 38e7e58a69b26dc100e458b31dfa3b2a7d67bc36d051325526ef1987d5bc8a24
F ext/jni/src/org/sqlite/jni/annotation/Nullable.java 56e3dee1f3f703a545dfdeddc1c3d64d1581172b1ad01ffcae95c18547fafd90
F ext/jni/src/c/sqlite3-jni.c 6f6df9657989e9ca2cfdcc2fe9a71c279de56d5c941adfd09a0f24256de35c8f
F ext/jni/src/c/sqlite3-jni.h b4c413a0d0c734683da1049cfcf89e35ae2719759d0656ec0f8c57188f18cab8
F ext/jni/src/org/sqlite/jni/annotation/NotNull.java a99341e88154e70447596b1af6a27c586317df41a7e0f246fd41370cd7b723b2
F ext/jni/src/org/sqlite/jni/annotation/Nullable.java 0b1879852707f752512d4db9d7edd0d8db2f0c2612316ce1c832715e012ff6ba
F ext/jni/src/org/sqlite/jni/annotation/package-info.java 977b374aed9d5853cbf3438ba3b0940abfa2ea4574f702a2448ee143b98ac3ca
F ext/jni/src/org/sqlite/jni/capi/AbstractCollationCallback.java 1afa90d3f236f79cc7fcd2497e111992644f7596fbc8e8bcf7f1908ae00acd6c
F ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java 0b72cdff61533b564d65b63418129656daa9a9f30e7e7be982bd5ab394b1dbd0
F ext/jni/src/org/sqlite/jni/capi/AuthorizerCallback.java c045a5b47e02bb5f1af91973814a905f12048c428a3504fbc5266d1c1be3de5a
F ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java bc29e986c866c2ddbbb9f935f5b7264c1c1026864e50a4a735192864f75e37c0
F ext/jni/src/org/sqlite/jni/capi/AuthorizerCallback.java 7ed409d5449684616cc924534e22ff6b07d361f12ad904b69ecb10e0568a8013
F ext/jni/src/org/sqlite/jni/capi/AutoExtensionCallback.java 74cc4998a73d6563542ecb90804a3c4f4e828cb4bd69e61226d1a51f4646e759
F ext/jni/src/org/sqlite/jni/capi/BusyHandlerCallback.java 7b8e19810c42b0ad21a04b5d8c804b32ee5905d137148703f16a75b612c380ca
F ext/jni/src/org/sqlite/jni/capi/CApi.java d428a1fd3b827f01c55d10d21ff35e33e7dac9e8a1d92a8b5c7d7255e67407d8
F ext/jni/src/org/sqlite/jni/capi/CallbackProxy.java 57e2d275dcebe690b1fc1f3d34eb96879b2d7039bce30b563aee547bf45d8a8b
F ext/jni/src/org/sqlite/jni/capi/CApi.java bccb442ca81cd4decb1adae99006a60b7a9f54e5153842e738c01104e97d1de0
F ext/jni/src/org/sqlite/jni/capi/CallbackProxy.java 0bfd6e56e8265c2f05c9207665707285534d78f8466ef0e0430c65677f00943d
F ext/jni/src/org/sqlite/jni/capi/CollationCallback.java e29bcfc540fdd343e2f5cca4d27235113f2886acb13380686756d5cabdfd065a
F ext/jni/src/org/sqlite/jni/capi/CollationNeededCallback.java 5bfa226a8e7a92e804fd52d6e42b4c7b875fa7a94f8e2c330af8cc244a8920ab
F ext/jni/src/org/sqlite/jni/capi/CommitHookCallback.java 482f53dfec9e3ac2a9070d3fceebd56250932aaaf7c4f5bc8de29fc011416e0c
F ext/jni/src/org/sqlite/jni/capi/CollationNeededCallback.java f81cf10b79c52f9b2e9247d523d29ae48863935f60420eae35f257c38c80ce95
F ext/jni/src/org/sqlite/jni/capi/CommitHookCallback.java 29c002f3c638cc80f7db1594564a262d1beb32637824c3dca2d60a224d1f71d7
F ext/jni/src/org/sqlite/jni/capi/ConfigLogCallback.java b995ca412f59b631803b93aa5b3684fce62e335d1e123207084c054abfd488d4
F ext/jni/src/org/sqlite/jni/capi/ConfigSqlLogCallback.java e5723900b6458bc6288f52187090a78ebe0a20f403ac7c887ec9061dfe51aba7
F ext/jni/src/org/sqlite/jni/capi/ConfigSqllogCallback.java 701f2e4d8bdeb27cfbeeb56315d15b13d8752b0fdbca705f31bd4366c58d8a33
F ext/jni/src/org/sqlite/jni/capi/NativePointerHolder.java b7036dcb1ef1b39f1f36ac605dde0ff1a24a9a01ade6aa1a605039443e089a61
F ext/jni/src/org/sqlite/jni/capi/OutputPointer.java 246b0e66c4603f41c567105a21189d138aaf8c58203ecd4928802333da553e7c
F ext/jni/src/org/sqlite/jni/capi/PrepareMultiCallback.java 97352091abd7556167f4799076396279a51749fdae2b72a6ba61cd39b3df0359
F ext/jni/src/org/sqlite/jni/capi/PreupdateHookCallback.java efcf57545c5e282d1dd332fa63329b3b218d98f356ef107a9dbe3979be82213a
F ext/jni/src/org/sqlite/jni/capi/OutputPointer.java 68f60aec7aeb5cd4e5fb83449037f668c63cb99f682ee1036cc226d0cbd909b9
F ext/jni/src/org/sqlite/jni/capi/PrepareMultiCallback.java aca8f9fa72e3b6602bc9a7dd3ae9f5b2808103fbbee9b2749dc96c19cdc261a1
F ext/jni/src/org/sqlite/jni/capi/PreupdateHookCallback.java 819d938e26208adde17ca4b7ddde1d8cd6915b6ab7b708249a9787beca6bd6b6
F ext/jni/src/org/sqlite/jni/capi/ProgressHandlerCallback.java 01bc0c238eed2d5f93c73522cb7849a445cc9098c2ed1e78248fa20ed1cfde5b
F ext/jni/src/org/sqlite/jni/capi/ResultCode.java 8141171f1bcf9f46eef303b9d3c5dc2537a25ad1628f3638398d8a60cacefa7f
F ext/jni/src/org/sqlite/jni/capi/RollbackHookCallback.java e172210a2080e851ebb694c70e9f0bf89284237795e38710a7f5f1b61e3f6787
F ext/jni/src/org/sqlite/jni/capi/SQLFunction.java 0d1e9afc9ff8a2adb94a155b72385155fa3b8011a5cca0bb3c28468c7131c1a5
F ext/jni/src/org/sqlite/jni/capi/RollbackHookCallback.java 105e324d09c207100485e7667ad172e64322c62426bb49b547e9b0dc9c33f5f0
F ext/jni/src/org/sqlite/jni/capi/SQLFunction.java fef556adbc3624292423083a648bdf97fa8a4f6b3b6577c9660dd7bd6a6d3c4a
F ext/jni/src/org/sqlite/jni/capi/SQLTester.java 09bee15aa0eedac68d767ae21d9a6a62a31ade59182a3ccbf036d6463d9e30b1
F ext/jni/src/org/sqlite/jni/capi/ScalarFunction.java 93b9700fca4c68075ccab12fe0fbbc76c91cafc9f368e835b9bd7cd7732c8615
F ext/jni/src/org/sqlite/jni/capi/TableColumnMetadata.java addf120e0e76e5be1ff2260daa7ce305ff9b5fafd64153a7a28e9d8f000a815f
F ext/jni/src/org/sqlite/jni/capi/Tester1.java e5fa17301b7266c1cbe4bcce67788e08e45871c7c72c153d515abb37e501de0a
F ext/jni/src/org/sqlite/jni/capi/Tester1.java ca195521b6bda3e0cd00e76bb71ec8060d1fab76a2f13b1af9feea40789f44bb
F ext/jni/src/org/sqlite/jni/capi/TraceV2Callback.java 0a25e117a0daae3394a77f24713e36d7b44c67d6e6d30e9e1d56a63442eef723
F ext/jni/src/org/sqlite/jni/capi/UpdateHookCallback.java c8bdf7848e6599115d601bcc9427ff902cb33129b9be32870ac6808e04b6ae56
F ext/jni/src/org/sqlite/jni/capi/ValueHolder.java 2ce069f3e007fdbbe1f4e507a5a407fc9679da31a0aa40985e6317ed4d5ec7b5
F ext/jni/src/org/sqlite/jni/capi/UpdateHookCallback.java 2766b8526bbffc4f1045f70e79f1bc1b1efe1c3e95ca06cdb8a7391032dda3b4
F ext/jni/src/org/sqlite/jni/capi/ValueHolder.java 9f9e151f1da017b706c0ee5f40f4c86b54e773d6ae4339723e0cc85a456251ab
F ext/jni/src/org/sqlite/jni/capi/WindowFunction.java caf4396f91b2567904cf94bc538a069fd62260d975bd037d15a02a890ed1ef9e
F ext/jni/src/org/sqlite/jni/capi/XDestroyCallback.java f3abb8dd7381f53ebba909437090caf68200f06717b8a7d6aa96fa3e8133117d
F ext/jni/src/org/sqlite/jni/capi/package-info.java 08ff986a65d2be9162442c82d28a65ce431d826f188520717c2ecb1484d0a50e
F ext/jni/src/org/sqlite/jni/capi/sqlite3.java c6a5c555d163d76663534f2b2cce7cab15325b9852d0f58c6688a85e73ae52f0
F ext/jni/src/org/sqlite/jni/capi/sqlite3.java 4010bbebc5bf44e2044e610786088cdee7dc155da2b333c0551492ff1cedf33b
F ext/jni/src/org/sqlite/jni/capi/sqlite3_backup.java 6742b431cd4d77e8000c1f92ec66265a58414c86bf3b0b5fbcb1164e08477227
F ext/jni/src/org/sqlite/jni/capi/sqlite3_blob.java 59e26ca5254cd4771f467237bcfe2d8deed30a77152fabcd4574fd406c301d63
F ext/jni/src/org/sqlite/jni/capi/sqlite3_blob.java f204ab6ab1263e119fe43730141a00662d80972129a5351dfb11aae5d282df36
F ext/jni/src/org/sqlite/jni/capi/sqlite3_context.java f0ef982009c335c4393ffcb68051809ca1711e4f47bcb8d1d46952f22c01bc22
F ext/jni/src/org/sqlite/jni/capi/sqlite3_stmt.java 293b5fa7d5b5724c87de544654aca1103d76f3092bc2c8f4360102a65ba25dff
F ext/jni/src/org/sqlite/jni/capi/sqlite3_stmt.java ff579621e9bd5ffbc6b2ef9f996c12db4df6e0c8cc5697c91273e5fca279fcf8
F ext/jni/src/org/sqlite/jni/capi/sqlite3_value.java e1d62a257c13504b46d39d5c21c49cf157ad73fda00cc5f34c931aa008c37049
F ext/jni/src/org/sqlite/jni/fts5/Fts5.java e94681023785f1eff5399f0ddc82f46b035977d350f14838db659236ebdf6b41
F ext/jni/src/org/sqlite/jni/fts5/Fts5Context.java 338637e6e5a2cc385d962b220f3c1f475cc371d12ae43d18ef27327b6e6225f7
@@ -297,14 +294,13 @@ F ext/jni/src/org/sqlite/jni/fts5/fts5_api.java a8e88c3783d21cec51b0748568a96653
F ext/jni/src/org/sqlite/jni/fts5/fts5_extension_function.java 9e2b954d210d572552b28aca523b272fae14bd41e318921b22f65b728d5bf978
F ext/jni/src/org/sqlite/jni/fts5/fts5_tokenizer.java 92bdaa3893bd684533004d64ade23d329843f809cd0d0f4f1a2856da6e6b4d90
F ext/jni/src/org/sqlite/jni/test-script-interpreter.md f9f25126127045d051e918fe59004a1485311c50a13edbf18c79a6ff9160030e
F ext/jni/src/org/sqlite/jni/wrapper1/AggregateFunction.java d5c108b02afd3c63c9e5e53f71f85273c1bfdc461ae526e0a0bb2b25e4df6483
F ext/jni/src/org/sqlite/jni/wrapper1/AggregateFunction.java 5ad99bd74c85f56bbef324d9ec29b4048f4620547c9a80093d8586c3557f9f9a
F ext/jni/src/org/sqlite/jni/wrapper1/ScalarFunction.java 43c43adfb7866098aadaaca1620028a6ec82d5193149970019b1cce9eb59fb03
F ext/jni/src/org/sqlite/jni/wrapper1/SqlFunction.java 27b141f5914c7cb0e40e90a301d5e05b77f3bd42236834a68031b7086381fafd
F ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java ada39f18e4e3e9d4868dadbc3f7bfe1c6c7fde74fb1fb2954c3f0f70120b805c
F ext/jni/src/org/sqlite/jni/wrapper1/SqliteException.java 982538ddb4c0719ef87dfa664cd137b09890b546029a7477810bd64d4c47ee35
F ext/jni/src/org/sqlite/jni/wrapper1/Tester2.java ce45f2ec85facbb73690096547ed166e7be82299e3d92eaa206f82b60a6ec969
F ext/jni/src/org/sqlite/jni/wrapper1/ValueHolder.java a84e90c43724a69c2ecebd601bc8e5139f869b7d08cb705c77ef757dacdd0593
F ext/jni/src/org/sqlite/jni/wrapper1/WindowFunction.java c7d1452f9ff26175b3c19bbf273116cc2846610af68e01756d755f037fe7319f
F ext/jni/src/org/sqlite/jni/wrapper1/SqlFunction.java 004394eeb944baa56e36cd7ae69ba6d4a52b52db3c49439db16e98270b861421
F ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java a9ddc6a9e8c113168cc67592ae24c0e56d30dd06226eeab012f2761a0889d7bb
F ext/jni/src/org/sqlite/jni/wrapper1/SqliteException.java 1386f7b753134fc12253ce2fbbc448ba8c970567fac01a3356cb672e14408d73
F ext/jni/src/org/sqlite/jni/wrapper1/Tester2.java c24b510ebe801c30533cc62efdf69a4a5e2da9ec4b49f8d403f2060693f060a0
F ext/jni/src/org/sqlite/jni/wrapper1/ValueHolder.java 7b89a7391f771692c5b83b0a5b86266abe8d59f1c77d7a0eccc9b79f259d79af
F ext/jni/src/tests/000-000-sanity.test c3427a0e0ac84d7cbe4c95fdc1cd4b61f9ddcf43443408f3000139478c4dc745
F ext/jni/src/tests/000-001-ignored.test e17e874c6ab3c437f1293d88093cf06286083b65bf162317f91bbfd92f961b70
F ext/jni/src/tests/900-001-fts.test bf0ce17a8d082773450e91f2388f5bbb2dfa316d0b676c313c637a91198090f0
@@ -388,7 +384,7 @@ F ext/misc/pcachetrace.c f4227ce03fb16aa8d6f321b72dd051097419d7a028a9853af048bee
F ext/misc/percentile.c b9086e223d583bdaf8cb73c98a6539d501a2fc4282654adbfea576453d82e691
F ext/misc/prefixes.c 82645f79229877afab08c8b08ca1e7fa31921280906b90a61c294e4f540cd2a6
F ext/misc/qpvtab.c fc189e127f68f791af90a487f4460ec91539a716daf45a0c357e963fd47cc06c
F ext/misc/randomjson.c 7dd13664155319d47b9facc0d8dbf45e13062966a47168e54e3f26d48240d7ea
F ext/misc/randomjson.c 1351346c2b698f569c2b91825a235e2ec3576c797ff97af29ecfc276b1d7ab55
F ext/misc/regexp.c 4bdd0045912f81c84908bd535ec5ad3b1c8540b4287c70ab84070963624047db
F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c
F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c
@@ -488,7 +484,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 0dd4775e896cee6067979d67aff7c998e75c2c9d9cd8d62a1a790c09cde7adca
F ext/rtree/rtree.c 2e1452a9338fe4db057fa677277bed86b65c667ed48b9b59144adae99f85a7cb
F ext/rtree/rtree.c 7026ddd4606aa0e888cc23a29ff10625b6b75fc55f90de4b2c8439da0de6817a
F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412
F ext/rtree/rtree1.test 2b5b8c719c6a4abe377f57766f428a49af36a93061cb146cccfdc3b30000c0a4
F ext/rtree/rtree2.test 9d9deddbb16fd0c30c36e6b4fdc3ee3132d765567f0f9432ee71e1303d32603d
@@ -508,6 +504,7 @@ F ext/rtree/rtreeF.test 81ffa7ef51c4e4618d497a57328c265bf576990c7070633b623b23cd
F ext/rtree/rtreeG.test 1b9ca6e3effb48f4161edaa463ddeaa8fca4b2526d084f9cbf5dbe4e0184939c
F ext/rtree/rtreeH.test 0885151ee8429242625600ae47142cca935332c70a06737f35af53a7bd7aaf90
F ext/rtree/rtreeI.test 608e77f7fde9be5a12eae316baef640fffaafcfa90a3d67443e78123e19c4ca4
F ext/rtree/rtreeJ.test 9b8c421c03d32be45685e4b65ed6191ceecf17f2d0e0e0dc2a37e070d1874ab3
F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195
F ext/rtree/rtree_util.tcl 202ca70df1f0645ef9d5a2170e62d378a28098d9407f0569e85c9c1cf1bd020a
F ext/rtree/rtreecheck.test 934546ad9b563e090ee0c5cbdc69ad014189ad76e5df7320526797a9a345661f
@@ -576,7 +573,7 @@ F ext/wasm/SQLTester/SQLTester.mjs ec2f6ba63a0f2f0562941a0fb8e46b7dc55589711513f
F ext/wasm/SQLTester/SQLTester.run.mjs c72b7fe2072d05992f7a3d8c6a1d34e95712513ceabe40849784e24e41c84638
F ext/wasm/SQLTester/index.html 3f8a016df0776be76605abf20e815ecaafbe055abac0e1fe5ea080e7846b760d
F ext/wasm/SQLTester/touint8array.c 2d5ece04ec1393a6a60c4bf96385bda5e1a10ad49f3038b96460fc5e5aa7e536
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api f442460ed9a109e637dd3ea1caa4489553ad9414e8988118b208bb7a4bbece6b
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api d6a5078f48a5301ed17b9a30331075d9b2506e1360c1f0dee0c7816c10acd9ab
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
F ext/wasm/api/README.md 5eb44fa02e9c693a1884a3692428647894b0380b24bca120866b7a24c8786134
@@ -586,17 +583,17 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08
F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62
F ext/wasm/api/pre-js.c-pp.js ad906703f7429590f2fbf5e6498513bf727a1a4f0ebfa057afb08161d7511219
F ext/wasm/api/sqlite3-api-cleanup.js d235ad237df6954145404305040991c72ef8b1881715d2a650dda7b3c2576d0e
F ext/wasm/api/sqlite3-api-glue.js 119b91c8a7ce6648679eb66fcdd1ed07ef7fd892eb501d658fbfefcc962012d9
F ext/wasm/api/sqlite3-api-glue.js 26aedfb27915f4f316f6eac84078443e4f0d2dfe5f012310014923ed4b77b2b6
F ext/wasm/api/sqlite3-api-oo1.js 9678dc4d9a5d39632b6ffe6ea94a023119260815bf32f265bf5f6c36c9516db8
F ext/wasm/api/sqlite3-api-prologue.js 9aeba7b45cf41b3a26d34d7fb2525633cd1adfc544888c1ea8dbb077496f4ce9
F ext/wasm/api/sqlite3-api-worker1.js 88770ac01fc756f89a3e060eec17111d6c1688e89ebfd34cb9d9e54d25affbb9
F ext/wasm/api/sqlite3-api-worker1.js f941382f21006b4a817754184e2661b0a63ce650201f3419cd60f4758b6fd60e
F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
F ext/wasm/api/sqlite3-opfs-async-proxy.js 8cf8a897726f14071fae6be6648125162b256dfb4f96555b865dbb7a6b65e379
F ext/wasm/api/sqlite3-v-helper.js 7daa0eab0a513a25b05e9abae7b5beaaa39209b3ed12f86aeae9ef8d2719ed25
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 595953994aa3ae2287c889c4da39ab3d6f17b6461ecf4bec334b7a3faafddb02
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 46c4afa6c50d7369252c104f274ad977a97e91ccfafc38b400fe36e90bdda88e
F ext/wasm/api/sqlite3-wasm.c d0e09eb5ed3743c00294e30019e591c3aa150572ae7ffe8a8994568a7377589f
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js 569d4e859968e65f55dec5fac0b879828a23c8b179162cc7812fec19f844dd21
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js a94e3f0ca25a777bb73779368f97be0e103e02d067ad3ee3e9c4cc5bcefbd01c
F ext/wasm/api/sqlite3-worker1.c-pp.js a541112aa51e16705f13a99bb943c64efe178aa28c86704a955f8fd9afe4ba37
F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8
F ext/wasm/batch-runner.js 0dad6a02ad796f1003d3b7048947d275c4d6277f63767b8e685c27df8fdac93e
@@ -637,10 +634,10 @@ F ext/wasm/split-speedtest1-script.sh a3e271938d4d14ee49105eb05567c6a69ba4c1f129
F ext/wasm/sql/000-mandelbrot.sql 775337a4b80938ac8146aedf88808282f04d02d983d82675bd63d9c2d97a15f0
F ext/wasm/sql/001-sudoku.sql 35b7cb7239ba5d5f193bc05ec379bcf66891bce6f2a5b3879f2f78d0917299b5
F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555e685bce3da8c3f
F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c
F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b
F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c
F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2
F ext/wasm/tester1.c-pp.js a92dc256738dbd1b50f142d1fd0c835294ba09b7bb6526650360e942f88cb63f
F ext/wasm/tester1.c-pp.js fb20d9e1c308ea34a29d8afdda1a6c5edc406241b5560fa23c19c14747ee41bc
F ext/wasm/tests/opfs/concurrency/index.html 0802373d57034d51835ff6041cda438c7a982deea6079efd98098d3e42fbcbc1
F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
@@ -667,31 +664,31 @@ F src/auth.c 19b7ccacae3dfba23fc6f1d0af68134fa216e9040e53b0681b4715445ea030b4
F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523
F src/bitvec.c 9eac5f42c11914d5ef00a75605bb205e934f435c579687f985f1f8b0995c8645
F src/btmutex.c 79a43670447eacc651519a429f6ece9fd638563cf95b469d6891185ddae2b522
F src/btree.c f3b09c5414de3a11db73e11e1d66f4c5e53c9e89876ff3b531a887ab656ca303 x
F src/btree.c 477f724b70d06fbe7481ded1b024719dc9132c980f695a86fe127cd96bb8ea9c
F src/btree.h 03e3356f5208bcab8eed4e094240fdac4a7f9f5ddf5e91045ce589f67d47c240
F src/btreeInt.h 3e2589726c4f105e653461814f65857465da68be1fac688de340c43b873f4062
F src/build.c 189e4517d67f09f0a3e0d8e1faa6e2ef0c2e95f6ac82e33c912cb7efa2a359cc
F src/btreeInt.h ef12a72b708677e48d6bc8dcd66fed25434740568b89e2cfa368093cfc5b9d15
F src/build.c c28f319906e7a6c99a09dbc794a06b07b699203a86bfe5eb01410534e344758d
F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 23331529e654be40ca97d171cbbffe9b3d4c71cc53b78fe5501230675952da8b
F src/date.c 3b8d02977d160e128469de38493b4085f7c5cf4073193459909a6af3cf6d7c91
F src/date.c eebc54a00e888d3c56147779e9f361b77d62fd69ff2008c5373946aa1ba1d574
F src/dbpage.c 80e46e1df623ec40486da7a5086cb723b0275a6e2a7b01d9f9b5da0f04ba2782
F src/dbstat.c 3b677254d512fcafd4d0b341bf267b38b235ccfddbef24f9154e19360fa22e43
F src/delete.c cb766727c78e715f9fb7ec8a7d03658ed2a3016343ca687acfcec9083cdca500
F src/expr.c e9a491c7f156e5b25641c28af11b735a424e108a21b9f83b6f3e51c99a8141d9
F src/expr.c 832f32dd73e6844199d1b41dbbb0fa08679ef07608da10910b998ab902fcb80e
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c a47610f0a5c6cb0ad79f8fcef039c01833dec0c751bb695f28dc0ec6a4c3ba00
F src/func.c 472f6dcfa39cf54f89a6aec76c79c225fb880a6c14469c15d361331662b9bf43
F src/global.c 29f56a330ed9d1b5cd9b79ac0ca36f97ac3afc730ff8bfa987b0db9e559d684d
F src/func.c f8acebf8d6c4f38af99f766754650b26bca1eee058739834899896ce724e43b7
F src/global.c 34aee8aa4138f94997a49352bb4d8b2449d18160743279bfe97a67ecf166d23c
F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220
F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c 3f0a94082d978bbdd33c38fefea15346c6c6bffb70bc645a71dc0f1f87dd3276
F src/json.c 92cc05dcf87cdace6fbf2a76e0cb2b030f04ddb1819e024af4ce8885261b4cef
F src/insert.c eb33ea46dcab93e90f112fced343aaf41f59cbd2e951d5066f1f9302be1c2f34
F src/json.c b2045aafc52f0475dc5d723d11cc0aaa9e1d233a28031b08c8174a3e407ed50c
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
F src/main.c 1b89f3de98d1b59fec5bac1d66d6ece21f703821b8eaa0d53d9604c35309f6f9
F src/main.c 63a0a5763a3662581652698c4bc0376fab407bc485f802964abd18a6cf397aca
F src/malloc.c f016922435dc7d1f1f5083a03338a3e91f8c67ce2c5bdcfa4cdef62e612f5fcc
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
@@ -712,28 +709,28 @@ F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63
F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06
F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a
F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107
F src/os_unix.c 97bdcd43315da7aaec9fea2da1ff7c9de458f93dd363e073f2742403a7f2e011
F src/os_win.c 4a50a154aeebc66a1f8fb79c1ff6dd5fe3d005556533361e0d460d41cb6a45a8
F src/os_unix.c 085610579629d469f7325cced82856ade34ba221c31a0cf034aedd009544ad41
F src/os_win.c 6ff43bac175bd9ed79e7c0f96840b139f2f51d01689a638fd05128becf94908a
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 987ab3a2cd9065d62e9955474470ff733445e2357432a67e3d0f5a8f9313e334
F src/pager.c d19325084b4ada4a9139175c6c09d5534bb63a8017c85fe542dee08602794637
F src/pager.h f4d33fec8052603758792045493423b8871a996da2d0973927b7d36cd6070473
F src/parse.y 020d80386eb216ec9520549106353c517d2bbc89be28752ffdca649a9eaf56ec
F src/pcache.c 040b165f30622a21b7a9a77c6f2e4877a32fb7f22d4c7f0d2a6fa6833a156a75
F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
F src/pcache1.c 602acb23c471bb8d557a6f0083cc2be641d6cafcafa19e481eba7ef4c9ca0f00
F src/pragma.c b5b4cff830575e6188cd56a295a57448d2b9dbc53f0dae58e22b97354cda3781
F src/pragma.c ebcaeb9e56ed4f9367274e10770864f059fc12b7d8552dec98e24ef39be87cbe
F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
F src/prepare.c 371f6115cb69286ebc12c6f2d7511279c2e47d9f54f475d46a554d687a3b312c
F src/prepare.c bde74add20fc0e8ce0c4e937a1f70a36d17413afe4f71d3e103f5cb74b17c8d9
F src/printf.c 9da63b9ae1c14789bcae12840f5d800fd9302500cd2d62733fac77f0041b4750
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
F src/resolve.c d017bad7ba8e778617701a0e986fdeb393d67d6afa84fb28ef4e8b8ad2acf916
F src/resolve.c b93de34e541ec2a8f1abd55ab7e914230aa20526e7c6e169ed05bc964ce5edd9
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c 85857bedd2913d888aa571755b48c54cd2e6e7fcb0087e19b226ee0368cfda1e
F src/shell.c.in 7bb83293775e1a5586d65212997442bc7acc70a2f1b781745da64ec3c2e4ea97
F src/sqlite.h.in d93a4821d2f792467a60f7dc81268d1bb8634f40c31694ef254cab4f9921f96a
F src/select.c 8460ae29edd8f515ed9f1debc12e972825453dbb904ced7253e8ccfd1e4ed164
F src/shell.c.in 2e15f7ab2273843f3d3cdc22f3d6a1d080dd57099450b0a3bd9256a74ce822d9
F src/sqlite.h.in 1ecba681f97f5e0659433da9555cacc2c124d26c4d09db1edcc64ee15d614839
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
F src/sqliteInt.h 6b82eb99a9d2887e873fb29e56befb7c50cf4624df615d23a28f071dc8abf5f6
F src/sqliteInt.h 142d16cb29c0c6ee067f96a25c8d528673300bcb2b6bdb066b587306067847af
F src/sqliteLimit.h 33b1c9baba578d34efe7dfdb43193b366111cdf41476b1e82699e14c11ee1fb6
F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@@ -752,7 +749,7 @@ F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0
F src/test_bestindex.c f6af1e41cb7901edafb065a8198e4a0192dd42432b642d038965be5e628dec12
F src/test_blob.c ae4a0620b478548afb67963095a7417cd06a4ec0a56adb453542203bfdcb31ce
F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274
F src/test_config.c f0cc1f517deaa96dd384822ae2bb91534fa56aa458528b439830d709941d3932
F src/test_config.c 5fa77ee6064ba546e144c4fea870c5ede2c54314616f81485c6a9c4192100c75
F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f
F src/test_demovfs.c 38a459d1c78fd9afa770445b224c485e079018d6ac07332ff9bd07b54d2b8ce9
F src/test_devsym.c 649434ed34d0b03fbd5a6b42df80f0f9a7e53f94dd1710aad5dd8831e91c4e86
@@ -791,18 +788,18 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c 23d9f4539880b40226254ad9072f4ecf12eb1902e62aea47aac29928afafcfd5
F src/treeview.c c6fc972683fd00f975d8b32a81c1f25d2fb7d4035366bf45c9f5622d3ccd70ee
F src/treeview.c 62fafcd31eea60b718f8daf448116b7b19f90134ebc6c20777ddbb07f56a3d28
F src/trigger.c 0905b96b04bb6658509f711a8207287f1315cdbc3df1a1b13ba6483c8e341c81
F src/update.c 6904814dd62a7a93bbb86d9f1419c7f134a9119582645854ab02b36b676d9f92
F src/upsert.c fa125a8d3410ce9a97b02cb50f7ae68a2476c405c76aa692d3acf6b8586e9242
F src/update.c 732404a04d1737ef14bb6ec6b84f74edf28b3c102a92ae46b4855438a710efe7
F src/upsert.c 2e60567a0e9e8520c18671b30712a88dc73534474304af94f32bb5f3ef65ac65
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
F src/util.c b22cc9f203a8c0b9ee5338a67f8860347d14845864c10248bebe84518a781677
F src/util.c 1e2754e628086dcb93f3f70be7937f0367baa3ad616c4f16f45d61e8ed12c01f
F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104
F src/vdbe.c f73bead140670fac1aa4227188827ada52387a5fe0ccff0dd5af2a906754d904
F src/vdbe.c b0617c320ae426b0561954dcdb63427fce72d08a4723eb411e3e2b5a7515aa4f
F src/vdbe.h 88e19a982df9027ec1c177c793d1a5d34dc23d8f06e3b2d997f43688b05ee0eb
F src/vdbeInt.h 949669dfd8a41550d27dcb905b494f2ccde9a2e6c1b0b04daa1227e2e74c2b2c
F src/vdbeapi.c 8f57d60c89da0b60e6d4e272358c511f6bae4e24330bdb11f8b42f986d1bf21b
F src/vdbeaux.c c5a471b34e9c4cfc0295a3e10734fd197670ffaebcb742f284c8e17e8026ceea
F src/vdbeapi.c dd812ddd2f7806519e9d492c820456f86628bb6014b559034506e7f9d7f683c5
F src/vdbeaux.c ba59d1fb97097901a50f8f5a2fcbdc8c2f7ad64acdde6a2ee364f07561ba7335
F src/vdbeblob.c 13f9287b55b6356b4b1845410382d6bede203ceb29ef69388a4a3d007ffacbe5
F src/vdbemem.c 0012d5f01cc866833847c2f3ae4c318ac53a1cb3d28acad9c35e688039464cf0
F src/vdbesort.c 237840ca1947511fa59bd4e18b9eeae93f2af2468c34d2427b059f896230a547
@@ -810,10 +807,10 @@ F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf8
F src/vdbevtab.c 2143db7db0ceed69b21422581f434baffc507a08d831565193a7a02882a1b6a7
F src/vtab.c 154725ebecd3bc02f7fbd7ad3974334f73fff76e02a964e828e48a7c5fb7efff
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c e5247a3406531b705b44630e9ccf9ca0e5c74955ef19c06fbb146d765c500c20
F src/wal.c 01e051a1e713d9eabdb25df38602837cec8f4c2cae448ce2cf6accc87af903e9
F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2
F src/where.c 1fdc69ce1333e9bd6d7d3df9fa5af1373a3f5bfdd52108d1dbc0ca85a55f777e
F src/where.c b10d2f7e924a7a666213805df0bc1aac44d5e981cf5a720851b3d66d71243a7d
F src/whereInt.h 4b38c5889514e3aead3f27d0ee9a26e47c3f150efc59e2a8b4e3bc8835e4d7a1
F src/wherecode.c 5d77db30a2a3dd532492ae882de114edba2fae672622056b1c7fd61f5917a8f1
F src/whereexpr.c dc5096eca5ed503999be3bdee8a90c51361289a678d396a220912e9cb73b3c00
@@ -823,7 +820,7 @@ F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867d
F test/affinity3.test f094773025eddf31135c7ad4cde722b7696f8eb07b97511f98585addf2a510a9
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggfault.test 777f269d0da5b0c2524c7ff6d99ae9a93db4f1b1839a914dd2a12e3035c29829
F test/aggnested.test ce85a6af7d59c3109e35c5f03b2cd11da1a9b1417371e2f942102d0f0d77fd62
F test/aggnested.test 2e738bfe2980df301a782f6e7bbf9459266f64f7e72f58f3b5c843bf897c568c
F test/aggorderby.test e6b98dbbf3ababa96892435d387de2dcf602ef02c2b848d2d817473066f154ba
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
F test/all.test 2ecb8bbd52416642e41c9081182a8df05d42c75637afd4488aace78cc4b69e13
@@ -1020,7 +1017,7 @@ F test/ctime.test 340f362f41f92972bbd71f44e10569a5cc694062b692231bd08aa6fe6c1c47
F test/cursorhint.test 05cf0febe5c5f8a31f199401fd1c9322249e753950d55f26f9d5aca61408a270
F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee9ae9c42f
F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8
F test/date.test ff2341a1ef71b9a27979494d299222f9a293aa22cb9ff6e9c38d88a895317ebf
F test/date.test c0d17cdfd89395bc78087b131e3538d96f864b5029c335318011accc7c0d0934
F test/date2.test 7e12ec14aaf4d5e6294b4ba140445b0eca06ea50062a9c3a69c4ee13d0b6f8b1
F test/date3.test a1b77abf05c6772fe5ca2337cac1398892f2a41e62bce7e6be0f4a08a0e64ae5
F test/date4.test 8aeb3de5b5e9fda968baa9357e4c0fae573724b7904943410195a19e96e31b6a
@@ -1034,7 +1031,7 @@ F test/dbpagefault.test 35f06cfb2ef100a9b19d25754e8141b9cba9b7daabd4c60fa5af93fc
F test/dbstatus.test 4a4221a883025ffd39696b3d1b3910b928fb097d77e671351acb35f3aed42759
F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef
F test/decimal.test ef731887b43ee32ef86e1c8fddb61a40789f988332c029c601dcf2c319277e9e
F test/default.test 9687cfb16717e4b8238c191697c98be88c0b16e568dd5368cd9284154097ef50
F test/default.test 830fad7180cdf0e6a06e93acc0403bf73762314a639363314db5674c631b6127
F test/delete.test 2686e1c98d552ef37d79ad55b17b93fe96fad9737786917ce3839767f734c48f
F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab
@@ -1205,7 +1202,7 @@ F test/fts4umlaut.test fcaca4471de7e78c9d1f7e8976e3e8704d7d8ad979d57a739d00f3f75
F test/fts4unicode.test 82a9c16b68ba2f358a856226bb2ee02f81583797bc4744061c54401bf1a0f4c9
F test/fts4upfrom.test f25835162c989dffd5e2ef91ec24c4848cc9973093e2d492d1c7b32afac1b49d
F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
F test/func.test 3a29323b640c0552f6e9f1577407ced3a68e7d8c0bc04b61dd6040fa593a3a02
F test/func.test 49a39f86fcf374abbfd4f8c428b7420bc3c89095722b511a5503ccc31516d7fe
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
F test/func3.test 600a632c305a88f3946d38f9a51efe145c989b2e13bd2b2a488db47fe76bab6a
F test/func4.test 2285fb5792d593fef442358763f0fd9de806eda47dbc7a5934df57ffdc484c31
@@ -1233,7 +1230,7 @@ F test/fuzzdata8.db 4a53b6d077c6a5c23b609d8d3ac66996fa55ba3f8d02f9b6efdd0214a767
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc
F test/fuzzinvariants.c b34530e8431f2cf3591eff588fc7684d6fdef466916fb46141c8c5374a3d8099
F test/fuzzinvariants.c 4355043e98cd8555c62462fcbba91c17c6492b0b017bbbe68656d5f2208f6444
F test/gcfault.test 4ea410ac161e685f17b19e1f606f58514a2850e806c65b846d05f60d436c5b0d
F test/gencol1.test e169bdfa11c7ed5e9f322a98a7db3afe9e66235750b68c923efee8e1876b46ec
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
@@ -1302,7 +1299,7 @@ F test/join.test f7abfef3faeaf2800308872e33a57e5b6e4a2b44fb8c6b90c6068412e71a6cf
F test/join2.test 8561fe82ce434ac96de91544072e578dc2cadddf2d9bc9cd802f866a9b92502e
F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
F test/join5.test 7cc3f3595bb41e60f3f96d5cb6dd8cfcbc31212f0136bba6fc081c082994a94a
F test/join5.test 380d12a9350f99f0cc681a4f1fea999886f18b3fe0d71a9b3065bcaead1e007f
F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c
F test/join7.test 2268dcbb54b724391dda3748ea95c60d960607ffeed67885675998e7117697f6
F test/join8.test d384d63985e3991c404afccadaf3efd1cdf9cd72680167f80e3cb80b95c18c68
@@ -1313,7 +1310,7 @@ F test/joinC.test 1f1a602c2127f55f136e2cbd3bf2d26546614bf8cffe5902ec1ac9c07f87f2
F test/joinD.test 2ce62e7353a0702ca5e70008faf319c1d4686aa19fba34275c6d1da0e960be28
F test/joinE.test d5d182f3812771e2c0d97c9dcf5dbe4c41c8e21c82560e59358731c4a3981d6b
F test/joinF.test 53dd66158806823ea680dd7543b5406af151b5aafa5cd06a7f3231cd94938127
F test/joinH.test f69e5b53b7d887914e854b6a131efbed4ea9f5ca52bdab81788bfc3e79299f43
F test/joinH.test d5054173442fdf98260eeb6bb9751daa733b0ae6842fe50dcbd5469945b86985
F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497
F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4
F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e
@@ -1322,17 +1319,15 @@ F test/jrnlmode2.test 8759a1d4657c064637f8b079592651530db738419e1d649c6df7048cd7
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
F test/json/README.md 63e3e589e1df8fd3cc1588ba1faaff659214003f8b77a15af5c6452b35e30ee2
F test/json/json-generator.tcl dc0dd0f393800c98658fc4c47eaa6af29d4e17527380cd28656fb261bddc8a3f
F test/json/json-q1-b.txt 606818a5fba6d9e418c9f4ea7d8418af026775042dad81439b72447a147a462c
F test/json/json-q1.txt 65f9d1cdcc4cffa9823fb73ed936aae5658700cd001fde448f68bfb91c807307
F test/json/json-speed-check.sh b060a9a6c696c0a807d8929400fa11bd7113edc58b0d66b9795f424f8d0db326 x
F test/json101.test 70587d7d35ef9e2126364ba70f0c951f70827cfbd28649d779ff3df7e8f87547
F test/json102.test 557a46e16df1aa9bdbc4076a71a45814ea0e7503d6621d87d42a8c04cbc2b0ef
F test/json/json-speed-check.sh 8b7babf530faa58bd59d6d362cec8e9036a68c5457ff46f3b1f1511d21af6737 x
F test/json101.test bc05d2476fd6f7ead31ec05b43d1b24b2b193ae112fd8f0d2ed56d9a904f9fa5
F test/json102.test 4c69694773a470f1fda34e5f4ba24920b35184fb66050b450fc2ef9ab5ad310b
F test/json103.test 53df87f83a4e5fa0c0a56eb29ff6c94055c6eb919f33316d62161a8880112dbe
F test/json104.test 1b844a70cddcfa2e4cd81a5db0657b2e61e7f00868310f24f56a9ba0114348c1
F test/json105.test e64a8d73677fbae67886642cd5076e2ef3efe89f8483b87595cf9c030216c9bd
F test/json501.test ab168a12eb6eb14d479f8c1cdae3ac062fd5a4679f17f976e96f1af518408330
F test/json105.test 11670a4387f4308ae0318cadcbd6a918ea7edcd19fbafde020720a073952675d
F test/json501.test c419deb835b70c1a2c8532936927bcc1146730328edd2052276715bfd209724d
F test/json502.test 98c38e3c4573841028a1381dfb81d4c3f9b105d39668167da10d055e503f6d0b
F test/jsonb01.test cace70765b36a36aec9a85a41ea65667d3bbf647d4400ddc3ac76f8fe7d94f90
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
F test/kvtest.c 6e0228409ea7ca0497dad503fbd109badb5e59545d131014b6aaac68b56f484a
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
@@ -1396,7 +1391,7 @@ F test/minmax2.test cf9311babb6f0518d04e42fd6a42c619531c4309a9dd790a2c4e9b3bc595
F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354
F test/minmax4.test 272ca395257f05937dc96441c9dde4bc9fbf116a8d4fa02baeb0d13d50e36c87
F test/misc1.test 8d138a4926ab90617c1aa29ce26e7785ae2b83a4d3a195d543b7374e05589dd1
F test/misc2.test 71e746af479119386ac2ed7ab7d81d99970e75b49ffd3e8efffee100b4b5f350
F test/misc2.test a1a3573cc02662becd967766021d6f16c54684d56df5f227481c7ef0d9df0bd0
F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d
F test/misc4.test 10cd6addb2fa9093df4751a1b92b50440175dd5468a6ec84d0386e78f087db0e
F test/misc5.test c4aeaa0fa28faa08f2485309c38db4719e6cd1364215d5687a5b96d340a3fa58
@@ -1405,10 +1400,11 @@ F test/misc7.test d912f3d45c2989191b797504a220ca225d6be80b21acad22ba0d35f4a9ee45
F test/misc8.test 4db9f8be59834cea08c87e9658014080efa02678ef54a088f84fa5647e81fee0
F test/misuse.test 9e7f78402005e833af71dcab32d048003869eca5abcaccc985d4f8dc1d86bcc7
F test/mjournal.test 28a08d5cb5fb5b5702a46e19176e45e964e0800d1f894677169e79f34030e152
F test/mmap1.test 5c1f768828094b0dd94e55ae7f10489a1ded74772682be2c4c78679d0acaf7ef
F test/mmap1.test e154d0442c9b43646f86b8ddc38b656bb8bc79284209a9367076473cec5d0eef
F test/mmap2.test 9d6dd9ddb4ad2379f29cc78f38ce1e63ed418022
F test/mmap3.test b3c297e78e6a8520aafcc1a8f140535594c9086e
F test/mmap4.test 2e2b4e32555b58da15176e6fe750f17c9dcf7f93
F test/mmapcorrupt.test 0d89724591f22a376019f3df60d075b838dd2ba6dae6effb0be465c49cf86d4a
F test/mmapfault.test d4c9eff9cd8c2dc14bc43e71e042f175b0a26fe3
F test/mmapwarm.test 2272005969cd17a910077bd5082f70bc1fefad9a875afec7fc9af483898ecaf3
F test/multiplex.test d74c034e52805f6de8cc5432cef8c9eb774bb64ec29b83a22effc8ca4dac1f08
@@ -1469,7 +1465,7 @@ F test/pg_common.tcl 3b27542224db1e713ae387459b5d117c836a5f6e328846922993b6d2b76
F test/pragma.test 57a36226218c03cfb381019fe43234b2cefbd8a1f12825514f906a17ccf7991e
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
F test/pragma3.test 92a46bbea12322dd94a404f49edcfbfc913a2c98115f0d030a7459bb4712ef31
F test/pragma4.test ca5e4dfc46adfe490f75d73734f70349d95a199e6510973899e502eef2c8b1f8
F test/pragma4.test 0010fbd5a3ec84a8cd94ae859b5b5c9c6e608881c8397bba15a7dda059a25d6c
F test/pragma5.test 7b33fc43e2e41abf17f35fb73f71b49671a380ea92a6c94b6ce530a25f8d9102
F test/pragmafault.test 275edaf3161771d37de60e5c2b412627ac94cef11739236bec12ed1258b240f8
F test/prefixes.test b524a1c44bffec225b9aec98bd728480352aa8532ac4c15771fb85e8beef65d9
@@ -1493,9 +1489,10 @@ 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 80ef3941bf7ad136f4dc3d8960786f10a4f488797238171bdd757cc6eb4c3efa
F test/resetdb.test 54c06f18bc832ac6d6319e5ab23d5c8dd49fdbeec7c696d791682a8006bd5fc3
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
F test/returning1.test db532cde29d6aebbc48c6ddc3149b30476f8e69ca7a2c4b53986c7635e6fd8ec
F test/returning1.test 3ead782eddf51f573cdd43bcbb10d1b485ac095a19a76d16c43fd159ea9b7466
F test/returningfault.test ae4c4b5e8745813287a359d9ccdb9d5c883c2e68afb18fb0767937d5de5692a4
F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa
F test/rollback2.test 3f3a4e20401825017df7e7671e9f31b6de5fae5620c2b9b49917f52f8c160a8f
@@ -1503,7 +1500,7 @@ F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a
F test/round1.test 29c3c9039936ed024d672f003c4d35ee11c14c0acb75c5f7d6188ff16190cfd4
F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc
F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
F test/rowid.test e29025be95baf6b32f0d5edef59a7633028325896a98f1caa8019559ca910350
F test/rowid.test aaa2572271edf58f8f88ac4d39f69e57ee5ae7a858332cdce9106e7cff8b7963
F test/rowvalue.test baf4fa3ec1a8c1c920c3faa5fd25959cb454bbd99ac8960397c34549d9fc4abe
F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b
F test/rowvalue3.test 1347e25ca11c547c5a6ff0cc5626f95aa9740e9275bfaec096029f57cb2130ce
@@ -1592,7 +1589,7 @@ F test/snapshot2.test 8d6ff5dd9cc503f6e12d408a30409c3f9c653507b24408d9cd7195931c
F test/snapshot3.test 8744313270c55f6e18574283553d3c5c5fe4c5970585663613a0e75c151e599b
F test/snapshot4.test d4e9347ef2fcabc491fc893506c7bbaf334da3be111d6eb4f3a97cc623b78322
F test/snapshot_fault.test 129234ceb9b26a0e1000e8563a16e790f5c1412354e70749cbd78c3d5d07d60a
F test/snapshot_up.test 77dc7853bfb2b4fa249f76e1714cfa1e596826165d9ef22c06ac3a0b7b778d9a
F test/snapshot_up.test a0a29c4cf33475fcef07c3f8e64af795e24ab91b4cc68295863402a393cdd41c
F test/soak.test 18944cf21b94a7fe0df02016a6ee1e9632bc4e8d095a0cb49d95e15d5cca2d5c
F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087
F test/sort.test f86751134159abb5e5fd4381a0d7038c91013638cd1e3fa1d7850901f6df6196
@@ -1655,8 +1652,8 @@ F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d163
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
F test/tester.tcl 68454ef88508c196d19e8694daa27bff7107a91857799eaa12f417188ae53ede
F test/testrunner.tcl e18d71f2e797da808ba6d31335e504ed6b2791581b89287a72b697a2f31b1ea1
F test/testrunner_data.tcl e4d5017290a6d5c11785e36cc94c67d8bb950c8cdc2dbe4c1db2a3a583812560
F test/testrunner.tcl 14c8b8ece841b1dd17516a0dc9c7ad9b5f4d4db7987974d3fdf66ae56b2a71fa
F test/testrunner_data.tcl 7f73f93634d32dafc857ed491b840f371113d09fde6a8bfb9e47b938d47b8c85
F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899
F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
@@ -1821,7 +1818,7 @@ F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7
F test/tpch01.test 4479008f85f6f8f25f7ab2cb305d665752b4727fa28a8df3d8e0ad46520c62ff
F test/trace.test a659a9862957f4789e37a92b3bf6d2caf5c86b02cdeefc41e850ae53acf6992a
F test/trace2.test f5cb67ad3bc09e0c58e8cca78dfd0b5639259983
F test/trace3.test 4f418ed30d15d9d17dcf13a17f0bd99a92e3038e038798e35db7525f82f4c281
F test/trace3.test ae2004df24b585fed9046cc0bae4601762bc6fc4aa321d475f1350bba5047f31
F test/trans.test 45f6f9ab6f66a7b5744f1caac06b558f95da62501916906cf55586a896f9f439
F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76
F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94
@@ -1834,7 +1831,7 @@ F test/trigger5.test 619391a3e9fc194081d22cefd830d811e7badf83
F test/trigger6.test 0e411654f122552da6590f0b4e6f781048a4a9b9
F test/trigger7.test e7ce54bfda67a88d778aea42544e151c465547a7e617127b6914c2221a6d53c1
F test/trigger8.test 30cb0530bd7c4728055420e3f739aa00412eafa4
F test/trigger9.test fd49aff8b724ae1a6238989ecf84320d88c0e8f8d9142a891b93f826dfe37b59
F test/trigger9.test 1724b595661da3dd3c8d79f0ebae818132a39e65c241bad2049f66952b1dc29d
F test/triggerA.test 837be862d8721f903dba3f3ceff05b32e0bee5214cf6ea3da5fadf12d3650e9d
F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe
F test/triggerC.test 29f5a28d0fe39e6e2c01f6e1f53f08c0955170ae10a63ad023e33cb0a1682a51
@@ -1854,7 +1851,7 @@ F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff
F test/types2.test 1aeb81976841a91eef292723649b5c4fe3bc3cac
F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a
F test/unhex.test b7f1b806207cb77fa31c3e434fe92fba524464e3e9356809bfcc28f15af1a8b7
F test/unionall.test eb9afa030897af75fd2f0dd28354ef63c8a5897b6c76aa1f15acae61a12eabcf
F test/unionall.test 04d30726c5056f84f92b3a12bf8d8a1dbbe807d1ddc8af95def09e6ef2dd91e3
F test/unionall2.test 71e8fa08d5699d50dc9f9dc0c9799c2e7a6bb7931a330d369307a4df7f157fa1
F test/unionallfault.test 652bfbb630e6c43135965dc1e8f0a9a791da83aec885d626a632fe1909c56f73
F test/unionvtab.test e1704ab1b4c1bb3ffc9da4681f8e85a0b909fd80b937984fc94b27415ac8e5a4
@@ -1875,7 +1872,7 @@ F test/upsert1.test a512e2f884d3a36159fce2e45108c236f78ae38e35bda55f4050db580ceb
F test/upsert2.test 720e94d09f7362a282bc69b3c6b83d51daeaaf0440eb4920a08b86518b8c7496
F test/upsert3.test 88d7d590a1948a9cb6eac1b54b0642f67a9f35a1fc0f19b200e97d5d39e3179c
F test/upsert4.test 25d2a1da92f149331ae0c51ca6e3eee78189577585eab92de149900d62994fa5
F test/upsert5.test fff0dcfce73c649204543088d8e5bde01172676063ec9b8f8fc7f195abc386fe
F test/upsert5.test 9953b180d02d1369cdbb6c73c900834e5fef8cb78e98e07511c8762ec21cc176
F test/upsertfault.test f21ca47740841fdb4d61acfa7b17646d773e67724fe8c185b71c018db8a94b35
F test/uri.test c1abaaaa28e9422d61e5f3f9cbc8ef993ec49fe802f581520731708561d49384
F test/uri2.test 9d3ba7a53ee167572d53a298ee4a5d38ec4a8fb7
@@ -1957,6 +1954,8 @@ F test/walshared.test 42e3808582504878af237ea02c42ca793e8a0efaa19df7df26ac573370
F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f
F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747
F test/walvfs.test e1a6ad0f3c78e98b55c3d5f0889cf366cc0d0a1cb2bccb44ac9ec67384adc4a1
F test/wapp.tcl b440cd8cf57953d3a49e7ee81e6a18f18efdaf113b69f7d8482b0710a64566ec
F test/wapptest.tcl 1bea58a6a8e68a73f542ee4fca28b771b84ed803bd0c9e385087070b3d747b3c x
F test/where.test 59abb854eee24f166b5f7ba9d17eb250abc59ce0a66c48912ffb10763648196d
F test/where2.test 03c21a11e7b90e2845fc3c8b4002fc44cc2797fa74c86ee47d70bd7ea4f29ed6
F test/where3.test 5b4ffc0ac2ea0fe92f02b1244b7531522fe4d7bccf6fa8741d54e82c10e67753
@@ -1988,7 +1987,7 @@ F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2
F test/win32lock.test e0924eb8daac02bf80e9da88930747bd44dd9b230b7759fed927b1655b467c9c
F test/win32longpath.test 4baffc3acb2e5188a5e3a895b2b543ed09e62f7c72d713c1feebf76222fe9976
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
F test/window1.test 5e8abe56a7d667eeddbba6de180086dcf69ed528d046447a25464f945ece101f
F test/window1.test ccfeaf116afc6a8f748a8122a4f1ee6b69e6bbc5acee61197d3c17167338b100
F test/window2.tcl 492c125fa550cda1dd3555768a2303b3effbeceee215293adf8871efc25f1476
F test/window2.test e466a88bd626d66edc3d352d7d7e1d5531e0079b549ba44efb029d1fbff9fd3c
F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03
@@ -2112,7 +2111,7 @@ F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaa
F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848
F tool/src-verify.c 41c586dee84d0b190ad13e0282ed83d4a65ec9fefde9adf4943efdf6558eea7f
F tool/srcck1.c 371de5363b70154012955544f86fdee8f6e5326f
F tool/srctree-check.tcl c15f860a3c97d5f7b4c14b60392d9466af29dd006c4ef18127f502641e2977a8
F tool/srctree-check.tcl 9f1098d439159692ece45cc9e701b35df4956269399fe0c770e41f235d1ce5e6
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
F tool/stripccomments.c 20b8aabc4694d0d4af5566e42da1f1a03aff057689370326e9269a9ddcffdc37
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
@@ -2145,8 +2144,9 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 04c0d5644372446c924a2e31a26edf51ddc563a1990d170b0ed4739e3e8b239b
R 4a2861d7ab7860f80e426ce44e32c50f
P d68fb8b5dbb8305e00d2dd14d8fe6b3d9f67e2459102ff160d956a6b75ddc18e
Q +c7896e88850669e18e89d44c4169d4f4a5d4b904bea6ccb2ac64f93b6d348a42
R 32bc816261ff7ca9b25d83710dd33ef1
U drh
Z 1fffc27f10fd5ca429d5618946ebb513
Z 723a8575c7cde0891641a014d7dbe6b4
# Remove this line to create a well-formed Fossil manifest.
+1 -1
View File
@@ -1 +1 @@
cc7a641ab5ae739d31c24f0ad0caeb15a481a63fa8f13720718ea922c25862ff
d38cfa6067ccd450c4fac183765c05ff247ecb49ccf172a68ef9d381577df84f
Executable → Regular
+4 -1
View File
@@ -6281,7 +6281,10 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){
}
pPage = pCur->pPage;
assert( pPage->isInit );
if( sqlite3FaultSim(412) ) pPage->isInit = 0;
if( !pPage->isInit ){
return SQLITE_CORRUPT_BKPT;
}
if( !pPage->leaf ){
int idx = pCur->ix;
rc = moveToChild(pCur, get4byte(findCell(pPage, idx)));
+1 -1
View File
@@ -64,7 +64,7 @@
** 22 1 Min embedded payload fraction (must be 32)
** 23 1 Min leaf payload fraction (must be 32)
** 24 4 File change counter
** 28 4 The size of the database in pages
** 28 4 Reserved for future use
** 32 4 First freelist page
** 36 4 Number of freelist pages in the file
** 40 60 15 4-byte meta values passed to higher layers
+6 -3
View File
@@ -3002,9 +3002,12 @@ void sqlite3CreateView(
** on a view, even though views do not have rowids. The following flag
** setting fixes this problem. But the fix can be disabled by compiling
** with -DSQLITE_ALLOW_ROWID_IN_VIEW in case there are legacy apps that
** depend upon the old buggy behavior. */
#ifndef SQLITE_ALLOW_ROWID_IN_VIEW
p->tabFlags |= TF_NoVisibleRowid;
** depend upon the old buggy behavior. The ability can also be toggled
** using sqlite3_config(SQLITE_CONFIG_ROWID_IN_VIEW,...) */
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
p->tabFlags |= sqlite3Config.mNoVisibleRowid; /* Optional. Allow by default */
#else
p->tabFlags |= TF_NoVisibleRowid; /* Never allow rowid in view */
#endif
sqlite3TwoPartName(pParse, pName1, pName2, &pName);
-6
View File
@@ -1043,12 +1043,6 @@ static int isDate(
}
computeJD(p);
if( p->isError || !validJulianDay(p->iJD) ) return 1;
if( argc==1 && p->validYMD && p->D>28 ){
/* Make sure a YYYY-MM-DD is normalized.
** Example: 2023-02-31 -> 2023-03-03 */
assert( p->validJD );
p->validYMD = 0;
}
return 0;
}
+14 -9
View File
@@ -218,9 +218,10 @@ Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){
assert( pExpr->x.pList->nExpr>0 );
assert( pExpr->op==TK_FUNCTION );
pExpr = pExpr->x.pList->a[0].pExpr;
}else{
assert( pExpr->op==TK_COLLATE );
}else if( pExpr->op==TK_COLLATE ){
pExpr = pExpr->pLeft;
}else{
break;
}
}
return pExpr;
@@ -2737,9 +2738,12 @@ int sqlite3ExprCanBeNull(const Expr *p){
return 0;
case TK_COLUMN:
assert( ExprUseYTab(p) );
return ExprHasProperty(p, EP_CanBeNull) ||
p->y.pTab==0 || /* Reference to column of index on expression */
(p->iColumn>=0
return ExprHasProperty(p, EP_CanBeNull)
|| p->y.pTab==0 /* Reference to column of index on expression */
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
|| (p->iColumn==XN_ROWID && IsView(p->y.pTab))
#endif
|| (p->iColumn>=0
&& p->y.pTab->aCol!=0 /* Possible due to prior error */
&& p->y.pTab->aCol[p->iColumn].notNull==0);
default:
@@ -5322,8 +5326,10 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
if( inReg!=target ){
u8 op;
if( ALWAYS(pExpr)
&& (ExprHasProperty(pExpr,EP_Subquery) || pExpr->op==TK_REGISTER)
Expr *pX = sqlite3ExprSkipCollateAndLikely(pExpr);
testcase( pX!=pExpr );
if( ALWAYS(pX)
&& (ExprHasProperty(pX,EP_Subquery) || pX->op==TK_REGISTER)
){
op = OP_Copy;
}else{
@@ -6769,14 +6775,13 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
case TK_AGG_FUNCTION: {
if( (pNC->ncFlags & NC_InAggFunc)==0
&& pWalker->walkerDepth==pExpr->op2
&& pExpr->pAggInfo==0
){
/* Check to see if pExpr is a duplicate of another aggregate
** function that is already in the pAggInfo structure
*/
struct AggInfo_func *pItem = pAggInfo->aFunc;
for(i=0; i<pAggInfo->nFunc; i++, pItem++){
if( NEVER(pItem->pFExpr==pExpr) ) break;
if( pItem->pFExpr==pExpr ) break;
if( sqlite3ExprCompare(0, pItem->pFExpr, pExpr, -1)==0 ){
break;
}
+3 -3
View File
@@ -1892,7 +1892,7 @@ static void sumFinalize(sqlite3_context *context){
if( p->approx ){
if( p->ovrfl ){
sqlite3_result_error(context,"integer overflow",-1);
}else if( !sqlite3IsNaN(p->rErr) ){
}else if( !sqlite3IsOverflow(p->rErr) ){
sqlite3_result_double(context, p->rSum+p->rErr);
}else{
sqlite3_result_double(context, p->rSum);
@@ -1909,7 +1909,7 @@ static void avgFinalize(sqlite3_context *context){
double r;
if( p->approx ){
r = p->rSum;
if( !sqlite3IsNaN(p->rErr) ) r += p->rErr;
if( !sqlite3IsOverflow(p->rErr) ) r += p->rErr;
}else{
r = (double)(p->iSum);
}
@@ -1923,7 +1923,7 @@ static void totalFinalize(sqlite3_context *context){
if( p ){
if( p->approx ){
r = p->rSum;
if( !sqlite3IsNaN(p->rErr) ) r += p->rErr;
if( !sqlite3IsOverflow(p->rErr) ) r += p->rErr;
}else{
r = (double)(p->iSum);
}
+3
View File
@@ -285,6 +285,9 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
#endif
#ifndef SQLITE_UNTESTABLE
0, /* xTestCallback */
#endif
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
0, /* mNoVisibleRowid. 0 == allow rowid-in-view */
#endif
0, /* bLocaltimeFault */
0, /* xAltLocaltime */
+1 -1
View File
@@ -1086,7 +1086,7 @@ void sqlite3Insert(
pNx->iDataCur = iDataCur;
pNx->iIdxCur = iIdxCur;
if( pNx->pUpsertTarget ){
if( sqlite3UpsertAnalyzeTarget(pParse, pTabList, pNx) ){
if( sqlite3UpsertAnalyzeTarget(pParse, pTabList, pNx, pUpsert) ){
goto insert_cleanup;
}
}
+1382 -3257
View File
File diff suppressed because it is too large Load Diff
+12
View File
@@ -765,6 +765,18 @@ int sqlite3_config(int op, ...){
}
#endif /* SQLITE_OMIT_DESERIALIZE */
case SQLITE_CONFIG_ROWID_IN_VIEW: {
int *pVal = va_arg(ap,int*);
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
if( 0==*pVal ) sqlite3GlobalConfig.mNoVisibleRowid = TF_NoVisibleRowid;
if( 1==*pVal ) sqlite3GlobalConfig.mNoVisibleRowid = 0;
*pVal = (sqlite3GlobalConfig.mNoVisibleRowid==0);
#else
*pVal = 0;
#endif
break;
}
default: {
rc = SQLITE_ERROR;
break;
+102 -220
View File
@@ -4054,13 +4054,7 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
case SQLITE_FCNTL_LOCK_TIMEOUT: {
int iOld = pFile->iBusyTimeout;
#if SQLITE_ENABLE_SETLK_TIMEOUT==1
pFile->iBusyTimeout = *(int*)pArg;
#elif SQLITE_ENABLE_SETLK_TIMEOUT==2
pFile->iBusyTimeout = !!(*(int*)pArg);
#else
# error "SQLITE_ENABLE_SETLK_TIMEOUT must be set to 1 or 2"
#endif
*(int*)pArg = iOld;
return SQLITE_OK;
}
@@ -4313,25 +4307,6 @@ static int unixGetpagesize(void){
** Either unixShmNode.pShmMutex must be held or unixShmNode.nRef==0 and
** unixMutexHeld() is true when reading or writing any other field
** in this structure.
**
** aLock[SQLITE_SHM_NLOCK]:
** This array records the various locks held by clients on each of the
** SQLITE_SHM_NLOCK slots. If the aLock[] entry is set to 0, then no
** locks are held by the process on this slot. If it is set to -1, then
** some client holds an EXCLUSIVE lock on the locking slot. If the aLock[]
** value is set to a positive value, then it is the number of shared
** locks currently held on the slot.
**
** aMutex[SQLITE_SHM_NLOCK]:
** Normally, when SQLITE_ENABLE_SETLK_TIMEOUT is not defined, mutex
** pShmMutex is used to protect the aLock[] array and the right to
** call fcntl() on unixShmNode.hShm to obtain or release locks.
**
** If SQLITE_ENABLE_SETLK_TIMEOUT is defined though, we use an array
** of mutexes - one for each locking slot. To read or write locking
** slot aLock[iSlot], the caller must hold the corresponding mutex
** aMutex[iSlot]. Similarly, to call fcntl() to obtain or release a
** lock corresponding to slot iSlot, mutex aMutex[iSlot] must be held.
*/
struct unixShmNode {
unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */
@@ -4345,11 +4320,10 @@ struct unixShmNode {
char **apRegion; /* Array of mapped shared-memory regions */
int nRef; /* Number of unixShm objects pointing to this */
unixShm *pFirst; /* All unixShm objects pointing to this */
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
sqlite3_mutex *aMutex[SQLITE_SHM_NLOCK];
#endif
int aLock[SQLITE_SHM_NLOCK]; /* # shared locks on slot, -1==excl lock */
#ifdef SQLITE_DEBUG
u8 exclMask; /* Mask of exclusive locks held */
u8 sharedMask; /* Mask of shared locks held */
u8 nextShmId; /* Next available unixShm.id value */
#endif
};
@@ -4432,29 +4406,16 @@ static int unixShmSystemLock(
struct flock f; /* The posix advisory locking structure */
int rc = SQLITE_OK; /* Result code form fcntl() */
/* Access to the unixShmNode object is serialized by the caller */
pShmNode = pFile->pInode->pShmNode;
/* Assert that the correct mutex or mutexes are held. */
if( pShmNode->nRef==0 ){
assert( ofst==UNIX_SHM_DMS && n==1 && unixMutexHeld() );
}else{
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
int ii;
for(ii=ofst-UNIX_SHM_BASE; ii<ofst-UNIX_SHM_BASE+n; ii++){
assert( sqlite3_mutex_held(pShmNode->aMutex[ii]) );
}
#else
assert( sqlite3_mutex_held(pShmNode->pShmMutex) );
assert( pShmNode->nRef>0 );
#endif
}
assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) );
assert( pShmNode->nRef>0 || unixMutexHeld() );
/* Shared locks never span more than one byte */
assert( n==1 || lockType!=F_RDLCK );
/* Locks are within range */
assert( n>=1 && n<=SQLITE_SHM_NLOCK );
assert( ofst>=UNIX_SHM_BASE && ofst<=(UNIX_SHM_DMS+SQLITE_SHM_NLOCK) );
if( pShmNode->hShm>=0 ){
int res;
@@ -4465,7 +4426,7 @@ static int unixShmSystemLock(
f.l_len = n;
res = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
if( res==-1 ){
#if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && SQLITE_ENABLE_SETLK_TIMEOUT==1
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
rc = (pFile->iBusyTimeout ? SQLITE_BUSY_TIMEOUT : SQLITE_BUSY);
#else
rc = SQLITE_BUSY;
@@ -4473,28 +4434,39 @@ static int unixShmSystemLock(
}
}
/* Do debug tracing */
/* Update the global lock state and do debug tracing */
#ifdef SQLITE_DEBUG
{ u16 mask;
OSTRACE(("SHM-LOCK "));
mask = ofst>31 ? 0xffff : (1<<(ofst+n)) - (1<<ofst);
if( rc==SQLITE_OK ){
if( lockType==F_UNLCK ){
OSTRACE(("unlock %d..%d ok\n", ofst, ofst+n-1));
OSTRACE(("unlock %d ok", ofst));
pShmNode->exclMask &= ~mask;
pShmNode->sharedMask &= ~mask;
}else if( lockType==F_RDLCK ){
OSTRACE(("read-lock %d..%d ok\n", ofst, ofst+n-1));
OSTRACE(("read-lock %d ok", ofst));
pShmNode->exclMask &= ~mask;
pShmNode->sharedMask |= mask;
}else{
assert( lockType==F_WRLCK );
OSTRACE(("write-lock %d..%d ok\n", ofst, ofst+n-1));
OSTRACE(("write-lock %d ok", ofst));
pShmNode->exclMask |= mask;
pShmNode->sharedMask &= ~mask;
}
}else{
if( lockType==F_UNLCK ){
OSTRACE(("unlock %d..%d failed\n", ofst, ofst+n-1));
OSTRACE(("unlock %d failed", ofst));
}else if( lockType==F_RDLCK ){
OSTRACE(("read-lock %d..%d failed\n", ofst, ofst+n-1));
OSTRACE(("read-lock failed"));
}else{
assert( lockType==F_WRLCK );
OSTRACE(("write-lock %d..%d failed\n", ofst, ofst+n-1));
OSTRACE(("write-lock %d failed", ofst));
}
}
OSTRACE((" - afterwards %03x,%03x\n",
pShmNode->sharedMask, pShmNode->exclMask));
}
#endif
return rc;
@@ -4531,11 +4503,6 @@ static void unixShmPurge(unixFile *pFd){
int i;
assert( p->pInode==pFd->pInode );
sqlite3_mutex_free(p->pShmMutex);
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
for(i=0; i<SQLITE_SHM_NLOCK; i++){
sqlite3_mutex_free(p->aMutex[i]);
}
#endif
for(i=0; i<p->nRegion; i+=nShmPerMap){
if( p->hShm>=0 ){
osMunmap(p->apRegion[i], p->szRegion);
@@ -4595,20 +4562,7 @@ static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){
pShmNode->isUnlocked = 1;
rc = SQLITE_READONLY_CANTINIT;
}else{
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
/* Do not use a blocking lock here. If the lock cannot be obtained
** immediately, it means some other connection is truncating the
** *-shm file. And after it has done so, it will not release its
** lock, but only downgrade it to a shared lock. So no point in
** blocking here. The call below to obtain the shared DMS lock may
** use a blocking lock. */
int iSaveTimeout = pDbFd->iBusyTimeout;
pDbFd->iBusyTimeout = 0;
#endif
rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1);
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
pDbFd->iBusyTimeout = iSaveTimeout;
#endif
/* The first connection to attach must truncate the -shm file. We
** truncate to 3 bytes (an arbitrary small number, less than the
** -shm header size) rather than 0 as a system debugging aid, to
@@ -4729,18 +4683,6 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
rc = SQLITE_NOMEM_BKPT;
goto shm_open_err;
}
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
{
int ii;
for(ii=0; ii<SQLITE_SHM_NLOCK; ii++){
pShmNode->aMutex[ii] = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
if( pShmNode->aMutex[ii]==0 ){
rc = SQLITE_NOMEM_BKPT;
goto shm_open_err;
}
}
}
#endif
}
if( pInode->bProcessLock==0 ){
@@ -4962,11 +4904,9 @@ shmpage_out:
*/
#ifdef SQLITE_DEBUG
static int assertLockingArrayOk(unixShmNode *pShmNode){
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
return 1;
#else
unixShm *pX;
int aLock[SQLITE_SHM_NLOCK];
assert( sqlite3_mutex_held(pShmNode->pShmMutex) );
memset(aLock, 0, sizeof(aLock));
for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
@@ -4984,14 +4924,13 @@ static int assertLockingArrayOk(unixShmNode *pShmNode){
assert( 0==memcmp(pShmNode->aLock, aLock, sizeof(aLock)) );
return (memcmp(pShmNode->aLock, aLock, sizeof(aLock))==0);
#endif
}
#endif
/*
** Change the lock state for a shared-memory segment.
**
** Note that the relationship between SHARED and EXCLUSIVE locks is a little
** Note that the relationship between SHAREd and EXCLUSIVE locks is a little
** different here than in posix. In xShmLock(), one can go from unlocked
** to shared and back or from unlocked to exclusive and back. But one may
** not go from shared to exclusive or from exclusive to shared.
@@ -5006,7 +4945,7 @@ static int unixShmLock(
unixShm *p; /* The shared memory being locked */
unixShmNode *pShmNode; /* The underlying file iNode */
int rc = SQLITE_OK; /* Result code */
u16 mask = (1<<(ofst+n)) - (1<<ofst); /* Mask of locks to take or release */
u16 mask; /* Mask of locks to take or release */
int *aLock;
p = pDbFd->pShm;
@@ -5041,150 +4980,88 @@ static int unixShmLock(
** It is not permitted to block on the RECOVER lock.
*/
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
{
u16 lockMask = (p->exclMask|p->sharedMask);
assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || (
(ofst!=2) /* not RECOVER */
&& (ofst!=1 || lockMask==0 || lockMask==2)
&& (ofst!=0 || lockMask<3)
&& (ofst<3 || lockMask<(1<<ofst))
));
}
assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || (
(ofst!=2) /* not RECOVER */
&& (ofst!=1 || (p->exclMask|p->sharedMask)==0)
&& (ofst!=0 || (p->exclMask|p->sharedMask)<3)
&& (ofst<3 || (p->exclMask|p->sharedMask)<(1<<ofst))
));
#endif
/* Check if there is any work to do. There are three cases:
**
** a) An unlock operation where there are locks to unlock,
** b) An shared lock where the requested lock is not already held
** c) An exclusive lock where the requested lock is not already held
**
** The SQLite core never requests an exclusive lock that it already holds.
** This is assert()ed below.
*/
assert( flags!=(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK)
|| 0==(p->exclMask & mask)
);
if( ((flags & SQLITE_SHM_UNLOCK) && ((p->exclMask|p->sharedMask) & mask))
|| (flags==(SQLITE_SHM_SHARED|SQLITE_SHM_LOCK) && 0==(p->sharedMask & mask))
|| (flags==(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK))
){
mask = (1<<(ofst+n)) - (1<<ofst);
assert( n>1 || mask==(1<<ofst) );
sqlite3_mutex_enter(pShmNode->pShmMutex);
assert( assertLockingArrayOk(pShmNode) );
if( flags & SQLITE_SHM_UNLOCK ){
if( (p->exclMask|p->sharedMask) & mask ){
int ii;
int bUnlock = 1;
/* Take the required mutexes. In SETLK_TIMEOUT mode (blocking locks), if
** this is an attempt on an exclusive lock use sqlite3_mutex_try(). If any
** other thread is holding this mutex, then it is either holding or about
** to hold a lock exclusive to the one being requested, and we may
** therefore return SQLITE_BUSY to the caller.
**
** Doing this prevents some deadlock scenarios. For example, thread 1 may
** be a checkpointer blocked waiting on the WRITER lock. And thread 2
** may be a normal SQL client upgrading to a write transaction. In this
** case thread 2 does a non-blocking request for the WRITER lock. But -
** if it were to use sqlite3_mutex_enter() then it would effectively
** become a (doomed) blocking request, as thread 2 would block until thread
** 1 obtained WRITER and released the mutex. Since thread 2 already holds
** a lock on a read-locking slot at this point, this breaks the
** anti-deadlock rules (see above). */
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
int iMutex;
for(iMutex=ofst; iMutex<ofst+n; iMutex++){
if( flags==(SQLITE_SHM_LOCK|SQLITE_SHM_EXCLUSIVE) ){
rc = sqlite3_mutex_try(pShmNode->aMutex[iMutex]);
if( rc!=SQLITE_OK ) break;
}else{
sqlite3_mutex_enter(pShmNode->aMutex[iMutex]);
for(ii=ofst; ii<ofst+n; ii++){
if( aLock[ii]>((p->sharedMask & (1<<ii)) ? 1 : 0) ){
bUnlock = 0;
}
}
if( bUnlock ){
rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n);
if( rc==SQLITE_OK ){
memset(&aLock[ofst], 0, sizeof(int)*n);
}
}else if( ALWAYS(p->sharedMask & (1<<ofst)) ){
assert( n==1 && aLock[ofst]>1 );
aLock[ofst]--;
}
/* Undo the local locks */
if( rc==SQLITE_OK ){
p->exclMask &= ~mask;
p->sharedMask &= ~mask;
}
}
#else
sqlite3_mutex_enter(pShmNode->pShmMutex);
#endif
}else if( flags & SQLITE_SHM_SHARED ){
assert( n==1 );
assert( (p->exclMask & (1<<ofst))==0 );
if( (p->sharedMask & mask)==0 ){
if( aLock[ofst]<0 ){
rc = SQLITE_BUSY;
}else if( aLock[ofst]==0 ){
rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n);
}
/* Get the local shared locks */
if( rc==SQLITE_OK ){
p->sharedMask |= mask;
aLock[ofst]++;
}
}
}else{
/* Make sure no sibling connections hold locks that will block this
** lock. If any do, return SQLITE_BUSY right away. */
int ii;
for(ii=ofst; ii<ofst+n; ii++){
assert( (p->sharedMask & mask)==0 );
if( ALWAYS((p->exclMask & (1<<ii))==0) && aLock[ii] ){
rc = SQLITE_BUSY;
break;
}
}
/* Get the exclusive locks at the system level. Then if successful
** also update the in-memory values. */
if( rc==SQLITE_OK ){
if( flags & SQLITE_SHM_UNLOCK ){
/* Case (a) - unlock. */
int bUnlock = 1;
assert( (p->exclMask & p->sharedMask)==0 );
assert( !(flags & SQLITE_SHM_EXCLUSIVE) || (p->exclMask & mask)==mask );
assert( !(flags & SQLITE_SHM_SHARED) || (p->sharedMask & mask)==mask );
/* If this is a SHARED lock being unlocked, it is possible that other
** clients within this process are holding the same SHARED lock. In
** this case, set bUnlock to 0 so that the posix lock is not removed
** from the file-descriptor below. */
if( flags & SQLITE_SHM_SHARED ){
assert( n==1 );
assert( aLock[ofst]>=1 );
if( aLock[ofst]>1 ){
bUnlock = 0;
aLock[ofst]--;
p->sharedMask &= ~mask;
}
}
if( bUnlock ){
rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n);
if( rc==SQLITE_OK ){
memset(&aLock[ofst], 0, sizeof(int)*n);
p->sharedMask &= ~mask;
p->exclMask &= ~mask;
}
}
}else if( flags & SQLITE_SHM_SHARED ){
/* Case (b) - a shared lock. */
if( aLock[ofst]<0 ){
/* An exclusive lock is held by some other connection. BUSY. */
rc = SQLITE_BUSY;
}else if( aLock[ofst]==0 ){
rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n);
}
/* Get the local shared locks */
if( rc==SQLITE_OK ){
p->sharedMask |= mask;
aLock[ofst]++;
}
}else{
/* Case (c) - an exclusive lock. */
int ii;
assert( flags==(SQLITE_SHM_LOCK|SQLITE_SHM_EXCLUSIVE) );
rc = unixShmSystemLock(pDbFd, F_WRLCK, ofst+UNIX_SHM_BASE, n);
if( rc==SQLITE_OK ){
assert( (p->sharedMask & mask)==0 );
assert( (p->exclMask & mask)==0 );
/* Make sure no sibling connections hold locks that will block this
** lock. If any do, return SQLITE_BUSY right away. */
p->exclMask |= mask;
for(ii=ofst; ii<ofst+n; ii++){
if( aLock[ii] ){
rc = SQLITE_BUSY;
break;
}
}
/* Get the exclusive locks at the system level. Then if successful
** also update the in-memory values. */
if( rc==SQLITE_OK ){
rc = unixShmSystemLock(pDbFd, F_WRLCK, ofst+UNIX_SHM_BASE, n);
if( rc==SQLITE_OK ){
p->exclMask |= mask;
for(ii=ofst; ii<ofst+n; ii++){
aLock[ii] = -1;
}
}
aLock[ii] = -1;
}
}
assert( assertLockingArrayOk(pShmNode) );
}
/* Drop the mutexes acquired above. */
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
for(iMutex--; iMutex>=ofst; iMutex--){
sqlite3_mutex_leave(pShmNode->aMutex[iMutex]);
}
#else
sqlite3_mutex_leave(pShmNode->pShmMutex);
#endif
}
assert( assertLockingArrayOk(pShmNode) );
sqlite3_mutex_leave(pShmNode->pShmMutex);
OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
p->id, osGetpid(0), p->sharedMask, p->exclMask));
return rc;
@@ -5434,11 +5311,16 @@ static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
#if SQLITE_MAX_MMAP_SIZE>0
if( pFd->mmapSizeMax>0 ){
/* Ensure that there is always at least a 256 byte buffer of addressable
** memory following the returned page. If the database is corrupt,
** SQLite may overread the page slightly (in practice only a few bytes,
** but 256 is safe, round, number). */
const int nEofBuffer = 256;
if( pFd->pMapRegion==0 ){
int rc = unixMapfile(pFd, -1);
if( rc!=SQLITE_OK ) return rc;
}
if( pFd->mmapSize >= iOff+nAmt ){
if( pFd->mmapSize >= (iOff+nAmt+nEofBuffer) ){
*pp = &((u8 *)pFd->pMapRegion)[iOff];
pFd->nFetchOut++;
}
+6 -1
View File
@@ -4521,6 +4521,11 @@ static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
#if SQLITE_MAX_MMAP_SIZE>0
if( pFd->mmapSizeMax>0 ){
/* Ensure that there is always at least a 256 byte buffer of addressable
** memory following the returned page. If the database is corrupt,
** SQLite may overread the page slightly (in practice only a few bytes,
** but 256 is safe, round, number). */
const int nEofBuffer = 256;
if( pFd->pMapRegion==0 ){
int rc = winMapfile(pFd, -1);
if( rc!=SQLITE_OK ){
@@ -4529,7 +4534,7 @@ static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
return rc;
}
}
if( pFd->mmapSize >= iOff+nAmt ){
if( pFd->mmapSize >= (iOff+nAmt+nEofBuffer) ){
assert( pFd->pMapRegion!=0 );
*pp = &((u8 *)pFd->pMapRegion)[iOff];
pFd->nFetchOut++;
+1 -1
View File
@@ -7792,7 +7792,7 @@ int sqlite3PagerWalFramesize(Pager *pPager){
}
#endif
#ifdef SQLITE_USE_SEH
#if defined(SQLITE_USE_SEH) && !defined(SQLITE_OMIT_WAL)
int sqlite3PagerWalSystemErrno(Pager *pPager){
return sqlite3WalSystemErrno(pPager->pWal);
}
+39 -26
View File
@@ -1762,31 +1762,7 @@ void sqlite3Pragma(
int mxCol; /* Maximum non-virtual column number */
if( pObjTab && pObjTab!=pTab ) continue;
if( !IsOrdinaryTable(pTab) ){
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite3_vtab *pVTab;
int a1;
if( !IsVirtual(pTab) ) continue;
if( pTab->nCol<=0 ){
const char *zMod = pTab->u.vtab.azArg[0];
if( sqlite3HashFind(&db->aModule, zMod)==0 ) continue;
}
sqlite3ViewGetColumnNames(pParse, pTab);
if( pTab->u.vtab.p==0 ) continue;
pVTab = pTab->u.vtab.p->pVtab;
if( NEVER(pVTab==0) ) continue;
if( NEVER(pVTab->pModule==0) ) continue;
if( pVTab->pModule->iVersion<4 ) continue;
if( pVTab->pModule->xIntegrity==0 ) continue;
sqlite3VdbeAddOp3(v, OP_VCheck, i, 3, isQuick);
pTab->nTabRef++;
sqlite3VdbeAppendP4(v, pTab, P4_TABLEREF);
a1 = sqlite3VdbeAddOp1(v, OP_IsNull, 3); VdbeCoverage(v);
integrityCheckResultRow(v);
sqlite3VdbeJumpHere(v, a1);
#endif
continue;
}
if( !IsOrdinaryTable(pTab) ) continue;
if( isQuick || HasRowid(pTab) ){
pPk = 0;
r2 = 0;
@@ -2111,6 +2087,39 @@ void sqlite3Pragma(
}
}
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Second pass to invoke the xIntegrity method on all virtual
** tables.
*/
for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
Table *pTab = sqliteHashData(x);
sqlite3_vtab *pVTab;
int a1;
if( pObjTab && pObjTab!=pTab ) continue;
if( IsOrdinaryTable(pTab) ) continue;
if( !IsVirtual(pTab) ) continue;
if( pTab->nCol<=0 ){
const char *zMod = pTab->u.vtab.azArg[0];
if( sqlite3HashFind(&db->aModule, zMod)==0 ) continue;
}
sqlite3ViewGetColumnNames(pParse, pTab);
if( pTab->u.vtab.p==0 ) continue;
pVTab = pTab->u.vtab.p->pVtab;
if( NEVER(pVTab==0) ) continue;
if( NEVER(pVTab->pModule==0) ) continue;
if( pVTab->pModule->iVersion<4 ) continue;
if( pVTab->pModule->xIntegrity==0 ) continue;
sqlite3VdbeAddOp3(v, OP_VCheck, i, 3, isQuick);
pTab->nTabRef++;
sqlite3VdbeAppendP4(v, pTab, P4_TABLEREF);
a1 = sqlite3VdbeAddOp1(v, OP_IsNull, 3); VdbeCoverage(v);
integrityCheckResultRow(v);
sqlite3VdbeJumpHere(v, a1);
#endif
continue;
}
}
{
static const int iLn = VDBE_OFFSET_LINENO(2);
@@ -2747,7 +2756,11 @@ static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
j = seen[0]-1;
pIdxInfo->aConstraintUsage[j].argvIndex = 1;
pIdxInfo->aConstraintUsage[j].omit = 1;
if( seen[1]==0 ) return SQLITE_OK;
if( seen[1]==0 ){
pIdxInfo->estimatedCost = (double)1000;
pIdxInfo->estimatedRows = 1000;
return SQLITE_OK;
}
pIdxInfo->estimatedCost = (double)20;
pIdxInfo->estimatedRows = 20;
j = seen[1]-1;
-1
View File
@@ -868,7 +868,6 @@ static int sqlite3LockAndPrepare(
assert( (rc&db->errMask)==rc );
db->busyHandler.nBusy = 0;
sqlite3_mutex_leave(db->mutex);
assert( rc==SQLITE_OK || (*ppStmt)==0 );
return rc;
}
+37 -9
View File
@@ -79,6 +79,8 @@ static void resolveAlias(
assert( iCol>=0 && iCol<pEList->nExpr );
pOrig = pEList->a[iCol].pExpr;
assert( pOrig!=0 );
assert( !ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) );
if( pExpr->pAggInfo ) return;
db = pParse->db;
pDup = sqlite3ExprDup(db, pOrig, 0);
if( db->mallocFailed ){
@@ -182,6 +184,7 @@ Bitmask sqlite3ExprColUsed(Expr *pExpr){
assert( ExprUseYTab(pExpr) );
pExTab = pExpr->y.pTab;
assert( pExTab!=0 );
assert( n < pExTab->nCol );
if( (pExTab->tabFlags & TF_HasGenerated)!=0
&& (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0
){
@@ -465,8 +468,37 @@ static int lookupName(
}
}
if( 0==cnt && VisibleRowid(pTab) ){
/* pTab is a potential ROWID match. Keep track of it and match
** the ROWID later if that seems appropriate. (Search for "cntTab"
** to find related code.) Only allow a ROWID match if there is
** a single ROWID match candidate.
*/
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
/* In SQLITE_ALLOW_ROWID_IN_VIEW mode, allow a ROWID match
** if there is a single VIEW candidate or if there is a single
** non-VIEW candidate plus multiple VIEW candidates. In other
** words non-VIEW candidate terms take precedence over VIEWs.
*/
if( cntTab==0
|| (cntTab==1
&& ALWAYS(pMatch!=0)
&& ALWAYS(pMatch->pTab!=0)
&& (pMatch->pTab->tabFlags & TF_Ephemeral)!=0
&& (pTab->tabFlags & TF_Ephemeral)==0)
){
cntTab = 1;
pMatch = pItem;
}else{
cntTab++;
}
#else
/* The (much more common) non-SQLITE_ALLOW_ROWID_IN_VIEW case is
** simpler since we require exactly one candidate, which will
** always be a non-VIEW
*/
cntTab++;
pMatch = pItem;
#endif
}
}
if( pMatch ){
@@ -592,13 +624,13 @@ static int lookupName(
** Perhaps the name is a reference to the ROWID
*/
if( cnt==0
&& cntTab==1
&& cntTab>=1
&& pMatch
&& (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0
&& sqlite3IsRowid(zCol)
&& ALWAYS(VisibleRowid(pMatch->pTab) || pMatch->fg.isNestedFrom)
){
cnt = 1;
cnt = cntTab;
if( pMatch->fg.isNestedFrom==0 ) pExpr->iColumn = -1;
pExpr->affExpr = SQLITE_AFF_INTEGER;
}
@@ -758,6 +790,7 @@ static int lookupName(
sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
pParse->checkSchema = 1;
pTopNC->nNcErr++;
eNewExprOp = TK_NULL;
}
assert( pFJMatch==0 );
@@ -784,7 +817,7 @@ static int lookupName(
** If a generated column is referenced, set bits for every column
** of the table.
*/
if( pExpr->iColumn>=0 && pMatch!=0 ){
if( pExpr->iColumn>=0 && cnt==1 && pMatch!=0 ){
pMatch->colUsed |= sqlite3ExprColUsed(pExpr);
}
@@ -1249,12 +1282,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
while( pNC2
&& sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0
){
pExpr->op2 += (1 + pNC2->nNestedSelect);
pExpr->op2++;
pNC2 = pNC2->pNext;
}
assert( pDef!=0 || IN_RENAME_OBJECT );
if( pNC2 && pDef ){
pExpr->op2 += pNC2->nNestedSelect;
assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
assert( SQLITE_FUNC_ANYORDER==NC_OrderAgg );
testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
@@ -1813,7 +1845,6 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
/* Recursively resolve names in all subqueries in the FROM clause
*/
if( pOuterNC ) pOuterNC->nNestedSelect++;
for(i=0; i<p->pSrc->nSrc; i++){
SrcItem *pItem = &p->pSrc->a[i];
if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){
@@ -1838,9 +1869,6 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
}
}
}
if( pOuterNC && ALWAYS(pOuterNC->nNestedSelect>0) ){
pOuterNC->nNestedSelect--;
}
/* Set up the local name-context to pass to sqlite3ResolveExprNames() to
** resolve the result-set expression list.
+25 -9
View File
@@ -1950,11 +1950,7 @@ static const char *columnTypeImpl(
** data for the result-set column of the sub-select.
*/
if( iCol<pS->pEList->nExpr
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
&& iCol>=0
#else
&& ALWAYS(iCol>=0)
#endif
&& (!ViewCanHaveRowid || iCol>=0)
){
/* If iCol is less than zero, then the expression requests the
** rowid of the sub-select or view. This expression is legal (see
@@ -5134,6 +5130,10 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){
**
** (11) The subquery is not a VALUES clause
**
** (12) The WHERE clause is not "rowid ISNULL" or the equivalent. This
** case only comes up if SQLite is compiled using
** SQLITE_ALLOW_ROWID_IN_VIEW.
**
** Return 0 if no changes are made and non-zero if one or more WHERE clause
** terms are duplicated into the subquery.
*/
@@ -5244,6 +5244,18 @@ static int pushDownWhereTerms(
}
#endif
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
if( ViewCanHaveRowid && (pWhere->op==TK_ISNULL || pWhere->op==TK_NOTNULL) ){
Expr *pLeft = pWhere->pLeft;
if( ALWAYS(pLeft)
&& pLeft->op==TK_COLUMN
&& pLeft->iColumn < 0
){
return 0; /* Restriction (12) */
}
}
#endif
if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc) ){
nChng++;
pSubq->selFlags |= SF_PushDown;
@@ -5872,12 +5884,14 @@ int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){
while( pSel->pPrior ){ pSel = pSel->pPrior; }
sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol);
pTab->iPKey = -1;
pTab->eTabType = TABTYP_VIEW;
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
#ifndef SQLITE_ALLOW_ROWID_IN_VIEW
/* The usual case - do not allow ROWID on a subquery */
pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
#else
pTab->tabFlags |= TF_Ephemeral; /* Legacy compatibility mode */
/* Legacy compatibility mode */
pTab->tabFlags |= TF_Ephemeral | sqlite3Config.mNoVisibleRowid;
#endif
return pParse->nErr ? SQLITE_ERROR : SQLITE_OK;
}
@@ -6145,7 +6159,7 @@ static int selectExpander(Walker *pWalker, Select *p){
pNestedFrom = pFrom->pSelect->pEList;
assert( pNestedFrom!=0 );
assert( pNestedFrom->nExpr==pTab->nCol );
assert( VisibleRowid(pTab)==0 );
assert( VisibleRowid(pTab)==0 || ViewCanHaveRowid );
}else{
if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
continue;
@@ -6177,7 +6191,8 @@ static int selectExpander(Walker *pWalker, Select *p){
pUsing = 0;
}
nAdd = pTab->nCol + (VisibleRowid(pTab) && (selFlags&SF_NestedFrom));
nAdd = pTab->nCol;
if( VisibleRowid(pTab) && (selFlags & SF_NestedFrom)!=0 ) nAdd++;
for(j=0; j<nAdd; j++){
const char *zName;
struct ExprList_item *pX; /* Newly added ExprList term */
@@ -6259,7 +6274,8 @@ static int selectExpander(Walker *pWalker, Select *p){
pX = &pNew->a[pNew->nExpr-1];
assert( pX->zEName==0 );
if( (selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){
if( pNestedFrom ){
if( pNestedFrom && (!ViewCanHaveRowid || j<pNestedFrom->nExpr) ){
assert( j<pNestedFrom->nExpr );
pX->zEName = sqlite3DbStrDup(db, pNestedFrom->a[j].zEName);
testcase( pX->zEName==0 );
}else{
+16 -11
View File
@@ -251,7 +251,6 @@ INCLUDE ../ext/consio/console_io.h
INCLUDE ../ext/consio/console_io.c
#ifndef SQLITE_SHELL_FIDDLE
/* From here onward, fgets() is redirected to the console_io library. */
# define fgets(b,n,f) fGetsUtf8(b,n,f)
/*
@@ -276,7 +275,6 @@ INCLUDE ../ext/consio/console_io.c
# define eputz(z) ePutsUtf8(z)
# define eputf ePrintfUtf8
# define oputb(buf,na) oPutbUtf8(buf,na)
#else
/* For Fiddle, all console handling and emit redirection is omitted. */
# define sputz(fp,z) fputs(z,fp)
@@ -360,7 +358,7 @@ static void endTimer(void){
sqlite3_int64 iEnd = timeOfDay();
struct rusage sEnd;
getrusage(RUSAGE_SELF, &sEnd);
sputf(stdout, "Run Time: real %.3f user %f sys %f\n",
oputf("Run Time: real %.3f user %f sys %f\n",
(iEnd - iBegin)*0.001,
timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
@@ -439,7 +437,7 @@ static void endTimer(void){
FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
sqlite3_int64 ftWallEnd = timeOfDay();
getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
sputf(stdout, "Run Time: real %.3f user %f sys %f\n",
oputf("Run Time: real %.3f user %f sys %f\n",
(ftWallEnd - ftWallBegin)*0.001,
timeDiff(&ftUserBegin, &ftUserEnd),
timeDiff(&ftKernelBegin, &ftKernelEnd));
@@ -11779,6 +11777,7 @@ static const char zOptions[] =
" -newline SEP set output row separator. Default: '\\n'\n"
" -nofollow refuse to open symbolic links to database files\n"
" -nonce STRING set the safe-mode escape nonce\n"
" -no-rowid-in-view Disable rowid-in-view using sqlite3_config()\n"
" -nullvalue TEXT set text string for NULL values. Default ''\n"
" -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
" -pcachetrace trace all page cache operations\n"
@@ -11860,14 +11859,14 @@ static void printBold(const char *zText){
FOREGROUND_RED|FOREGROUND_INTENSITY
);
#endif
sputz(stdout, zText);
oputz(zText);
#if !SQLITE_OS_WINRT
SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
#endif
}
#else
static void printBold(const char *zText){
sputf(stdout, "\033[1m%s\033[0m", zText);
oputf("\033[1m%s\033[0m", zText);
}
#endif
@@ -12073,6 +12072,10 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
stdin_is_interactive = 0;
}else if( cli_strcmp(z,"-utf8")==0 ){
}else if( cli_strcmp(z,"-no-utf8")==0 ){
}else if( cli_strcmp(z,"-no-rowid-in-view")==0 ){
int val = 0;
sqlite3_config(SQLITE_CONFIG_ROWID_IN_VIEW, &val);
assert( val==0 );
}else if( cli_strcmp(z,"-heap")==0 ){
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
const char *zSize;
@@ -12334,8 +12337,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 ){
sputf(stdout, "%s %s (%d-bit)\n",
sqlite3_libversion(), sqlite3_sourceid(), 8*(int)sizeof(char*));
oputf("%s %s (%d-bit)\n", sqlite3_libversion(), sqlite3_sourceid(),
8*(int)sizeof(char*));
return 0;
}else if( cli_strcmp(z,"-interactive")==0 ){
/* already handled */
@@ -12345,6 +12348,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
/* already handled */
}else if( cli_strcmp(z,"-no-utf8")==0 ){
/* already handled */
}else if( cli_strcmp(z,"-no-rowid-in-view")==0 ){
/* already handled */
}else if( cli_strcmp(z,"-heap")==0 ){
i++;
}else if( cli_strcmp(z,"-pagecache")==0 ){
@@ -12467,13 +12472,13 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
#else
# define SHELL_CIO_CHAR_SET ""
#endif
sputf(stdout, "SQLite version %s %.19s%s\n" /*extra-version-info*/
oputf("SQLite version %s %.19s%s\n" /*extra-version-info*/
"Enter \".help\" for usage hints.\n",
sqlite3_libversion(), sqlite3_sourceid(), SHELL_CIO_CHAR_SET);
if( warnInmemoryDb ){
sputz(stdout, "Connected to a ");
oputz("Connected to a ");
printBold("transient in-memory database");
sputz(stdout, ".\nUse \".open FILENAME\" to reopen on a"
oputz(".\nUse \".open FILENAME\" to reopen on a"
" persistent database.\n");
}
zHistory = getenv("SQLITE_HISTORY");
+20 -5
View File
@@ -2141,6 +2141,22 @@ struct sqlite3_mem_methods {
** configuration setting is never used, then the default maximum is determined
** by the [SQLITE_MEMDB_DEFAULT_MAXSIZE] compile-time option. If that
** compile-time option is not set, then the default maximum is 1073741824.
**
** [[SQLITE_CONFIG_ROWID_IN_VIEW]]
** <dt>SQLITE_CONFIG_ROWID_IN_VIEW
** <dd>The SQLITE_CONFIG_ROWID_IN_VIEW option enables or disables the ability
** for VIEWs to have a ROWID. The capability can only be enabled if SQLite is
** compiled with -DSQLITE_ALLOW_ROWID_IN_VIEW, in which case the capability
** defaults to on. This configuration option queries the current setting or
** changes the setting to off or on. The argument is a pointer to an integer.
** If that integer initially holds a value of 1, then the ability for VIEWs to
** have ROWIDs is activated. If the integer initially holds zero, then the
** ability is deactivated. Any other initial value for the integer leaves the
** setting unchanged. After changes, if any, the integer is written with
** a 1 or 0, if the ability for VIEWs to have ROWIDs is on or off. If SQLite
** is compiled without -DSQLITE_ALLOW_ROWID_IN_VIEW (which is the usual and
** recommended case) then the integer is always filled with zero, regardless
** if its initial value.
** </dl>
*/
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
@@ -2172,6 +2188,7 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */
#define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */
#define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */
#define SQLITE_CONFIG_ROWID_IN_VIEW 30 /* int* */
/*
** CAPI3REF: Database Connection Configuration Options
@@ -3954,17 +3971,15 @@ void sqlite3_free_filename(sqlite3_filename);
** </ul>
**
** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
** text that describes the error, as either UTF-8 or UTF-16 respectively,
** or NULL if no error message is available.
** text that describes the error, as either UTF-8 or UTF-16 respectively.
** (See how SQLite handles [invalid UTF] for exceptions to this rule.)
** ^(Memory to hold the error message string is managed internally.
** The application does not need to worry about freeing the result.
** However, the error string might be overwritten or deallocated by
** subsequent calls to other SQLite interface functions.)^
**
** ^The sqlite3_errstr(E) interface returns the English-language text
** that describes the [result code] E, as UTF-8, or NULL if E is not an
** result code for which a text error message is available.
** ^The sqlite3_errstr() interface returns the English-language text
** that describes the [result code], as UTF-8.
** ^(Memory to hold the error message string is managed internally
** and must not be freed by the application)^.
**
+23 -6
View File
@@ -2114,11 +2114,11 @@ struct FuncDestructor {
#define MFUNCTION(zName, nArg, xPtr, xFunc) \
{nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \
xPtr, 0, xFunc, 0, 0, 0, #zName, {0} }
#define JFUNCTION(zName, nArg, bUseCache, bWS, bRS, bJsonB, iArg, xFunc) \
#define JFUNCTION(zName, nArg, bUseCache, bWS, bRS, iArg, xFunc) \
{nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|SQLITE_FUNC_CONSTANT|\
SQLITE_UTF8|((bUseCache)*SQLITE_FUNC_RUNONLY)|\
((bRS)*SQLITE_SUBTYPE)|((bWS)*SQLITE_RESULT_SUBTYPE), \
SQLITE_INT_TO_PTR(iArg|((bJsonB)*JSON_BLOB)),0,xFunc,0, 0, 0, #zName, {0} }
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
#define INLINE_FUNC(zName, nArg, iArg, mFlags) \
{nArg, SQLITE_FUNC_BUILTIN|\
SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \
@@ -2516,6 +2516,15 @@ struct Table {
#define HasRowid(X) (((X)->tabFlags & TF_WithoutRowid)==0)
#define VisibleRowid(X) (((X)->tabFlags & TF_NoVisibleRowid)==0)
/* Macro is true if the SQLITE_ALLOW_ROWID_IN_VIEW (mis-)feature is
** available. By default, this macro is false
*/
#ifndef SQLITE_ALLOW_ROWID_IN_VIEW
# define ViewCanHaveRowid 0
#else
# define ViewCanHaveRowid (sqlite3Config.mNoVisibleRowid==0)
#endif
/*
** Each foreign key constraint is an instance of the following structure.
**
@@ -3399,7 +3408,6 @@ struct NameContext {
int nRef; /* Number of names resolved by this context */
int nNcErr; /* Number of errors encountered while resolving names */
int ncFlags; /* Zero or more NC_* flags defined below */
u32 nNestedSelect; /* Number of nested selects using this NC */
Select *pWinSelect; /* SELECT statement for any window functions */
};
@@ -3456,6 +3464,7 @@ struct Upsert {
Expr *pUpsertWhere; /* WHERE clause for the ON CONFLICT UPDATE */
Upsert *pNextUpsert; /* Next ON CONFLICT clause in the list */
u8 isDoUpdate; /* True for DO UPDATE. False for DO NOTHING */
u8 isDup; /* True if 2nd or later with same pUpsertIdx */
/* Above this point is the parse tree for the ON CONFLICT clauses.
** The next group of fields stores intermediate data. */
void *pToFree; /* Free memory when deleting the Upsert object */
@@ -4220,6 +4229,11 @@ struct Sqlite3Config {
#endif
#ifndef SQLITE_UNTESTABLE
int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
#endif
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
u32 mNoVisibleRowid; /* TF_NoVisibleRowid if the ROWID_IN_VIEW
** feature is disabled. 0 if rowids can
** occur in views. */
#endif
int bLocaltimeFault; /* True to fail localtime() calls */
int (*xAltLocaltime)(const void*,void*); /* Alternative localtime() routine */
@@ -4676,10 +4690,13 @@ void sqlite3MutexWarnOnContention(sqlite3_mutex*);
# define EXP754 (((u64)0x7ff)<<52)
# define MAN754 ((((u64)1)<<52)-1)
# define IsNaN(X) (((X)&EXP754)==EXP754 && ((X)&MAN754)!=0)
# define IsOvfl(X) (((X)&EXP754)==EXP754)
int sqlite3IsNaN(double);
int sqlite3IsOverflow(double);
#else
# define IsNaN(X) 0
# define sqlite3IsNaN(X) 0
# define IsNaN(X) 0
# define sqlite3IsNaN(X) 0
# define sqlite3IsOVerflow(X) 0
#endif
/*
@@ -5519,7 +5536,7 @@ const char *sqlite3JournalModename(int);
Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*,Upsert*);
void sqlite3UpsertDelete(sqlite3*,Upsert*);
Upsert *sqlite3UpsertDup(sqlite3*,Upsert*);
int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*);
int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*,Upsert*);
void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int);
Upsert *sqlite3UpsertOfIndex(Upsert*,Index*);
int sqlite3UpsertNextIsIPK(Upsert*);
+8
View File
@@ -59,6 +59,14 @@ static void set_options(Tcl_Interp *interp){
Tcl_SetVar2(interp, "sqlite_options", "rowid32", "0", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
Tcl_SetVar2(
interp, "sqlite_options", "allow_rowid_in_view", "1", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(
interp, "sqlite_options", "allow_rowid_in_view", "0", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_CASE_SENSITIVE_LIKE
Tcl_SetVar2(interp, "sqlite_options","casesensitivelike","1",TCL_GLOBAL_ONLY);
#else
+1 -1
View File
@@ -781,7 +781,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
assert( pExpr->x.pList->nExpr==2 );
pY = pExpr->x.pList->a[0].pExpr;
pZ = pExpr->x.pList->a[1].pExpr;
sqlite3TreeViewLine(pView, "BETWEEN%s", zFlgs);
sqlite3TreeViewLine(pView, "BETWEEN");
sqlite3TreeViewExpr(pView, pX, 1);
sqlite3TreeViewExpr(pView, pY, 1);
sqlite3TreeViewExpr(pView, pZ, 0);
+3
View File
@@ -921,6 +921,9 @@ void sqlite3Update(
}
}
if( chngRowid==0 && pPk==0 ){
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
if( isView ) sqlite3VdbeAddOp2(v, OP_Null, 0, regOldRowid);
#endif
sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid);
}
}
+17 -4
View File
@@ -90,7 +90,8 @@ Upsert *sqlite3UpsertNew(
int sqlite3UpsertAnalyzeTarget(
Parse *pParse, /* The parsing context */
SrcList *pTabList, /* Table into which we are inserting */
Upsert *pUpsert /* The ON CONFLICT clauses */
Upsert *pUpsert, /* The ON CONFLICT clauses */
Upsert *pAll /* Complete list of all ON CONFLICT clauses */
){
Table *pTab; /* That table into which we are inserting */
int rc; /* Result code */
@@ -193,6 +194,14 @@ int sqlite3UpsertAnalyzeTarget(
continue;
}
pUpsert->pUpsertIdx = pIdx;
if( sqlite3UpsertOfIndex(pAll,pIdx)!=pUpsert ){
/* Really this should be an error. The isDup ON CONFLICT clause will
** never fire. But this problem was not discovered until three years
** after multi-CONFLICT upsert was added, and so we silently ignore
** the problem to prevent breaking applications that might actually
** have redundant ON CONFLICT clauses. */
pUpsert->isDup = 1;
}
break;
}
if( pUpsert->pUpsertIdx==0 ){
@@ -219,9 +228,13 @@ int sqlite3UpsertNextIsIPK(Upsert *pUpsert){
Upsert *pNext;
if( NEVER(pUpsert==0) ) return 0;
pNext = pUpsert->pNextUpsert;
if( pNext==0 ) return 1;
if( pNext->pUpsertTarget==0 ) return 1;
if( pNext->pUpsertIdx==0 ) return 1;
while( 1 /*exit-by-return*/ ){
if( pNext==0 ) return 1;
if( pNext->pUpsertTarget==0 ) return 1;
if( pNext->pUpsertIdx==0 ) return 1;
if( !pNext->isDup ) return 0;
pNext = pNext->pNextUpsert;
}
return 0;
}
+14 -1
View File
@@ -68,6 +68,19 @@ int sqlite3IsNaN(double x){
}
#endif /* SQLITE_OMIT_FLOATING_POINT */
#ifndef SQLITE_OMIT_FLOATING_POINT
/*
** Return true if the floating point value is NaN or +Inf or -Inf.
*/
int sqlite3IsOverflow(double x){
int rc; /* The value return */
u64 y;
memcpy(&y,&x,sizeof(y));
rc = IsOvfl(y);
return rc;
}
#endif /* SQLITE_OMIT_FLOATING_POINT */
/*
** Compute a string length that is limited to what can be stored in
** lower 30 bits of a 32-bit signed integer.
@@ -141,7 +154,7 @@ void sqlite3ErrorClear(sqlite3 *db){
*/
void sqlite3SystemError(sqlite3 *db, int rc){
if( rc==SQLITE_IOERR_NOMEM ) return;
#ifdef SQLITE_USE_SEH
#if defined(SQLITE_USE_SEH) && !defined(SQLITE_OMIT_WAL)
if( rc==SQLITE_IOERR_IN_PAGE ){
int ii;
int iErr;
+1 -5
View File
@@ -2034,7 +2034,7 @@ case OP_AddImm: { /* in1 */
pIn1 = &aMem[pOp->p1];
memAboutToChange(p, pIn1);
sqlite3VdbeMemIntegerify(pIn1);
*(u64*)&pIn1->u.i += (u64)pOp->p2;
pIn1->u.i += pOp->p2;
break;
}
@@ -8321,7 +8321,6 @@ case OP_VColumn: { /* ncycle */
const sqlite3_module *pModule;
Mem *pDest;
sqlite3_context sContext;
FuncDef nullFunc;
VdbeCursor *pCur = p->apCsr[pOp->p1];
assert( pCur!=0 );
@@ -8339,9 +8338,6 @@ case OP_VColumn: { /* ncycle */
memset(&sContext, 0, sizeof(sContext));
sContext.pOut = pDest;
sContext.enc = encoding;
nullFunc.pUserData = 0;
nullFunc.funcFlags = SQLITE_RESULT_SUBTYPE;
sContext.pFunc = &nullFunc;
assert( pOp->p5==OPFLAG_NOCHNG || pOp->p5==0 );
if( pOp->p5 & OPFLAG_NOCHNG ){
sqlite3VdbeMemSetNull(pDest);
+3 -10
View File
@@ -152,15 +152,7 @@ int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
int rc = SQLITE_OK;
Vdbe *p = (Vdbe*)pStmt;
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex;
#endif
#ifdef SQLITE_ENABLE_API_ARMOR
if( pStmt==0 ){
return SQLITE_MISUSE_BKPT;
}
#endif
#if SQLITE_THREADSAFE
mutex = p->db->mutex;
sqlite3_mutex *mutex = ((Vdbe*)pStmt)->db->mutex;
#endif
sqlite3_mutex_enter(mutex);
for(i=0; i<p->nVar; i++){
@@ -950,8 +942,9 @@ int sqlite3_step(sqlite3_stmt *pStmt){
void *sqlite3_user_data(sqlite3_context *p){
#ifdef SQLITE_ENABLE_API_ARMOR
if( p==0 ) return 0;
#endif
#else
assert( p && p->pFunc );
#endif
return p->pFunc->pUserData;
}
+33 -5
View File
@@ -1531,7 +1531,7 @@ static void SQLITE_NOINLINE vdbeChangeP4Full(
int n
){
if( pOp->p4type ){
assert( pOp->p4type > P4_FREE_IF_LE );
freeP4(p->db, pOp->p4type, pOp->p4.p);
pOp->p4type = 0;
pOp->p4.p = 0;
}
@@ -4060,6 +4060,23 @@ static void serialGet(
pMem->flags = IsNaN(x) ? MEM_Null : MEM_Real;
}
}
static int serialGet7(
const unsigned char *buf, /* Buffer to deserialize from */
Mem *pMem /* Memory cell to write value into */
){
u64 x = FOUR_BYTE_UINT(buf);
u32 y = FOUR_BYTE_UINT(buf+4);
x = (x<<32) + y;
assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 );
swapMixedEndianFloat(x);
memcpy(&pMem->u.r, &x, sizeof(x));
if( IsNaN(x) ){
pMem->flags = MEM_Null;
return 1;
}
pMem->flags = MEM_Real;
return 0;
}
void sqlite3VdbeSerialGet(
const unsigned char *buf, /* Buffer to deserialize from */
u32 serial_type, /* Serial type to deserialize */
@@ -4739,7 +4756,7 @@ int sqlite3VdbeRecordCompareWithSkip(
}else if( serial_type==0 ){
rc = -1;
}else if( serial_type==7 ){
sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
serialGet7(&aKey1[d1], &mem1);
rc = -sqlite3IntFloatCompare(pRhs->u.i, mem1.u.r);
}else{
i64 lhs = vdbeRecordDecodeInt(serial_type, &aKey1[d1]);
@@ -4764,14 +4781,18 @@ int sqlite3VdbeRecordCompareWithSkip(
}else if( serial_type==0 ){
rc = -1;
}else{
sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
if( serial_type==7 ){
if( mem1.u.r<pRhs->u.r ){
if( serialGet7(&aKey1[d1], &mem1) ){
rc = -1; /* mem1 is a NaN */
}else if( mem1.u.r<pRhs->u.r ){
rc = -1;
}else if( mem1.u.r>pRhs->u.r ){
rc = +1;
}else{
assert( rc==0 );
}
}else{
sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
rc = sqlite3IntFloatCompare(mem1.u.i, pRhs->u.r);
}
}
@@ -4841,7 +4862,14 @@ int sqlite3VdbeRecordCompareWithSkip(
/* RHS is null */
else{
serial_type = aKey1[idx1];
rc = (serial_type!=0 && serial_type!=10);
if( serial_type==0
|| serial_type==10
|| (serial_type==7 && serialGet7(&aKey1[d1], &mem1)!=0)
){
assert( rc==0 );
}else{
rc = 1;
}
}
if( rc!=0 ){
+23 -52
View File
@@ -2004,19 +2004,6 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){
}
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
/*
** Attempt to enable blocking locks that block for nMs ms. Return 1 if
** blocking locks are successfully enabled, or 0 otherwise.
*/
static int walEnableBlockingMs(Wal *pWal, int nMs){
int rc = sqlite3OsFileControl(
pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&nMs
);
return (rc==SQLITE_OK);
}
/*
** Attempt to enable blocking locks. Blocking locks are enabled only if (a)
** they are supported by the VFS, and (b) the database handle is configured
@@ -2028,7 +2015,11 @@ static int walEnableBlocking(Wal *pWal){
if( pWal->db ){
int tmout = pWal->db->busyTimeout;
if( tmout ){
res = walEnableBlockingMs(pWal, tmout);
int rc;
rc = sqlite3OsFileControl(
pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout
);
res = (rc==SQLITE_OK);
}
}
return res;
@@ -2077,10 +2068,20 @@ void sqlite3WalDb(Wal *pWal, sqlite3 *db){
pWal->db = db;
}
/*
** Take an exclusive WRITE lock. Blocking if so configured.
*/
static int walLockWriter(Wal *pWal){
int rc;
walEnableBlocking(pWal);
rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
walDisableBlocking(pWal);
return rc;
}
#else
# define walEnableBlocking(x) 0
# define walDisableBlocking(x)
# define walEnableBlockingMs(pWal, ms) 0
# define walLockWriter(pWal) walLockExclusive((pWal), WAL_WRITE_LOCK, 1)
# define sqlite3WalDb(pWal, db)
#endif /* ifdef SQLITE_ENABLE_SETLK_TIMEOUT */
@@ -2681,9 +2682,7 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
}
}else{
int bWriteLock = pWal->writeLock;
if( bWriteLock
|| SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1))
){
if( bWriteLock || SQLITE_OK==(rc = walLockWriter(pWal)) ){
pWal->writeLock = 1;
if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
badHdr = walIndexTryHdr(pWal, pChanged);
@@ -2691,8 +2690,7 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
/* If the wal-index header is still malformed even while holding
** a WRITE lock, it can only mean that the header is corrupted and
** needs to be reconstructed. So run recovery to do exactly that.
** Disable blocking locks first. */
walDisableBlocking(pWal);
*/
rc = walIndexRecover(pWal);
*pChanged = 1;
}
@@ -2959,9 +2957,6 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
int i; /* Loop counter */
int rc = SQLITE_OK; /* Return code */
u32 mxFrame; /* Wal frame to lock to */
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
int nBlockTmout = 0;
#endif
assert( pWal->readLock<0 ); /* Not currently locked */
@@ -2992,19 +2987,6 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
return SQLITE_PROTOCOL;
}
if( cnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39;
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
/* In SQLITE_ENABLE_SETLK_TIMEOUT builds, configure the file-descriptor
** to block for locks for approximately nDelay us. This affects three
** locks: (a) the shared lock taken on the DMS slot in os_unix.c (if
** using os_unix.c), (b) the WRITER lock taken in walIndexReadHdr() if the
** first attempted read fails, and (c) the shared lock taken on the DMS
** slot in os_unix.c. All three of these locks are attempted from within
** the call to walIndexReadHdr() below. */
nBlockTmout = (nDelay+998) / 1000;
if( !useWal && walEnableBlockingMs(pWal, nBlockTmout) ){
nDelay = 1;
}
#endif
sqlite3OsSleep(pWal->pVfs, nDelay);
}
@@ -3013,10 +2995,6 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
if( pWal->bShmUnreliable==0 ){
rc = walIndexReadHdr(pWal, pChanged);
}
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
walDisableBlocking(pWal);
if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY;
#endif
if( rc==SQLITE_BUSY ){
/* If there is not a recovery running in another thread or process
** then convert BUSY errors to WAL_RETRY. If recovery is known to
@@ -3131,12 +3109,9 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT;
}
(void)walEnableBlockingMs(pWal, nBlockTmout);
rc = walLockShared(pWal, WAL_READ_LOCK(mxI));
walDisableBlocking(pWal);
if( rc ){
assert( (rc&0xFF)!=SQLITE_BUSY||rc==SQLITE_BUSY||rc==SQLITE_BUSY_TIMEOUT );
return (rc&0xFF)==SQLITE_BUSY ? WAL_RETRY : rc;
return rc==SQLITE_BUSY ? WAL_RETRY : rc;
}
/* Now that the read-lock has been obtained, check that neither the
** value in the aReadMark[] array or the contents of the wal-index
@@ -4229,9 +4204,10 @@ int sqlite3WalCheckpoint(
if( pWal->readOnly ) return SQLITE_READONLY;
WALTRACE(("WAL%p: checkpoint begins\n", pWal));
/* Enable blocking locks, if possible. */
/* Enable blocking locks, if possible. If blocking locks are successfully
** enabled, set xBusy2=0 so that the busy-handler is never invoked. */
sqlite3WalDb(pWal, db);
if( xBusy2 ) (void)walEnableBlocking(pWal);
(void)walEnableBlocking(pWal);
/* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive
** "checkpoint" lock on the database file.
@@ -4272,14 +4248,9 @@ int sqlite3WalCheckpoint(
/* Read the wal-index header. */
SEH_TRY {
if( rc==SQLITE_OK ){
/* For a passive checkpoint, do not re-enable blocking locks after
** reading the wal-index header. A passive checkpoint should not block
** or invoke the busy handler. The only lock such a checkpoint may
** attempt to obtain is a lock on a read-slot, and it should give up
** immediately and do a partial checkpoint if it cannot obtain it. */
walDisableBlocking(pWal);
rc = walIndexReadHdr(pWal, &isChanged);
if( eMode2!=SQLITE_CHECKPOINT_PASSIVE ) (void)walEnableBlocking(pWal);
(void)walEnableBlocking(pWal);
if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
}
+4 -11
View File
@@ -678,22 +678,12 @@ static void translateColumnToCopy(
for(; iStart<iEnd; iStart++, pOp++){
if( pOp->p1!=iTabCur ) continue;
if( pOp->opcode==OP_Column ){
#ifdef SQLITE_DEBUG
if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
printf("TRANSLATE OP_Column to OP_Copy at %d\n", iStart);
}
#endif
pOp->opcode = OP_Copy;
pOp->p1 = pOp->p2 + iRegister;
pOp->p2 = pOp->p3;
pOp->p3 = 0;
pOp->p5 = 2; /* Cause the MEM_Subtype flag to be cleared */
}else if( pOp->opcode==OP_Rowid ){
#ifdef SQLITE_DEBUG
if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
printf("TRANSLATE OP_Rowid to OP_Sequence at %d\n", iStart);
}
#endif
pOp->opcode = OP_Sequence;
pOp->p1 = iAutoidxCur;
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
@@ -6012,7 +6002,10 @@ WhereInfo *sqlite3WhereBegin(
/* An ORDER/GROUP BY clause of more than 63 terms cannot be optimized */
testcase( pOrderBy && pOrderBy->nExpr==BMS-1 );
if( pOrderBy && pOrderBy->nExpr>=BMS ) pOrderBy = 0;
if( pOrderBy && pOrderBy->nExpr>=BMS ){
pOrderBy = 0;
wctrlFlags &= ~WHERE_WANT_DISTINCT;
}
/* The number of tables in the FROM clause is limited by the number of
** bits in a Bitmask
-112
View File
@@ -358,119 +358,7 @@ do_execsql_test 6.2.2 {
FROM t2 GROUP BY 'constant_string';
} {{}}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 7.0 {
CREATE TABLE invoice (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
amount DOUBLE PRECISION DEFAULT NULL,
name VARCHAR(100) DEFAULT NULL
);
INSERT INTO invoice (amount, name) VALUES
(4.0, 'Michael'), (15.0, 'Bara'), (4.0, 'Michael'), (6.0, 'John');
}
do_execsql_test 7.1 {
SELECT sum(amount), name
from invoice
group by name
having (select v > 6 from (select sum(amount) v) t)
} {
15.0 Bara
8.0 Michael
}
do_execsql_test 7.2 {
SELECT (select 1 from (select sum(amount))) FROM invoice
} {1}
do_execsql_test 8.0 {
CREATE TABLE t1(x INT);
INSERT INTO t1 VALUES(100);
INSERT INTO t1 VALUES(20);
INSERT INTO t1 VALUES(3);
SELECT (SELECT y FROM (SELECT sum(x) AS y) AS t2 ) FROM t1;
} {123}
do_execsql_test 8.1 {
SELECT (
SELECT y FROM (
SELECT z AS y FROM (SELECT sum(x) AS z) AS t2
)
) FROM t1;
} {123}
do_execsql_test 8.2 {
SELECT (
SELECT a FROM (
SELECT y AS a FROM (
SELECT z AS y FROM (SELECT sum(x) AS z) AS t2
)
)
) FROM t1;
} {123}
#-------------------------------------------------------------------------
# dbsqlfuzz 04408efc51ae46897c4c122b407412045ed221b4
#
reset_db
do_execsql_test 9.1 {
WITH out(i, j, k) AS (
VALUES(1234, 5678, 9012)
)
SELECT (
SELECT (
SELECT min(abc) = ( SELECT ( SELECT 1234 fROM (SELECT abc) ) )
FROM (
SELECT sum( out.i ) + ( SELECT sum( out.i ) ) AS abc FROM (SELECT out.j)
)
)
) FROM out;
} {0}
do_execsql_test 9.2 {
CREATE TABLE t1(a);
CREATE TABLE t2(b);
INSERT INTO t1 VALUES(1), (2), (3);
INSERT INTO t2 VALUES(4), (5), (6);
SELECT (
SELECT min(y) + (SELECT x) FROM (
SELECT sum(a) AS x, b AS y FROM t2
)
)
FROM t1;
} {10}
do_execsql_test 9.3 {
SELECT (
SELECT min(y) + (SELECT (SELECT x)) FROM (
SELECT sum(a) AS x, b AS y FROM t2
)
)
FROM t1;
} {10}
do_execsql_test 9.4 {
SELECT (
SELECT (SELECT x) FROM (
SELECT sum(a) AS x, b AS y FROM t2
) GROUP BY y
)
FROM t1;
} {6}
do_execsql_test 9.5 {
SELECT (
SELECT (SELECT (SELECT x)) FROM (
SELECT sum(a) AS x, b AS y FROM t2
) GROUP BY y
)
FROM t1;
} {6}
-5
View File
@@ -146,8 +146,6 @@ datetest 2.49 {datetime('2003-10-22 12:24','0000 second')} {2003-10-22 12:24:00}
datetest 2.50 {datetime('2003-10-22 12:24','0001 second')} {2003-10-22 12:24:01}
datetest 2.51 {datetime('2003-10-22 12:24','nonsense')} NULL
datetest 2.60 {datetime('2023-02-31')} {2023-03-03 00:00:00}
datetest 3.1 {strftime('%d','2003-10-31 12:34:56.432')} 31
datetest 3.2.1 {strftime('pre%fpost','2003-10-31 12:34:56.432')} pre56.432post
datetest 3.2.2 {strftime('%f','2003-10-31 12:34:59.9999999')} 59.999
@@ -454,9 +452,6 @@ datetest 13.31 {date('2001-01-01','+1.5 years')} {2002-07-02}
datetest 13.32 {date('2002-01-01','+1.5 years')} {2003-07-02}
datetest 13.33 {date('2002-01-01','-1.5 years')} {2000-07-02}
datetest 13.34 {date('2001-01-01','-1.5 years')} {1999-07-02}
datetest 13.35 {date('2023-02-28')} {2023-02-28}
datetest 13.36 {date('2023-02-29')} {2023-03-01}
datetest 13.37 {date('2023-04-31')} {2023-05-01}
# Test for issues reported by BareFeet (list.sql at tandb.com.au)
# on mailing list on 2008-06-12.
+4
View File
@@ -136,5 +136,9 @@ do_catchsql_test default-5.1 {
CREATE TABLE t1 (a,b DEFAULT(random() NOTNULL IN (RAISE(IGNORE),2,3)));
INSERT INTO t1(a) VALUES(1);
} {1 {RAISE() may only be used within a trigger-program}}
do_catchsql_test default-5.2 {
CREATE TABLE Table0 (Col0 DEFAULT (RAISE(IGNORE) ) ) ;
INSERT INTO Table0 DEFAULT VALUES ;
} {1 {RAISE() may only be used within a trigger-program}}
finish_test
+21
View File
@@ -1553,4 +1553,25 @@ do_execsql_test func-38.100 {
WITH t1(x) AS (VALUES(-9e+999)) SELECT sum(x), avg(x), total(x) FROM t1;
} {Inf Inf Inf -Inf -Inf -Inf}
# 2024-03-21 https://sqlite.org/forum/forumpost/23b8688ef4
# Another problem with Kahan-Babushka-Neumaier summation and
# infinities.
#
do_execsql_test func-39.101 {
WITH RECURSIVE c(n) AS (VALUES(1) UNION ALL SELECT n+1 FROM c WHERE n<1)
SELECT sum(1.7976931348623157e308),
avg(1.7976931348623157e308),
total(1.7976931348623157e308)
FROM c;
} {1.79769313486232e+308 1.79769313486232e+308 1.79769313486232e+308}
for {set i 2} {$i<10} {incr i} {
do_execsql_test func-39.[expr {10*$i+100}] {
WITH RECURSIVE c(n) AS (VALUES(1) UNION ALL SELECT n+1 FROM c WHERE n<$i)
SELECT sum(1.7976931348623157e308),
avg(1.7976931348623157e308),
total(1.7976931348623157e308)
FROM c;
} {Inf Inf Inf}
}
finish_test
+8
View File
@@ -296,6 +296,14 @@ static char *fuzz_invariant_sql(sqlite3_stmt *pStmt, int iCnt){
** WHERE clause. */
continue;
}
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
if( sqlite3_strlike("%rowid%",zColName,0)==0
|| sqlite3_strlike("%oid%",zColName,0)==0
){
/* ROWID values are unreliable if SQLITE_ALLOW_ROWID_IN_VIEW is used */
continue;
}
#endif
for(j=0; j<i; j++){
const char *zPrior = sqlite3_column_name(pBase, j);
if( sqlite3_stricmp(zPrior, zColName)==0 ) break;
+6 -2
View File
@@ -370,8 +370,12 @@ do_execsql_test 9.1 {
ANALYZE sqlite_schema;
INSERT INTO sqlite_stat1 VALUES('t1','t1x1','648 324 81 81 81 81 81 81 81081 81 81 81');
ANALYZE sqlite_schema;
SELECT a FROM (SELECT a FROM t1 NATURAL LEFT JOIN t1) NATURAL LEFT JOIN t1 WHERE (rowid,1)<=(5,0);
} {1}
}
do_catchsql_test 9.2 {
SELECT a FROM
(SELECT a FROM t1 NATURAL LEFT JOIN t1) NATURAL LEFT JOIN t1
WHERE (rowid,1)<=(5,0);
} {0 1}
# 2022-03-02 https://sqlite.org/forum/info/50a1bbe08ce4c29c
# Bloom-filter pulldown is incompatible with skip-scan.
+3 -3
View File
@@ -201,13 +201,13 @@ do_execsql_test 9.0 {
do_catchsql_test 9.1 {
SELECT rowid FROM wo1, x1, x2;
} {1 {no such column: rowid}}
} {1 {ambiguous column name: rowid}}
do_catchsql_test 9.2 {
SELECT rowid FROM wo1, (x1, x2);
} {1 {no such column: rowid}}
} {1 {ambiguous column name: rowid}}
do_catchsql_test 9.3 {
SELECT rowid FROM wo1 JOIN (x1 JOIN x2);
} {1 {no such column: rowid}}
} {1 {ambiguous column name: rowid}}
do_catchsql_test 9.4 {
SELECT a FROM wo1, x1, x2;
} {1 {ambiguous column name: a}}
-25
View File
@@ -1,25 +0,0 @@
.mode qbox
.timer on
.param set $label '$.q87'
SELECT rowid, x->>$label FROM data1 WHERE x->>$label IS NOT NULL;
CREATE TEMP TABLE t2(x JSON TEXT);
WITH RECURSIVE
c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<25000),
array1(y) AS (
SELECT json_group_array(
json_object('x',x,'y',random(),'z',hex(randomblob(50)))
)
FROM c
),
c2(n) AS (VALUES(1) UNION ALL SELECT n+1 FROM c2 WHERE n<5)
INSERT INTO t2(x)
SELECT jsonb(json_object('a',n,'b',n*2,'c',y,'d',3,'e',5,'f',6))
FROM array1, c2;
CREATE INDEX t2x1 ON t2(x->>'a');
CREATE INDEX t2x2 ON t2(x->>'b');
CREATE INDEX t2x3 ON t2(x->>'e');
CREATE INDEX t2x4 ON t2(x->>'f');
UPDATE t2 SET x=jsonb_replace(x,'$.f',(x->>'f')+1);
UPDATE t2 SET x=jsonb_set(x,'$.e',(x->>'f')-1);
UPDATE t2 SET x=jsonb_remove(x,'$.d');
+4 -14
View File
@@ -40,7 +40,6 @@ doCachegrind=1
doVdbeProfile=0
doWal=1
doDiff=1
doJsonB=0
while test "$1" != ""; do
case $1 in
--nodiff)
@@ -55,9 +54,6 @@ while test "$1" != ""; do
--gcc7)
CC=gcc-7
;;
--jsonb)
doJsonB=1
;;
-*)
CC_OPTS="$CC_OPTS $1"
;;
@@ -73,18 +69,12 @@ rm -f cachegrind.out.* jsonshell
$CC -g -Os -Wall -I. $CC_OPTS ./shell.c ./sqlite3.c -o jsonshell -ldl -lpthread
ls -l jsonshell | tee -a summary-$NAME.txt
home=`echo $0 | sed -e 's,/[^/]*$,,'`
if test $doJsonB -eq 1; then
echo ./jsonshell json100mb_b.db "<$home/json-q1-b.txt"
valgrind --tool=cachegrind ./jsonshell json100mb_b.db <$home/json-q1-b.txt \
2>&1 | tee -a summary-$NAME.txt
else
echo ./jsonshell json100mb.db "<$home/json-q1.txt"
valgrind --tool=cachegrind ./jsonshell json100mb.db <$home/json-q1.txt \
2>&1 | tee -a summary-$NAME.txt
fi
echo ./jsonshell json100mb.db "<$home/json-q1.txt"
valgrind --tool=cachegrind ./jsonshell json100mb.db <$home/json-q1.txt \
2>&1 | tee -a summary-$NAME.txt
cg_anno.tcl cachegrind.out.* >jout-$NAME.txt
echo '*****************************************************' >>jout-$NAME.txt
sed 's/^[0-9=-]\{9\}/==00000==/' summary-$NAME.txt >>jout-$NAME.txt
if test "$NAME" != "$BASELINE" -a $doDiff -ne 0; then
if test "$NAME" != "$BASELINE"; then
fossil xdiff --tk -c 20 jout-$BASELINE.txt jout-$NAME.txt
fi
+11 -119
View File
@@ -36,9 +36,6 @@ do_execsql_test json101-1.2 {
do_catchsql_test json101-1.3 {
SELECT json_array(1,printf('%.1000c','x'),x'abcd',3);
} {1 {JSON cannot hold BLOB values}}
do_catchsql_test json101-1.3b {
SELECT jsonb_array(1,printf('%.1000c','x'),x'abcd',3);
} {1 {JSON cannot hold BLOB values}}
do_execsql_test json101-1.4 {
SELECT json_array(-9223372036854775808,9223372036854775807,0,1,-1,
0.0, 1.0, -1.0, -1e99, +2e100,
@@ -50,83 +47,36 @@ do_execsql_test json101-1.4 {
'abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ',
99);
} {[-9223372036854775808,9223372036854775807,0,1,-1,0.0,1.0,-1.0,-1.0e+99,2.0e+100,"one","two","three",4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,null,21,22,23,24,25,26,27,28,29,30,31,"abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ",99]}
do_execsql_test json101-1.4b {
SELECT json(jsonb_array(-9223372036854775808,9223372036854775807,0,1,-1,
0.0, 1.0, -1.0, -1e99, +2e100,
'one','two','three',
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, NULL, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
'abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ',
99));
} {[-9223372036854775808,9223372036854775807,0,1,-1,0.0,1.0,-1.0,-1.0e+99,2.0e+100,"one","two","three",4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,null,21,22,23,24,25,26,27,28,29,30,31,"abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ",99]}
do_execsql_test json101-2.1 {
SELECT json_object('a',1,'b',2.5,'c',null,'d','String Test');
} {{{"a":1,"b":2.5,"c":null,"d":"String Test"}}}
do_execsql_test json101-2.1b {
SELECT json(jsonb_object('a',1,'b',2.5,'c',null,'d','String Test'));
} {{{"a":1,"b":2.5,"c":null,"d":"String Test"}}}
do_catchsql_test json101-2.2 {
SELECT json_object('a',printf('%.1000c','x'),2,2.5);
} {1 {json_object() labels must be TEXT}}
do_catchsql_test json101-2.2b {
SELECT jsonb_object('a',printf('%.1000c','x'),2,2.5);
} {1 {json_object() labels must be TEXT}}
do_execsql_test json101-2.2.2 {
SELECT json_object('a',json_array('xyx',77,4.5),'x',2.5);
} {{{"a":["xyx",77,4.5],"x":2.5}}}
do_execsql_test json101-2.2.2b {
SELECT json(jsonb_object('a',json_array('xyx',77,4.5),'x',2.5));
} {{{"a":["xyx",77,4.5],"x":2.5}}}
do_execsql_test json101-2.2.3 {
SELECT json_object('a',jsonb_array('xyx',77,4.5),'x',2.5);
} {{{"a":["xyx",77,4.5],"x":2.5}}}
do_execsql_test json101-2.2.3b {
SELECT json(jsonb_object('a',jsonb_array('xyx',77,4.5),'x',2.5));
} {{{"a":["xyx",77,4.5],"x":2.5}}}
do_catchsql_test json101-2.3 {
SELECT json_object('a',1,'b');
} {1 {json_object() requires an even number of arguments}}
do_catchsql_test json101-2.4 {
SELECT json_object('a',printf('%.1000c','x'),'b',x'abcd');
} {1 {JSON cannot hold BLOB values}}
do_execsql_test json101-2.5 {
SELECT json_object('a',printf('%.10c','x'),'b',jsonb_array(1,2,3));
} {{{"a":"xxxxxxxxxx","b":[1,2,3]}}}
do_execsql_test json101-3.1 {
SELECT json_replace('{"a":1,"b":2}','$.a','[3,4,5]');
} {{{"a":"[3,4,5]","b":2}}}
do_execsql_test json101-3.1b {
SELECT json(jsonb_replace('{"a":1,"b":2}','$.a','[3,4,5]'));
} {{{"a":"[3,4,5]","b":2}}}
do_execsql_test json101-3.2 {
SELECT json_replace('{"a":1,"b":2}','$.a',json('[3,4,5]'));
} {{{"a":[3,4,5],"b":2}}}
do_execsql_test json101-3.2b {
SELECT json_replace('{"a":1,"b":2}','$.a',jsonb('[3,4,5]'));
} {{{"a":[3,4,5],"b":2}}}
do_execsql_test json101-3.3 {
SELECT json_type(json_set('{"a":1,"b":2}','$.b','{"x":3,"y":4}'),'$.b');
} {text}
do_execsql_test json101-3.3b {
SELECT json_type(jsonb_set('{"a":1,"b":2}','$.b','{"x":3,"y":4}'),'$.b');
} {text}
do_execsql_test json101-3.4 {
SELECT json_type(json_set('{"a":1,"b":2}','$.b',json('{"x":3,"y":4}')),'$.b');
} {object}
do_execsql_test json101-3.4b {
SELECT json_type(jsonb_set('{"a":1,"b":2}','$.b',jsonb('{"x":3,"y":4}')),'$.b');
} {object}
ifcapable vtab {
do_execsql_test json101-3.5 {
SELECT fullkey, atom, '|' FROM json_tree(json_set('{}','$.x',123,'$.x',456));
} {{$} {} | {$.x} 456 |}
do_execsql_test json101-3.5b {
SELECT fullkey, atom, '|' FROM json_tree(jsonb_set('{}','$.x',123,'$.x',456));
} {{$} {} | {$.x} 456 |}
do_execsql_test json101-3.5 {
SELECT fullkey, atom, '|' FROM json_tree(json_set('{}','$.x',123,'$.x',456));
} {{$} {} | {$.x} 456 |}
}
# Per rfc7159, any JSON value is allowed at the top level, and whitespace
@@ -181,13 +131,6 @@ do_execsql_test json101-4.10 {
WHERE json_extract(x,'$')<>x
AND json_type(x) IN ('object','array');
} {4}
do_execsql_test json101-4.10b {
CREATE TABLE j1b AS SELECT jsonb(x) AS "x" FROM j1;
SELECT count(*) FROM j1b WHERE json_type(x) IN ('object','array');
SELECT json(x) FROM j1b
WHERE json_extract(x,'$')<>json(x)
AND json_type(x) IN ('object','array');
} {4}
do_execsql_test json101-5.1 {
CREATE TABLE j2(id INTEGER PRIMARY KEY, json, src);
@@ -315,17 +258,11 @@ do_execsql_test json101-5.1 {
}
]','https://adobe.github.io/Spry/samples/data_region/JSONDataSetSample.html');
SELECT count(*) FROM j2;
CREATE TABLE j2b(id INTEGER PRIMARY KEY, json, src);
INSERT INTO J2b(id,json,src) SELECT id, jsonb(json), src FROM j2;
SELECT count(*) FROM j2b;
} {3 3}
} {3}
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 |}
do_execsql_test json101-5.2b {
SELECT id, json_valid(json,5), json_type(json), '|' FROM j2b ORDER BY id;
} {1 1 object | 2 1 object | 3 1 array |}
ifcapable !vtab {
finish_test
@@ -340,12 +277,6 @@ do_execsql_test json101-5.3 {
WHERE fullkey!=(path || CASE WHEN typeof(key)=='integer' THEN '['||key||']'
ELSE '.'||key END);
} {}
do_execsql_test json101-5.3b {
SELECT j2b.rowid, jx.rowid, fullkey, path, key
FROM j2b, json_tree(j2b.json) AS jx
WHERE fullkey!=(path || CASE WHEN typeof(key)=='integer' THEN '['||key||']'
ELSE '.'||key END);
} {}
do_execsql_test json101-5.4 {
SELECT j2.rowid, jx.rowid, fullkey, path, key
FROM j2, json_each(j2.json) AS jx
@@ -440,13 +371,6 @@ do_execsql_test json101-8.1 {
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 json101-8.1b {
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=jsonb_array(a);
SELECT json(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 json101-8.2 {
SELECT a=json_extract(b,'$[0]') FROM t8;
} {1}
@@ -477,7 +401,7 @@ do_execsql_test json101-9.4 {
SELECT json_quote(null);
} {"null"}
do_catchsql_test json101-9.5 {
SELECT json_quote(x'3031323334');
SELECT json_quote(x'30313233');
} {1 {JSON cannot hold BLOB values}}
do_catchsql_test json101-9.6 {
SELECT json_quote(123,456)
@@ -845,23 +769,14 @@ do_execsql_test json101-12.100 {
}
}');
} {}
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 json101-12.110b {
SELECT json_remove(jsonb(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 json101-12.120 {
SELECT json_extract(x, '$.settings.layer2."tris.legomenon"."summary.report"')
FROM t12;
} {0}
do_execsql_test json101-12.120b {
SELECT json_extract(jsonb(x), '$.settings.layer2."tris.legomenon"."summary.report"')
FROM t12;
} {0}
# 2018-01-26
# ticket https://www.sqlite.org/src/tktview/80177f0c226ff54f6ddd41
@@ -925,16 +840,16 @@ do_execsql_test json101-14.170 {
#
do_execsql_test json101-15.100 {
SELECT * FROM JSON_EACH('{"a":1, "b":2}');
} {a 1 integer 1 1 {} {$.a} {$} b 2 integer 2 5 {} {$.b} {$}}
} {a 1 integer 1 2 {} {$.a} {$} b 2 integer 2 4 {} {$.b} {$}}
do_execsql_test json101-15.110 {
SELECT xyz.* FROM JSON_EACH('{"a":1, "b":2}') AS xyz;
} {a 1 integer 1 1 {} {$.a} {$} b 2 integer 2 5 {} {$.b} {$}}
} {a 1 integer 1 2 {} {$.a} {$} b 2 integer 2 4 {} {$.b} {$}}
do_execsql_test json101-15.120 {
SELECT * FROM (JSON_EACH('{"a":1, "b":2}'));
} {a 1 integer 1 1 {} {$.a} {$} b 2 integer 2 5 {} {$.b} {$}}
} {a 1 integer 1 2 {} {$.a} {$} b 2 integer 2 4 {} {$.b} {$}}
do_execsql_test json101-15.130 {
SELECT xyz.* FROM (JSON_EACH('{"a":1, "b":2}')) AS xyz;
} {a 1 integer 1 1 {} {$.a} {$} b 2 integer 2 5 {} {$.b} {$}}
} {a 1 integer 1 2 {} {$.a} {$} b 2 integer 2 4 {} {$.b} {$}}
# 2019-11-10
# Mailing list bug report on the handling of surrogate pairs
@@ -974,7 +889,7 @@ do_execsql_test json101-18.4 {
} {6}
do_catchsql_test json101-18.5 {
SELECT json_extract('{"":8}', '$.');
} {1 {bad JSON path: '$.'}}
} {1 {JSON path error near ''}}
# 2022-08-29 https://sqlite.org/forum/forumpost/9b9e4716c0d7bbd1
# This is not a problem specifically with JSON functions. It is
@@ -1139,29 +1054,6 @@ do_execsql_test json101-23.2 {
FROM (SELECT json_set('[]','$[#]',0,'$[#]',1) AS j);
} {{[0,1]} 0 1}
# Insert/Set/Replace where the path specifies substructure that
# does not yet exist
#
proc tx x {return [string map [list ( \173 ) \175 ' \042 < \133 > \135] $x]}
foreach {id start path ins set repl} {
1 {{}} {$.a.b.c} ('a':('b':('c':9))) ('a':('b':('c':9))) ()
2 {{a:4}} {$.a.b.c} ('a':4) ('a':4) ('a':4)
3 {{a:{}}} {$.a.b.c} ('a':('b':('c':9))) ('a':('b':('c':9))) ('a':())
4 {[0,1,2]} {$[3].a[0].b} <0,1,2,('a':<('b':9)>)> <0,1,2,('a':<('b':9)>)> <0,1,2>
5 {[0,1,2]} {$[1].a[0].b} <0,1,2> <0,1,2> <0,1,2>
6 {[0,{},2]} {$[1].a[0].b} <0,('a':<('b':9)>),2> <0,('a':<('b':9)>),2> <0,(),2>
7 {[0,1,2]} {$[3][0].b} <0,1,2,<('b':9)>> <0,1,2,<('b':9)>> <0,1,2>
8 {[0,1,2]} {$[1][0].b} <0,1,2> <0,1,2> <0,1,2>
} {
do_execsql_test json101-24.$id.insert {
SELECT json_insert($start,$path,9);
} [list [tx $ins]]
do_execsql_test json101-24.$id.set {
SELECT json_set($start,$path,9);
} [list [tx $set]]
do_execsql_test json101-24.$id.replace {
SELECT json_replace($start,$path,9);
} [list [tx $repl]]
}
finish_test

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