Compare commits

..

36 Commits

Author SHA1 Message Date
stephan 5e2e34aef8 Re-add the (still) unsupported and (still 100%) untested sqlite3-node.mjs back to the dist bundle, as its removal in 3.51 has [caused some downstream disruption](https://github.com/sqlite/sqlite-wasm/issues/118). This is stashed in a branch for now and may never be merged - we're still negotiating the terms of its re-addition and my eventual capitulation.
FossilOrigin-Name: 8611cf643b11335cd490da1856c34b4f10ac8b82856e0857be1192e36da31f17
2025-11-13 08:36:52 +00:00
stephan f47095a5a0 Teach c-pp to export its argv as a #define list so that we can embed it in the generates files.
FossilOrigin-Name: 42f95ea71e5e7e927685de3a6da2ede38abe7cabdd1fc71b9a14bebe9f54a65e
2025-11-13 08:26:11 +00:00
stephan 791b767b26 Doc typo fix reported in [forum:00e49e9aa1|forum post 00e49e9aa1].
FossilOrigin-Name: 36cd33f634a45900f6e52ba07aa20242a5f2b29c7cbe19be968c52ffef34fcde
2025-11-13 07:07:28 +00:00
stephan ce53b80819 Minor doc correction and a JS error message tweak.
FossilOrigin-Name: c4ae21c89e5fd40eefd4916df6c6a6c4e27075a434a9d47576d3fcfbc7720588
2025-11-13 06:49:12 +00:00
stephan b867030b1a Clarify that 'pikchr' is not a typo.
FossilOrigin-Name: d7bb2ee6ec23c266c887fb2aeb77b0b17cd8f1429564d341537f57c5478410e2
2025-11-12 17:25:17 +00:00
drh 7efded5edc Improved concurrency for "make devtest" by splitting fuzzdata1.db and
fuzzdata2.db into slices for asan and ubsan testing.

FossilOrigin-Name: 2c31176607f02a73cf2626cda2dd0711ae74bdf0b4520d4c84ff299c860e419e
2025-11-10 20:01:39 +00:00
dan f07576429e Avoid dropping RETURNING triggers when the schema is reset while preparing a statement.
FossilOrigin-Name: 45d820ca227eb1ade4dda498b0f94b2c5df4bab3fc5fcdd517ee125a43d16f4d
2025-11-10 19:11:15 +00:00
dan 14fcb8252a Avoid dropping RETURNING triggers when the schema is reset while preparing a statement.
FossilOrigin-Name: e26bcef7522a6f6ee8d55fa30e7fe06419566cf4e8c2df0c33c92a4c89f58c05
2025-11-10 17:37:59 +00:00
drh a79f685533 Fix a missing va_end() call in the intckMprintf() function of the
incremental integrity-check extension.

FossilOrigin-Name: 62ad2350e368dc337ba2d0fb6847d07c40a6f79520dd6414d22b5b54983b0b12
2025-11-10 11:05:36 +00:00
dan 240397bb03 A more compact fix for the problem first fixed by [5f5a736f88].
FossilOrigin-Name: 7a644178c8d289ca18631844b2d73b32fddc72afcc80906633dd38c14eba2ca9
2025-11-10 11:00:41 +00:00
dan 4ac766cc05 Have sqlite3_set_errmsg() return SQLITE_MISUSE if a NULL db handle is passed to it, as documented.
FossilOrigin-Name: 5f5a736f88bc9bc6c9c83d2cbfd74c0b5357d7417d9993d34a78f0b7317ff796
2025-11-10 10:47:29 +00:00
stephan 73caea1764 Reworking of JS internals to support binding of nested C structs (like sqlite3_index_constraint and friends) and allow some of the automated JS/C conversions to be plugged in at the struct-binding level, simplifying how struct members, in particular function pointers, can be used from JS.
FossilOrigin-Name: bb4fd5b789cebf2b224c29023fea3e620a86fb36730c36c0d85d9f35880bf643
2025-11-10 07:41:54 +00:00
drh 998ebf1de7 Fix the ".www" command of the CLI so that it works on unix systems with
newer web browsers that do not allow access to files in /tmp.

FossilOrigin-Name: 2f918c14bac28c567cc854b3d41dcdd59191a118bb5fdea9373945fe860161f5
2025-11-10 01:46:06 +00:00
stephan 051e942f5d Minor doc typo fix reported in [forum:939d5864df|forum post 939d5864df].
FossilOrigin-Name: a1f9c977b83fab11c54710070dbedfaea47195050946db74075bdd3ade97a4c8
2025-11-09 07:11:15 +00:00
stephan 4182294987 CLI shell: ensure that .dump propagates its error code on error. Problem reported in [forum:a4f3873b0a8503cc|forum post a4f3873b0a].
FossilOrigin-Name: 850b92b6347187d702736bf5a574b9b4a49854a33799875f24fc75c50a6bf908
2025-11-09 06:51:32 +00:00
stephan c55d8262cf In sqlite3.wasm.allocFromTypedArray(), swap the order of the allocation and the access to the heap view object to work around an obscure issue when allocating huge blobs. The heap view object could previously become stale via the following allocation if the underlying WebAssembly.Memory object needed to grow. Essentially a realloc()-moves-the-pointer situation but it only comes up with huge allocations under the right circumstances and would trigger a JS exception (as opposed to corrupting the WASM heap). Problem reported in [forum:05b77273be104532|forum post 05b77273be104532].
FossilOrigin-Name: 0f712b6b0516dc151d3bcbb63497661c82e11eae368e639bbdf197e1b3467195
2025-11-09 06:32:10 +00:00
stephan 66b37e991b Add some UNUSED_PARAMATER()s for the sake of -pedantic -DSQLITE_OMIT_WAL.
FossilOrigin-Name: 620434a4a276ecaf2ee56d325815ac4e33c95e1190b420a341e376e54ef60278
2025-11-07 11:46:56 +00:00
drh 0aca0ccf2c Fix a harmless static-analyzer warning.
FossilOrigin-Name: 9819fc5aa7706fda9d4ec67835ae87eed64d321672873c9d864788b8cf5d27d8
2025-11-07 11:22:47 +00:00
drh 748c0adb62 Get the sqlite3Hwtime() function working on ARM. Enable scanstatus by
default on Windows CLI builds.

FossilOrigin-Name: 305bb022368bac9fafd7c2794762299324796903aaea270923d07f2127d8926c
2025-11-06 13:19:50 +00:00
drh e77530050e Improvements to documentation for stmt_scanstatus interfaces.
FossilOrigin-Name: 5f3e883d180d6fb7a1909df284713170f5431ea7afcc1a3eb5912c4620df42b2
2025-11-06 12:25:26 +00:00
stephan 366e0ed80c JNI: doc tweaks. Add missing SQLITE_DBSTATUS_TEMPBUF_SPILL export.
FossilOrigin-Name: 2c8938f43f721a2592b0efe36f75ab87aa370654e1a22d646c0a17d58d643295
2025-11-05 10:07:57 +00:00
stephan 201066302e TEA extension: add --tcl-stubs config flag, defaulting to zero, because there does not seem to be a universally-valid default for that. Addresses [forum:cd6503fce2|forum post cd6503fce2].
FossilOrigin-Name: 4954b94763052ed60ad2ae610e4f5c18fdba4475a39eb369408e984c89805e97
2025-11-05 05:59:53 +00:00
drh 29bdac3ee5 Remove stale code from the fileio.c extension.
FossilOrigin-Name: d26f115760f16cac1cd28c950d1c0eec199461d2c9a52baafb91ff6b8d5ec151
2025-11-04 23:47:49 +00:00
stephan 53ba0b80f2 Minor wasm build simplifications and extend the JS bindings of sqlite3_column/value_text() such that they include embeded NUL bytes in their result strings rather than truncate them at NUL. Consolidate the shell.c build flags from the canonical and autoconf makefiles into the configure script.
FossilOrigin-Name: cee2e2576f5e91911a019bff025ee6071850c0d75941e8746f10d57b56bd830a
2025-11-04 22:01:55 +00:00
stephan b799156a31 Consolidate the three VFS-specific SEE tests into a shared routine.
FossilOrigin-Name: 8ac0bf125ddb6cc86a6825dcfe8895559835eca85ef14b5ad489f7c8159462e4
2025-11-04 01:03:58 +00:00
stephan 23e4ae2121 Move the hard-coded SHELL_OPT makefile values from the two main makefiles into their shared configure script.
FossilOrigin-Name: 900885c4fb3071e461bf868e9e68d0d8f3d3e83a1bcbf5c9c68179c701c1fb92
2025-11-04 00:15:51 +00:00
stephan abc23b5404 Merge trunk into wasm-post-3.51 to for some minor config script work.
FossilOrigin-Name: bf55a4220a74022e8be5f8a0cd7f4ca395a36e1666e14113e7e60c4a94cf0b3a
2025-11-04 00:10:10 +00:00
stephan e977440d79 Add tests demonstrating [d0e803b90344].
FossilOrigin-Name: 7d22ee947ddecb0dc6c640e79c9a09c0931f8b04f97d3ac89afdbf1736312bf7
2025-11-03 21:38:34 +00:00
stephan bb3b269ba9 Add new file missing from [936990cf067a5ebb] (and subsequently deleted by fossil clean -x). Have speedtest1 wasm use the user-provided sqlite3.c, rather than forcing the canonical one, so that the wasm exports don't have to be re-generated for that special case. Remove a harmless duplicate -D... flag.
FossilOrigin-Name: 7a592f5cd09699b45051855f6d477def40220b17642cbdb0f35ed74dd32becf1
2025-11-03 21:26:27 +00:00
stephan c129de05bb Simplify the EXPORTED_FUNCTIONS lists to use the preprocessor instead of per-list shell commands. (Unrelated) Remove part of the post-compilation JS filtering which breaks with emsdk 4.0.16+, which means the .js files are about 57kb bigger than they really ought to be.
FossilOrigin-Name: 936990cf067a5ebb34f7f662fc2d23d468c50f179afafe47fe0d2ed775f5ef74
2025-10-30 20:18:20 +00:00
stephan 6acd8d28fd Merge trunk into the wasm-post-3.51 branch.
FossilOrigin-Name: dda1735716cf1006b2a5d1d8eb29df3039047be38dcc04249c4ce50c77084fac
2025-10-30 19:32:46 +00:00
stephan bc5e0be7f8 A experiment addressing the embedded-NUL behavior of sqlite3_colum/value_text() in the JS bindings, as discussed in [forum:d77281aec2df9ada|forum post d77281aec2]. This is an experiment only. It works, in that existing tests do not see the difference, but it has implicications which require careful consideration before deploying.
FossilOrigin-Name: d0e803b90344ee972e4b3fb30b77e283599dc4d5c6a3335ce9fea653a1b3f6f0
2025-10-30 02:21:38 +00:00
stephan 241004f8fc Demonstrate the opfs-sahpool VFS with SEE.
FossilOrigin-Name: b4cffc00f3a18906867e8f070fbc49293ac5c038bad58e96ea74948591f31013
2025-10-26 21:45:02 +00:00
stephan 89a9efe840 Add a test which uses SEE via the "opfs" VFS. "opfs-sahpool" is pending.
FossilOrigin-Name: 1eb5a7ea394aa5b7e8594d73ce31f4b9bef55f2fa977dc26810c0bfba1cc39f7
2025-10-26 21:30:29 +00:00
stephan 4f177f1d3e Merge trunk into the wasm-post-3.51 branch.
FossilOrigin-Name: be5d2bae508a681628d4f84528e37db4e8a39b16e580b0d6ab4cd844566e973f
2025-10-26 18:43:04 +00:00
stephan 02c5f3976f Random tiny tweaks in internal JS and flesh out the tester1 test selection list to include both 32-/64-bit entries for all tester1XYZ.html combinations. For after the 3.51 release.
FossilOrigin-Name: c087a1d23deac84ac46e769332ec167c5b38fc8e525fd90484d3fa0b6d304ffa
2025-10-24 21:01:23 +00:00
50 changed files with 1119 additions and 671 deletions
+1
View File
@@ -1770,6 +1770,7 @@ SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_PERCENTILE=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_STMT_SCANSTATUS=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_STRICT_SUBTYPE=1
!ENDIF
-13
View File
@@ -117,19 +117,6 @@ sqlite_cfg.h: $(AS_AUTO_DEF)
# CFLAGS for sqlite3$(T.exe)
#
SHELL_OPT ?= @OPT_SHELL@
SHELL_OPT += -DSQLITE_DQS=0
SHELL_OPT += -DSQLITE_ENABLE_FTS4
#SHELL_OPT += -DSQLITE_ENABLE_FTS5
SHELL_OPT += -DSQLITE_ENABLE_RTREE
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
SHELL_OPT += -DSQLITE_ENABLE_PERCENTILE
SHELL_OPT += -DSQLITE_STRICT_SUBTYPE=1
#
# Library-level feature flags
+3 -2
View File
@@ -119,7 +119,7 @@ TCLLIBDIR = @TCLLIBDIR@
# typically come from the ./configure command-line invocation).
#
CFLAGS.configure = @SH_CFLAGS@ @TEAISH_CFLAGS@ @CFLAGS@ @CPPFLAGS@ $(TCL_INCLUDE_SPEC)
#CFLAGS.configure += -DUSE_TCL_STUBS=1
CFLAGS.configure += -DUSE_TCL_STUBS=@TEAISH_USE_STUBS@
#
# LDFLAGS.configure = LDFLAGS as known at configure-time.
@@ -153,6 +153,7 @@ tx.src = @TEAISH_EXT_SRC@
# gets set up via the configure script.
#
tx.CFLAGS =
tx.CPPFLAGS =
#
# tx.LDFLAGS is typically set by teaish.make, whereas TEAISH_LDFLAGS
@@ -218,7 +219,7 @@ config.log: @TEAISH_TEST_TCL_IN@
# CC variant for compiling Tcl-using sources.
#
CC.tcl = \
$(CC) -o $@ $(CFLAGS.configure) $(CFLAGS) $(tx.CFLAGS)
$(CC) -o $@ $(CFLAGS.configure) $(CFLAGS) $(tx.CFLAGS) $(tx.CPPFLAGS)
#
# CC variant for linking $(tx.src) into an extension DLL. Note that
+19 -1
View File
@@ -557,7 +557,25 @@ proc proc-debug {msg} {
}
define OPT_FEATURE_FLAGS {} ; # -DSQLITE_OMIT/ENABLE flags.
define OPT_SHELL {} ; # Feature-related CFLAGS for the sqlite3 CLI app
#
# OPT_SHELL = feature-related CFLAGS for the sqlite3 CLI app. The
# list's initial values are defaults which are always applied and not
# affected by --feature-flags. The list is appended to by various
# --feature-flags.
define OPT_SHELL {
-DSQLITE_DQS=0
-DSQLITE_ENABLE_FTS4
-DSQLITE_ENABLE_RTREE
-DSQLITE_ENABLE_EXPLAIN_COMMENTS
-DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
-DSQLITE_ENABLE_STMTVTAB
-DSQLITE_ENABLE_DBPAGE_VTAB
-DSQLITE_ENABLE_DBSTAT_VTAB
-DSQLITE_ENABLE_BYTECODE_VTAB
-DSQLITE_ENABLE_OFFSET_SQL_FUNC
-DSQLITE_ENABLE_PERCENTILE
-DSQLITE_STRICT_SUBTYPE=1
}
########################################################################
# Adds $args, if not empty, to OPT_FEATURE_FLAGS. If the first arg is
# -shell then it strips that arg and passes the remaining args the
+5 -1
View File
@@ -220,7 +220,9 @@ proc teaish-configure-core {} {
=> {Full pathname of tclsh to use. It is used for trying to find
tclConfig.sh. Warning: if its containing dir has multiple tclsh
versions, it may select the wrong tclConfig.sh!
Defaults to the $TCLSH environment variable.}
Defaults to the $TCLSH environment variable.}
tcl-stubs=0 => {Enable use of Tcl stubs library.}
# TEA has --with-tclinclude but it appears to only be useful for
# building an extension against an uninstalled copy of TCL's own
@@ -498,6 +500,8 @@ proc teaish__configure_phase1 {} {
}
teaish-checks-run -post
define TEAISH_USE_STUBS [opt-bool tcl-stubs]
apply {{} {
# Set up "vsatisfies" code for pkgIndex.tcl.in,
# _teaish.tester.tcl.in, and for a configure-time check. We would
+1
View File
@@ -160,6 +160,7 @@ static char *intckMprintf(sqlite3_intck *p, const char *zFmt, ...){
sqlite3_free(zRet);
zRet = 0;
}
va_end(ap);
return zRet;
}
+19 -16
View File
@@ -13,11 +13,14 @@ Technical support is available in the forum:
<https://sqlite.org/forum>
> **FOREWARNING:** this subproject is very much in development and
subject to any number of changes. Please do not rely on any
information about its API until this disclaimer is removed. The JNI
bindings released with version 3.43 are a "tech preview." Once
finalized, strong backward compatibility guarantees will apply.
> **FOREWARNING:** the JNI subproject is experimental and subject to
any number of changes. This API is "feature-complete", with only a
few difficult-to-reach corners of the C API not represented here,
but it is not a supported deliverable of the project so does not
have same backward compatibility guarantees which the C APIs
do. That said: the [C-style API](#1to1ish) is especially resistent
to compatibility breakage because it's designed to be as close to
the C API as feasible.
Project goals/requirements:
@@ -162,11 +165,13 @@ 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`.
parameters which should not be null, and it internally uses the
`SQLITE_API_ARMOR` mechanism to help product against such misuse. Some
C-style APIs explicitly accept `null` as a no-op for usability's sake,
and some of the JNI APIs deliberately return an error code, instead of
segfaulting, when passed a `null`. There are no known cases where it
will misuse memory if passed a `null` or out-of-range value from
client code.
Client-defined callbacks _must never throw exceptions_ unless _very
explicitly documented_ as being throw-safe. Exceptions are generally
@@ -194,7 +199,8 @@ Some constructs, when modelled 1-to-1 from C to Java, are unduly
clumsy to work with in Java because they try to shoehorn C's way of
doing certain things into Java's wildly different ways. The following
subsections cover those, starting with a verbose explanation and
demonstration of where such changes are "really necessary"...
demonstration of where such changes are "really necessary" for
usability's sake...
### Custom Collations
@@ -286,12 +292,9 @@ binding. The Java API has only one core function-registration function:
```java
int sqlite3_create_function(sqlite3 db, String funcName, int nArgs,
int encoding, SQLFunction func);
int flags, SQLFunction func);
```
> Design question: does the encoding argument serve any purpose in
Java? That's as-yet undetermined. If not, it will be removed.
`SQLFunction` is not used directly, but is instead instantiated via
one of its three subclasses:
@@ -313,4 +316,4 @@ in-flux nature of this API.
Various APIs which accept callbacks, e.g. `sqlite3_trace_v2()` and
`sqlite3_update_hook()`, use interfaces similar to those shown above.
Despite the changes in signature, the JNI layer makes every effort to
provide the same semantics as the C API documentation suggests.
provide the same semantics as the C API documentation describes.
+3 -1
View File
@@ -245,8 +245,10 @@ extern "C" {
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_USED_SHARED 11L
#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_SPILL
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_SPILL 12L
#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_TEMPBUF_SPILL
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_TEMPBUF_SPILL 13L
#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_MAX
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_MAX 12L
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_MAX 13L
#undef org_sqlite_jni_capi_CApi_SQLITE_UTF8
#define org_sqlite_jni_capi_CApi_SQLITE_UTF8 1L
#undef org_sqlite_jni_capi_CApi_SQLITE_UTF16LE
+5 -3
View File
@@ -115,8 +115,9 @@ public final class CApi {
JNIEnv is not cached, else returns true, but this information is
primarily for testing of the JNI bindings and is not information
which client-level code can use to make any informed
decisions. Its return type and semantics are not considered
stable and may change at any time.
decisions. The semantics of its return type and value are not
considered stable and may change at any time. i.e. act as if it
returns null.
*/
public static native boolean sqlite3_java_uncache_thread();
@@ -2585,7 +2586,8 @@ public final class CApi {
public static final int SQLITE_DBSTATUS_DEFERRED_FKS = 10;
public static final int SQLITE_DBSTATUS_CACHE_USED_SHARED = 11;
public static final int SQLITE_DBSTATUS_CACHE_SPILL = 12;
public static final int SQLITE_DBSTATUS_MAX = 12;
public static final int SQLITE_DBSTATUS_TEMPBUF_SPILL = 13;
public static final int SQLITE_DBSTATUS_MAX = 13;
// encodings
public static final int SQLITE_UTF8 = 1;
@@ -171,6 +171,7 @@ public final class Sqlite implements AutoCloseable {
public static final int DBSTATUS_DEFERRED_FKS = CApi.SQLITE_DBSTATUS_DEFERRED_FKS;
public static final int DBSTATUS_CACHE_USED_SHARED = CApi.SQLITE_DBSTATUS_CACHE_USED_SHARED;
public static final int DBSTATUS_CACHE_SPILL = CApi.SQLITE_DBSTATUS_CACHE_SPILL;
public static final int DBSTATUS_TEMPBUF_SPILL = CApi.SQLITE_DBSTATUS_TEMPBUF_SPILL;
// Limits
public static final int LIMIT_LENGTH = CApi.SQLITE_LIMIT_LENGTH;
-8
View File
@@ -1122,11 +1122,3 @@ int sqlite3_fileio_init(
}
return rc;
}
#if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
/* To allow a standalone DLL, make test_windirent.c use the same
* redefined SQLite API calls as the above extension code does.
* Just pull in this .c to accomplish this. As a beneficial side
* effect, this extension becomes a single translation unit. */
# include "test_windirent.c"
#endif
-10
View File
@@ -1,10 +0,0 @@
_fiddle_db_arg
_fiddle_db_filename
_fiddle_exec
_fiddle_experiment
_fiddle_interrupt
_fiddle_main
_fiddle_reset_db
_fiddle_db_handle
_fiddle_db_vfs
_fiddle_export_db
+18 -26
View File
@@ -249,9 +249,7 @@ c-pp.D.64bit = -Dbits64
# This is intended to be used in makefile targets which generate an
# Emscripten module and where $@ is the module's .js/.mjs file.
b.strip-js-emcc-bindings = \
sed -i -e '/^.*= \(_sqlite3\|_fiddle\)[^=]*=.*createExportWrapper/d' \
-e '/^var \(_sqlite3\|_fiddle\)[^=]*=.*makeInvalidEarlyAccess/d' $@ || exit; \
echo '$(1) $(emo.garbage) (Probably) /createExportWrapper()/d and /makeInvalidEarlyAccess()/d'
echo '$(1) $(emo.bug) (disabled because it breaks emsdk 4.0.16+)'
#
@@ -588,18 +586,16 @@ emcc_opt_full = $(emcc_opt) -g3
########################################################################
# EXPORTED_FUNCTIONS.* = files for use with Emscripten's
# -sEXPORTED_FUNCTION flag.
EXPORTED_FUNCTIONS.api.core = $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-core
EXPORTED_FUNCTIONS.api.in = $(EXPORTED_FUNCTIONS.api.core)
ifeq (1,$(SQLITE_C_IS_SEE))
EXPORTED_FUNCTIONS.api.in += $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-see
endif
ifeq (0,$(wasm-bare-bones))
EXPORTED_FUNCTIONS.api.in += $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-extras
endif
EXPORTED_FUNCTIONS.api.in = $(dir.api)/EXPORTED_FUNCTIONS.c-pp
EXPORTED_FUNCTIONS.api = $(dir.tmp)/EXPORTED_FUNCTIONS.api
$(EXPORTED_FUNCTIONS.api): $(EXPORTED_FUNCTIONS.api.in) $(sqlite3.c) $(MAKEFILE)
@$(call b.mkdir@)
cat $(EXPORTED_FUNCTIONS.api.in) > $@
EXPORTED_FUNCTIONS.c-pp.flags =
ifeq (1,$(wasm-bare-bones))
EXPORTED_FUNCTIONS.c-pp.flags += -Dbare-bones
endif
$(eval $(call b.c-pp.target,filter,\
$(EXPORTED_FUNCTIONS.api.in),\
$(EXPORTED_FUNCTIONS.api),\
$(EXPORTED_FUNCTIONS.c-pp.flags)))
########################################################################
# emcc flags for .c/.o/.wasm/.js.
@@ -853,8 +849,8 @@ sqlite3-api.jses += $(dir.api)/sqlite3-api-cleanup.js
sqlite3-license-version.js = $(dir.tmp)/sqlite3-license-version.js
$(sqlite3-license-version.js): $(bin.version-info) \
$(dir.api)/sqlite3-license-version-header.js
@echo '$(logtag.@) $(emo.disk)'; { \
$(call b.mkdir@); \
@echo '$(logtag.@) $(emo.disk)'; \
$(call b.mkdir@); { \
cat $(dir.api)/sqlite3-license-version-header.js || exit $$?; \
echo '/*'; \
echo '** This code was built from sqlite3 version...'; \
@@ -958,9 +954,10 @@ endif
########################################################################
EXPORTED_FUNCTIONS.fiddle = $(dir.tmp)/EXPORTED_FUNCTIONS.fiddle
$(EXPORTED_FUNCTIONS.fiddle): $(fiddle.EXPORTED_FUNCTIONS.in) $(MAKEFILE_LIST)
$(EXPORTED_FUNCTIONS.fiddle): $(EXPORTED_FUNCTIONS.api.in) $(MAKEFILE_LIST)
@$(b.mkdir@)
@sort -u $(fiddle.EXPORTED_FUNCTIONS.in) > $@
@$(call b.c-pp.shcmd,filter,$(EXPORTED_FUNCTIONS.api.in),\
$@,$(EXPORTED_FUNCTIONS.c-pp.flags) -Dfiddle)
@echo $(logtag.@) $(emo.disk)
emcc.flags.fiddle = \
@@ -993,7 +990,7 @@ clean-fiddle:
$(dir.fiddle)/*.wasm \
$(dir.fiddle)/sqlite3-opfs-*.js \
$(dir.fiddle)/*.gz \
EXPORTED_FUNCTIONS.fiddle
$(EXPORTED_FUNCTIONS.fiddle)
rm -fr $(dir.fiddle-debug)
emcc.flags.fiddle.debug = $(emcc.flags.fiddle) \
@@ -1001,11 +998,6 @@ emcc.flags.fiddle.debug = $(emcc.flags.fiddle) \
-DSQLITE_ENABLE_SELECTTRACE \
-DSQLITE_ENABLE_WHERETRACE
fiddle.EXPORTED_FUNCTIONS.in = \
EXPORTED_FUNCTIONS.fiddle.in \
$(dir.api)/EXPORTED_FUNCTIONS.sqlite3-core \
$(dir.api)/EXPORTED_FUNCTIONS.sqlite3-extras
fiddle.c.in = $(dir.top)/shell.c $(sqlite3-wasm.c)
#
@@ -1199,10 +1191,10 @@ speedtest1.exit-runtime1 = -sEXIT_RUNTIME=1
# -sEXIT_RUNTIME=1 but we need EXIT_RUNTIME=0 for the worker-based app
# which runs speedtest1 multiple times.
$(EXPORTED_FUNCTIONS.speedtest1): $(EXPORTED_FUNCTIONS.api.core)
$(EXPORTED_FUNCTIONS.speedtest1): $(EXPORTED_FUNCTIONS.api)
@$(call b.echo,@,$(emo.disk)); \
$(call b.mkdir@); \
{ echo _wasm_main; cat $(EXPORTED_FUNCTIONS.api.core); } > $@ || exit
{ echo _wasm_main; cat $(EXPORTED_FUNCTIONS.api); } > $@ || exit
speedtest1: b-speedtest1
#
@@ -155,3 +155,92 @@ _sqlite3_vtab_in_next
_sqlite3_vtab_nochange
_sqlite3_vtab_on_conflict
_sqlite3_vtab_rhs_value
//#if not bare-bones
_sqlite3_column_database_name
_sqlite3_column_origin_name
_sqlite3_column_table_name
_sqlite3_create_module
_sqlite3_create_module_v2
_sqlite3_create_window_function
_sqlite3_declare_vtab
_sqlite3_drop_modules
_sqlite3_preupdate_blobwrite
_sqlite3_preupdate_count
_sqlite3_preupdate_depth
_sqlite3_preupdate_hook
_sqlite3_preupdate_new
_sqlite3_preupdate_old
_sqlite3_progress_handler
_sqlite3_set_authorizer
_sqlite3_vtab_collation
_sqlite3_vtab_distinct
_sqlite3_vtab_in
_sqlite3_vtab_in_first
_sqlite3_vtab_in_next
_sqlite3_vtab_nochange
_sqlite3_vtab_on_conflict
_sqlite3_vtab_rhs_value
_sqlite3changegroup_add
_sqlite3changegroup_add_strm
_sqlite3changegroup_delete
_sqlite3changegroup_new
_sqlite3changegroup_output
_sqlite3changegroup_output_strm
_sqlite3changeset_apply
_sqlite3changeset_apply_strm
_sqlite3changeset_apply_v2
_sqlite3changeset_apply_v2_strm
_sqlite3changeset_apply_v3
_sqlite3changeset_apply_v3_strm
_sqlite3changeset_concat
_sqlite3changeset_concat_strm
_sqlite3changeset_conflict
_sqlite3changeset_finalize
_sqlite3changeset_fk_conflicts
_sqlite3changeset_invert
_sqlite3changeset_invert_strm
_sqlite3changeset_new
_sqlite3changeset_next
_sqlite3changeset_old
_sqlite3changeset_op
_sqlite3changeset_pk
_sqlite3changeset_start
_sqlite3changeset_start_strm
_sqlite3changeset_start_v2
_sqlite3changeset_start_v2_strm
_sqlite3session_attach
_sqlite3session_changeset
_sqlite3session_changeset_size
_sqlite3session_changeset_strm
_sqlite3session_config
_sqlite3session_create
_sqlite3session_delete
_sqlite3session_diff
_sqlite3session_enable
_sqlite3session_indirect
_sqlite3session_isempty
_sqlite3session_memory_used
_sqlite3session_object_config
_sqlite3session_patchset
_sqlite3session_patchset_strm
_sqlite3session_table_filter
//#endif not bare-bones
//#if enable-see
_sqlite3_key
_sqlite3_key_v2
_sqlite3_rekey
_sqlite3_rekey_v2
_sqlite3_activate_see
//#endif enable-see
//#if fiddle
_fiddle_db_arg
_fiddle_db_filename
_fiddle_exec
_fiddle_experiment
_fiddle_interrupt
_fiddle_main
_fiddle_reset_db
_fiddle_db_handle
_fiddle_db_vfs
_fiddle_export_db
//#endif fiddle
@@ -1,68 +0,0 @@
_sqlite3_column_database_name
_sqlite3_column_origin_name
_sqlite3_column_table_name
_sqlite3_create_module
_sqlite3_create_module_v2
_sqlite3_create_window_function
_sqlite3_declare_vtab
_sqlite3_drop_modules
_sqlite3_preupdate_blobwrite
_sqlite3_preupdate_count
_sqlite3_preupdate_depth
_sqlite3_preupdate_hook
_sqlite3_preupdate_new
_sqlite3_preupdate_old
_sqlite3_progress_handler
_sqlite3_set_authorizer
_sqlite3_vtab_collation
_sqlite3_vtab_distinct
_sqlite3_vtab_in
_sqlite3_vtab_in_first
_sqlite3_vtab_in_next
_sqlite3_vtab_nochange
_sqlite3_vtab_on_conflict
_sqlite3_vtab_rhs_value
_sqlite3changegroup_add
_sqlite3changegroup_add_strm
_sqlite3changegroup_delete
_sqlite3changegroup_new
_sqlite3changegroup_output
_sqlite3changegroup_output_strm
_sqlite3changeset_apply
_sqlite3changeset_apply_strm
_sqlite3changeset_apply_v2
_sqlite3changeset_apply_v2_strm
_sqlite3changeset_apply_v3
_sqlite3changeset_apply_v3_strm
_sqlite3changeset_concat
_sqlite3changeset_concat_strm
_sqlite3changeset_conflict
_sqlite3changeset_finalize
_sqlite3changeset_fk_conflicts
_sqlite3changeset_invert
_sqlite3changeset_invert_strm
_sqlite3changeset_new
_sqlite3changeset_next
_sqlite3changeset_old
_sqlite3changeset_op
_sqlite3changeset_pk
_sqlite3changeset_start
_sqlite3changeset_start_strm
_sqlite3changeset_start_v2
_sqlite3changeset_start_v2_strm
_sqlite3session_attach
_sqlite3session_changeset
_sqlite3session_changeset_size
_sqlite3session_changeset_strm
_sqlite3session_config
_sqlite3session_create
_sqlite3session_delete
_sqlite3session_diff
_sqlite3session_enable
_sqlite3session_indirect
_sqlite3session_isempty
_sqlite3session_memory_used
_sqlite3session_object_config
_sqlite3session_patchset
_sqlite3session_patchset_strm
_sqlite3session_table_filter
@@ -1,5 +0,0 @@
_sqlite3_key
_sqlite3_key_v2
_sqlite3_rekey
_sqlite3_rekey_v2
_sqlite3_activate_see
@@ -1,3 +0,0 @@
FS
wasmMemory
+4 -3
View File
@@ -23,7 +23,7 @@ this writing, but is not set in stone forever and may change at any
time. This doc targets maintainers of this code and those wanting to
dive in to the details, not end user.
First off, a pikchr of the proverbial onion:
First off, a [pikchr][] of the proverbial onion:
```pikchr toggle center
scale = 0.85
@@ -205,9 +205,10 @@ Preprocessing of Source Files
Certain files in the build require preprocessing to filter in/out
parts which differ between vanilla JS, ES6 Modules, and node.js
builds. The preprocessor application itself is in
[`c-pp.c`](/file/ext/wasm/c-pp.c) and the complete technical details
of such preprocessing are maintained in
[`c-pp-lite.c`](/file/ext/wasm/c-pp-lite.c) and the complete technical
details of such preprocessing are maintained in
[`GNUMakefile`](/file/ext/wasm/GNUmakefile).
[OPFS]: https://developer.mozilla.org/en-US/docs/Web/API/File_System_API/Origin_private_file_system
[pikchr]: https://pikchr.org
+1 -1
View File
@@ -26,7 +26,7 @@ const toExportForESM =
*/
const originalInit = sqlite3InitModule;
if(!originalInit){
throw new Error("Expecting globalThis.sqlite3InitModule to be defined by the Emscripten build.");
throw new Error("Expecting sqlite3InitModule to be defined by the Emscripten build.");
}
/**
We need to add some state which our custom Module.locateFile()
+17
View File
@@ -14,6 +14,23 @@
itself. i.e. try to keep file-local symbol names obnoxiously
collision-resistant.
*/
/**
This file was preprocessed using:
//#@policy error
@c-pp::ARGV@
//#@policy off
*/
//#if unsupported-build
/**
UNSUPPORTED BUILD:
This SQLite JS build configuration is entirely unsupported! It has
not been tested beyond the ability to compile it. It may not
load. It may not work properly. Only builds targeting browser
environments are supported and tested.
*/
//#endif
(function(Module){
const sIMS =
globalThis.sqlite3InitModuleState/*from extern-post-js.c-pp.js*/
+1 -6
View File
@@ -55,12 +55,7 @@ try{
}
);
/** Figure out if this is a 32- or 64-bit WASM build. */
bootstrapConfig.wasmPtrIR =
'number'===(typeof bootstrapConfig.exports.sqlite3_libversion())
? 'i32' :'i64';
const sIMS = sqlite3InitScriptInfo;
sIMS.debugModule("Bootstrapping lib config", sIMS);
sqlite3InitScriptInfo.debugModule("Bootstrapping lib config", bootstrapConfig);
/**
For purposes of the Emscripten build, call sqlite3ApiBootstrap().
+47 -1
View File
@@ -120,7 +120,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
["sqlite3_column_double","f64", "sqlite3_stmt*", "int"],
["sqlite3_column_int","int", "sqlite3_stmt*", "int"],
["sqlite3_column_name","string", "sqlite3_stmt*", "int"],
//#define proxy-text-apis=1
//#if not proxy-text-apis
/* Search this file for tag:proxy-text-apis to see what this is about. */
["sqlite3_column_text","string", "sqlite3_stmt*", "int"],
//#endif
["sqlite3_column_type","int", "sqlite3_stmt*", "int"],
["sqlite3_column_value","sqlite3_value*", "sqlite3_stmt*", "int"],
["sqlite3_commit_hook", "void*", [
@@ -317,7 +321,9 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
["sqlite3_value_numeric_type", "int", "sqlite3_value*"],
["sqlite3_value_pointer", "*", "sqlite3_value*", "string:static"],
["sqlite3_value_subtype", "int", "sqlite3_value*"],
//#if not proxy-text-apis
["sqlite3_value_text", "string", "sqlite3_value*"],
//#endif
["sqlite3_value_type", "int", "sqlite3_value*"],
["sqlite3_vfs_find", "*", "string"],
["sqlite3_vfs_register", "int", "sqlite3_vfs*", "int"],
@@ -1654,6 +1660,45 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}/*sqlite3_bind_text/blob()*/
//#if proxy-text-apis
if(!capi.sqlite3_column_text){
/*[tag:proxy-text-apis]
As discussed at:
https://sqlite.org/forum/forumpost/d77281aec2df9ada
Summary: there are opinions that sqlite3_column_text() and
sqlite3_value_text() should handle strings such that embedded
NULs are retained. This block does that. This block does _not_
apply that special-case behavior to any number of _other_
APIs which return C-strings. That discrepancy makes this
block highly arguable, but one can also argue that these two
specific functions can get away with such acrobatics without
it being called voodoo in a pejorative sense.
*/
const argStmt = wasm.xWrap.argAdapter('sqlite3_stmt*'),
argInt = wasm.xWrap.argAdapter('int'),
argValue = wasm.xWrap.argAdapter('sqlite3_value*'),
newStr =
(cstr,n)=>wasm.typedArrayToString(wasm.heap8u(),
Number(cstr), Number(cstr)+n)
capi.sqlite3_column_text = function(stmt, colIndex){
const a0 = argStmt(stmt), a1 = argInt(colIndex);
const cstr = wasm.exports.sqlite3_column_text(a0, a1);
return cstr
? newStr(cstr,wasm.exports.sqlite3_column_bytes(a0, a1))
: null;
};
capi.sqlite3_value_text = function(val){
const a0 = argValue(val);
const cstr = wasm.exports.sqlite3_value_text(a0);
return cstr
? newStr(cstr,wasm.exports.sqlite3_value_bytes(a0))
: null;
};
}/*text-return-related bindings*/
//#endif proxy-text-apis
{/* sqlite3_config() */
/**
Wraps a small subset of the C API's sqlite3_config() options.
@@ -1836,6 +1881,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
for anything other than local/sessionStorage. It "can"
be used that way but it's not really intended to be. */
capi.sqlite3_vfs_unregister(pKvvfs);
delete capi.sqlite3_kvvfs_methods;
}
}/*pKvvfs*/
@@ -1944,7 +1990,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}
tgt[memKey] = fProxy;
}else{
const pFunc = wasm.installFunction(fProxy, tgt.memberSignature(name));
const pFunc = wasm.installFunction(fProxy, sigN);
tgt[memKey] = pFunc;
if(!tgt.ondispose || !tgt.ondispose.__removeFuncList){
tgt.addOnDispose('ondispose.__removeFuncList handler',
+27 -18
View File
@@ -799,22 +799,6 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
environment via whwashutil.js.
*/
Object.assign(wasm, {
/**
The WASM IR (Intermediate Representation) value for
pointer-type values. If set then it MUST be one of 'i32' or
'i64' (else an exception will be thrown). If it's not set, it
will default to 'i32'.
*/
pointerIR: config.wasmPtrIR,
/**
True if BigInt support was enabled via (e.g.) the
Emscripten -sWASM_BIGINT flag, else false. When
enabled, certain 64-bit sqlite3 APIs are enabled which
are not otherwise enabled due to JS/WASM int64
impedance mismatches.
*/
bigIntEnabled: !!config.bigIntEnabled,
/**
The symbols exported by the WASM environment.
@@ -834,6 +818,29 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
"in either config.exports.memory (exported)",
"or config.memory (imported)."),
/**
The WASM pointer size. If set then it MUST be one of 4 or 8 and
it MUST correspond to the WASM environment's pointer size. We
figure out the size by calling some un-JS-wrapped WASM function
which returns a pointer-type value. If that value is a BigInt,
it's 64-bit, else it's 32-bit. The pieces which populate
sqlite3.wasm (whwasmutil.js) can figure this out _if_ they can
allocate, but we have a chicken/egg situation there which makes
it illegal for that code to invoke wasm.dealloc() at the time
it would be needed. So we need to configure it ahead of time
(here) instead.
*/
pointerSize: ('number'===typeof config.exports.sqlite3_libversion()) ? 4 : 8,
/**
True if BigInt support was enabled via (e.g.) the
Emscripten -sWASM_BIGINT flag, else false. When
enabled, certain 64-bit sqlite3 APIs are enabled which
are not otherwise enabled due to JS/WASM int64
impedance mismatches.
*/
bigIntEnabled: !!config.bigIntEnabled,
/**
WebAssembly.Table object holding the indirect function call
table. Defaults to exports.__indirect_function_table.
@@ -921,9 +928,11 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
srcTypedArray = new Uint8Array(srcTypedArray);
}
affirmBindableTypedArray(srcTypedArray);
const heap = wasm.heapForSize(srcTypedArray.constructor);
const pRet = wasm.alloc(srcTypedArray.byteLength || 1);
heap.set(srcTypedArray.byteLength ? srcTypedArray : [0], Number(pRet));
wasm.heapForSize(srcTypedArray.constructor)
.set(srcTypedArray.byteLength ? srcTypedArray : [0], Number(pRet))
/* Maintenance note: the order of alloc() and heapForSize() calls
is significant: https://sqlite.org/forum/forumpost/05b77273be104532 */;
return pRet;
};
+1 -1
View File
@@ -326,7 +326,7 @@ SQLITE_WASM_EXPORT void * sqlite3__wasm_pstack_ptr(void){
*/
SQLITE_WASM_EXPORT void sqlite3__wasm_pstack_restore(unsigned char * p){
assert(p>=PStack.pBegin && p<=PStack.pEnd && p>=PStack.pPos);
assert(0==((unsigned long long)p & 0x7));
assert(0==((unsigned long long)p & 0x7) /* 8-byte aligned */);
if(p>=PStack.pBegin && p<=PStack.pEnd /*&& p>=PStack.pPos*/){
PStack.pPos = p;
}
+16 -1
View File
@@ -970,7 +970,6 @@ void db_prepare(sqlite3_stmt **pStmt, const char * zSql, ...){
char * z = 0;
int n = 0;
va_list va;
if(!str) fatal("sqlite3_str_new() failed");
va_start(va, zSql);
sqlite3_str_vappendf(str, zSql, va);
va_end(va);
@@ -2580,6 +2579,21 @@ static int arg_is_flag( char const *zFlag, char const *zArg,
return 0;
}
static void define_argv(int argc, char const * const * argv){
sqlite3_str * const s = sqlite3_str_new(g.db);
sqlite3_str_append(s, "c-pp::ARGV=", 11);
for( int i = 0; i < argc; ++i ){
if( i ) sqlite3_str_appendchar(s, 1, ' ');
sqlite3_str_appendf(s, "%s", argv[i]);
}
char * const z = sqlite3_str_finish(s);
assert(z);
if(z){
db_define_add(z, NULL);
sqlite3_free(z);
}
}
int main(int argc, char const * const * argv){
int rc = 0;
int inclCount = 0;
@@ -2617,6 +2631,7 @@ int main(int argc, char const * const * argv){
g.sqlTrace.expandSql = expandMode;
}
cmpp_initdb();
define_argv(argc, argv);
}
for(int i = 1; i < argc; ++i){
int negate = 0;
+10 -2
View File
@@ -227,6 +227,14 @@ globalThis.WhWasmUtilInstaller = function(target){
all args with a space between each. */
const toss = (...args)=>{throw new Error(args.join(' '))};
if( !target.pointerSize && !target.pointerIR
&& target.alloc && target.dealloc ){
/* Try to determine the pointer size by allocating. */
const ptr = target.alloc(1);
target.pointerSize = ('bigint'===typeof ptr ? 8 : 4);
target.dealloc(ptr);
}
/**
As of 2025-09-21, this library works with 64-bit WASM modules
built with Emscripten's -sMEMORY64=1.
@@ -996,12 +1004,12 @@ globalThis.WhWasmUtilInstaller = function(target){
target.heap8u().
*/
target.cstrlen = function(ptr){
if(!ptr || !target.isPtr(ptr)) return null;
if(!ptr || !target.isPtr/*64*/(ptr)) return null;
ptr = Number(ptr) /*tag:64bit*/;
const h = heapWrappers().HEAP8U;
let pos = ptr;
for( ; h[pos] !== 0; ++pos ){}
return Number(pos - ptr);
return pos - ptr;
};
/** Internal helper to use in operations which need to distinguish
+365 -96
View File
@@ -32,7 +32,7 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
if(!(config.heap instanceof WebAssembly.Memory)
&& !(config.heap instanceof Function)){
toss("config.heap must be WebAssembly.Memory instance or a function.");
toss("config.heap must be WebAssembly.Memory instance or a function which returns one.");
}
['alloc','dealloc'].forEach(function(k){
(config[k] instanceof Function) ||
@@ -48,14 +48,19 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
memberSuffix = (config.memberSuffix || ""),
BigInt = globalThis['BigInt'],
BigInt64Array = globalThis['BigInt64Array'],
bigIntEnabled = config.bigIntEnabled ?? !!BigInt64Array,
ptrIR = config.pointerIR
|| config.ptrIR/*deprecated*/
|| 'i32',
/* Undocumented (on purpose) config options: */
ptrSize = config.ptrSize/*deprecated*/
|| ('i32'===ptrIR ? 4 : 8)
;
bigIntEnabled = config.bigIntEnabled ?? !!BigInt64Array;
//console.warn("config",config);
let ptr = alloc(1);
const ptrIR = config.pointerIR
|| config.ptrIR/*deprecated*/
|| ('bigint'===typeof ptr ? 'i64' : 'i32');
/* Undocumented (on purpose) config options: */
const ptrSize = config.ptrSize/*deprecated*/
|| ('i32'===ptrIR ? 4 : 8);
dealloc(ptr);
ptr = undefined;
//console.warn("ptrIR =",ptrIR,"ptrSize =",ptrSize);
if(ptrIR!=='i32' && ptrIR!=='i64') toss("Invalid pointer representation:",ptrIR);
if(ptrSize!==4 && ptrSize!==8) toss("Invalid pointer size:",ptrSize);
@@ -136,11 +141,11 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
/** True if SIG s looks like a function signature, else
false. */
const isFuncSig = (s)=>'('===s[1];
/** True if SIG s is-a pointer signature. */
const isPtrSig = (s)=>'p'===s || 'P'===s;
/** True if SIG s is-a pointer-type signature. */
const isPtrSig = (s)=>'p'===s || 'P'===s || 's'===s;
const isAutoPtrSig = (s)=>'P'===s /*EXPERIMENTAL*/;
/** Returns p if SIG s is a function SIG, else returns s[0]. */
const sigLetter = (s)=>isFuncSig(s) ? 'p' : s[0];
const sigLetter = (s)=>s ? (isFuncSig(s) ? 'p' : s[0]) : undefined;
/** Returns the WASM IR form of the Emscripten-conventional letter
at SIG s[0]. Throws for an unknown SIG. */
const sigIR = function(s){
@@ -154,6 +159,19 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
}
toss("Unhandled signature IR:",s);
};
/** Returns the WASM sizeof of the Emscripten-conventional letter
at SIG s[0]. Throws for an unknown SIG. */
const sigSize = function(s){
switch(sigLetter(s)){
case 'c': case 'C': return 1;
case 'i': return 4;
case 'p': case 'P': case 's': return ptrSize;
case 'j': return 8;
case 'f': return 4;
case 'd': return 8;
}
toss("Unhandled signature sizeof:",s);
};
const affirmBigIntArray = BigInt64Array
? ()=>true : ()=>toss('BigInt64Array is not available.');
@@ -232,11 +250,22 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
accessible via boundObject.pointer, which is gated behind a
property interceptor, but are not exposed anywhere else in the
object.
This approach means we cannot proxy arrays, or any type which
might be realloced, as that pointer could change out from under
us. That's not an issue for nested structs, but it might be for a
struct they're embedded in. In the case of nested structs we
"could" record their top-most parent object and their offset into
that object, instead of storing the pointer itself. We could that
by allowing a function instead of a pointer in this map, that
function returning the (lazily-calculated) address. Hmm.
*/
const __instancePointerMap = new WeakMap();
const getInstancePtr = (obj)=>__instancePointerMap.get(obj);
/** Property name for the pointer-is-external marker. */
const xPtrPropName = '(pointer-is-external)';
const xPtrPropName = Symbol('(pointer-is-external)');
const __isPtr32 = (ptr)=>('number'===typeof ptr && (ptr===(ptr|0)) && ptr>=0);
const __isPtr64 = (ptr)=>(
@@ -252,7 +281,7 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
/** Frees the obj.pointer memory and clears the pointer
property. */
const __freeStruct = function(ctor, obj, m){
if(!m) m = __instancePointerMap.get(obj);
if(!m) m = getInstancePtr(obj);
if(m) {
__instancePointerMap.delete(obj);
if(Array.isArray(obj.ondispose)){
@@ -283,7 +312,12 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
ctor.structName,"instance:",
ctor.structInfo.sizeof,"bytes @"+m);
}
if(!obj[xPtrPropName]) dealloc(m);
if(!obj[xPtrPropName]){
if( ctor.structInfo.zeroOnFree ){
heap().fill(0, Number(m), Number(m)+ctor.structInfo.sizeof);
}
dealloc(m);
}
}
};
@@ -324,8 +358,69 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
: null;
};
/** True if sig looks like an emscripten/jaccwabyt
type signature, else false. */
const looksLikeASig = function f(sig){
f.rxSig1 ??= /^[ipPsjfdcC]$/;
f.rxSig2 ??= /^[vipPsjfdcC]\([ipPsjfdcC]*\)$/;
return f.rxSig1.test(sig) || f.rxSig2.test(sig);
};
/** Returns a pair of adaptor maps (objects) in a length-3
array specific to the given object. */
const __adaptorsFor = function(who){
let x = this.get(who);
if( !x ){
x = [ Object.create(null), Object.create(null), Object.create(null) ];
this.set(who, x);
}
return x;
}.bind(new WeakMap);
/** Code de-duplifier for __adaptGet(), __adaptSet(), and
__adaptStruct(). */
const __adaptor = function(who, which, key, proxy){
const a = __adaptorsFor(who)[which];
if(3===arguments.length) return a[key];
if( proxy ) return a[key] = proxy;
return delete a[key];
};
const noopAdapter = (x)=>x;
// StructBinder::adaptGet()
const __adaptGet = function(key, ...args){
/*if( looksLikeASig(key) ){
toss("Getter adaptor's name (",key,") collides with a data type signature.");
}*/
return __adaptor(this, 0, key, ...args);
};
// StructBinder::adaptSet()
const __adaptSet = function(key, ...args){
if( looksLikeASig(key) ){
toss("Setter adaptor's name (",key,") collides with a data type signature.");
}
return __adaptor(this, 1, key, ...args);
};
// StructBinder::adaptStruct()
const __adaptStruct = function(key, ...args){
return __adaptor(this, 2, key, ...args);
};
const __adaptStruct2 = function(who,key){
const si = ('string'===typeof key)
? __adaptor(who, 2, key) : key;
if( 'object'!==typeof si ){
toss("Invalid struct mapping object. Arg =",key,JSON.stringify(si));
}
return si;
};
const __memberKey = (k)=>memberPrefix + k + memberSuffix;
const __memberKeyProp = rop(__memberKey);
//const __adaptGetProp = rop(__adaptGet);
/**
Looks up a struct member in structInfo.members. Throws if found
@@ -342,7 +437,8 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
if(v.key===memberName){ m = v; break; }
}
if(!m && tossIfNotFound){
toss(sPropName(structInfo.name,memberName),'is not a mapped struct member.');
toss(sPropName(structInfo.name || structInfo.structName, memberName),
'is not a mapped struct member.');
}
}
return m;
@@ -361,7 +457,7 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
const __ptrPropDescriptor = {
configurable: false, enumerable: false,
get: function(){return __instancePointerMap.get(this)},
get: function(){return getInstancePtr(this)},
set: ()=>toss("Cannot assign the 'pointer' property of a struct.")
// Reminder: leaving `set` undefined makes assignments
// to the property _silently_ do nothing. Current unit tests
@@ -558,78 +654,176 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
});
/**
Pass this a StructBinder-generated prototype, and the struct
member description object. It will define property accessors for
proto[memberKey] which read from/write to memory in
this.pointer. It modifies descr to make certain downstream
operations much simpler.
If struct description object si has a getter proxy, return it (a
function), else return undefined.
*/
const makeMemberWrapper = function f(ctor,name, descr){
const memberGetterProxy = function(si){
return si.get || (si.adaptGet
? StructBinder.adaptGet(si.adaptGet)
: undefined);
};
/**
If struct description object si has a setter proxy, return it (a
function), else return undefined.
*/
const memberSetterProxy = function(si){
return si.set || (si.adaptSet
? StructBinder.adaptSet(si.adaptSet)
: undefined);
};
/**
To be called by makeMemberWrapper() when si has a 'members'
member, i.e. is an embedded struct. This function sets up that
struct like any other and also sets up property accessor for
ctor.memberKey(name) which returns an instance of that new
StructType when the member is accessed. That instance wraps the
memory of the member's part of the containing C struct instance.
That is, if struct Foo has member bar which is an inner struct
then:
const f = new Foo;
const b = f.bar;
assert( b is-a StructType object );
assert( b.pointer === f.b.pointer );
b will be disposed of when f() is. Calling b.dispose() will not
do any permanent harm, as the wrapper object will be recreated
when accessing f.bar, pointing to the same memory in f.
The si.zeroOnFree flag has no effect on embedded structs because
they wrap "external" memory, so do not own it, and are thus never
freed, as such.
*/
const makeMemberStructWrapper = function callee(ctor, name, si){
/**
Where we store inner-struct member proxies. Keys are a
combination of the parent object's pointer address and the
property's name. The values are StructType instances.
*/
const __innerStructs = (callee.innerStructs ??= new Map());
const key = ctor.memberKey(name);
if( undefined!==si.signature ){
toss("'signature' cannot be used on an embedded struct (",
ctor.structName,".",key,").");
}
if( memberSetterProxy(si) ){
toss("'set' and 'adaptSet' are not permitted for nested struct members.");
}
//console.warn("si =",ctor.structName, name, JSON.stringify(si,' '));
si.structName ??= ctor.structName+'::'+name;
si.key = key;
si.name = name;
si.constructor = this.call(this, si.structName, si);
//console.warn("si.constructor =",si.constructor);
//console.warn("si =",si,"ctor=",ctor);
const getterProxy = memberGetterProxy(si);
const prop = Object.assign(Object.create(null),{
configurable: false,
enumerable: false,
set: __propThrowOnSet(ctor/*not si.constructor*/.structName, key),
get: function(){
const dbg = si.constructor.prototype.debugFlags.__flags;
const p = this.pointer;
const k = p+'.'+key;
let s = __innerStructs.get(k);
if(dbg.getter){ log("debug.getter: k =",k); }
if( !s ){
s = new si.constructor(__ptrAdd(p, si.offset));
__innerStructs.set(k, s);
this.addOnDispose(()=>s.dispose());
s.addOnDispose(()=>__innerStructs.delete(k));
//console.warn("Created",k,"proxy");
}
if(getterProxy) s = getterProxy.apply(this,[s,key]);
if(dbg.getter) log("debug.getter: result =",s);
return s;
}
});
Object.defineProperty(ctor.prototype, key, prop);
}/*makeMemberStructWrapper()*/;
/**
Pass this a StructBinderImpl-generated constructor, a member
property name, and the struct member description object. It will
define property accessors for proto[memberKey] which read
from/write to memory in this.pointer. It modifies si to make
certain downstream operations simpler.
*/
const makeMemberWrapper = function f(ctor, name, si){
si = __adaptStruct2(this, si);
if( si.members ){
return makeMemberStructWrapper.call(this, ctor, name, si);
}
if(!f._){
/*cache all available getters/setters/set-wrappers for
direct reuse in each accessor function. */
/* Cache all available getters/setters/set-wrappers for
direct reuse in each accessor function. */
f._ = {getters: {}, setters: {}, sw:{}};
const a = ['i','c','C','p','P','s','f','d','v()'];
if(bigIntEnabled) a.push('j');
a.forEach(function(v){
//const ir = sigIR(v);
f._.getters[v] = sigDVGetter(v) /* DataView[MethodName] values for GETTERS */;
f._.setters[v] = sigDVSetter(v) /* DataView[MethodName] values for SETTERS */;
f._.sw[v] = sigDVSetWrapper(v) /* BigInt or Number ctor to wrap around values
for conversion */;
});
const rxSig1 = /^[ipPsjfdcC]$/,
rxSig2 = /^[vipPsjfdcC]\([ipPsjfdcC]*\)$/;
f.sigCheck = function(obj, name, key,sig){
if(Object.prototype.hasOwnProperty.call(obj, key)){
toss(obj.structName,'already has a property named',key+'.');
}
rxSig1.test(sig) || rxSig2.test(sig)
looksLikeASig(sig)
|| toss("Malformed signature for",
sPropName(obj.structName,name)+":",sig);
};
}
const key = ctor.memberKey(name);
f.sigCheck(ctor.prototype, name, key, descr.signature);
descr.key = key;
descr.name = name;
const sigGlyph = sigLetter(descr.signature);
f.sigCheck(ctor.prototype, name, key, si.signature);
si.key = key;
si.name = name;
const sigGlyph = sigLetter(si.signature);
const xPropName = sPropName(ctor.prototype.structName,key);
const dbg = ctor.prototype.debugFlags.__flags;
/*
TODO?: set prototype of descr to an object which can set/fetch
TODO?: set prototype of si to an object which can set/fetch
its preferred representation, e.g. conversion to string or mapped
function. Advantage: we can avoid doing that via if/else if/else
in the get/set methods.
*/
const getterProxy = memberGetterProxy(si);
const prop = Object.create(null);
prop.configurable = false;
prop.enumerable = false;
prop.get = function(){
if(dbg.getter){
log("debug.getter:",f._.getters[sigGlyph],"for", sigIR(sigGlyph),
xPropName,'@', this.pointer,'+',descr.offset,'sz',descr.sizeof);
xPropName,'@', this.pointer,'+',si.offset,'sz',si.sizeof);
}
let rc = (
new DataView(heap().buffer, Number(this.pointer) + descr.offset, descr.sizeof)
new DataView(heap().buffer, Number(this.pointer) + si.offset, si.sizeof)
)[f._.getters[sigGlyph]](0, isLittleEndian);
if(getterProxy) rc = getterProxy.apply(this,[rc,key]);
if(dbg.getter) log("debug.getter:",xPropName,"result =",rc);
return rc;
};
if(descr.readOnly){
if(si.readOnly){
prop.set = __propThrowOnSet(ctor.prototype.structName,key);
}else{
const setterProxy = memberSetterProxy(si);
prop.set = function(v){
if(dbg.setter){
log("debug.setter:",f._.setters[sigGlyph],"for", sigIR(sigGlyph),
xPropName,'@', this.pointer,'+',descr.offset,'sz',descr.sizeof, v);
xPropName,'@', this.pointer,'+',si.offset,'sz',si.sizeof, v);
}
if(!this.pointer){
toss("Cannot set struct property on disposed instance.");
toss("Cannot set native property on a disposed struct instance.");
}
if(null===v) v = __NullPtr;
else while(!__isPtr(v)){
if(isAutoPtrSig(descr.signature) && (v instanceof StructType)){
if( setterProxy ) v = setterProxy.apply(this,[v]);
if( null===v || undefined===v ) v = __NullPtr;
else while( isPtrSig(si.signature) && !__isPtr(v) ){
if(isAutoPtrSig(si.signature) && (v instanceof StructType)){
// It's a struct instance: let's store its pointer value!
v = v.pointer || __NullPtr;
if(dbg.setter) log("debug.setter:",xPropName,"resolved to",v);
@@ -638,66 +832,45 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
toss("Invalid value for pointer-type",xPropName+'.');
}
(
new DataView(heap().buffer, Number(this.pointer) + descr.offset,
descr.sizeof)
new DataView(heap().buffer, Number(this.pointer) + si.offset,
si.sizeof)
)[f._.setters[sigGlyph]](0, f._.sw[sigGlyph](v), isLittleEndian);
};
}
Object.defineProperty(ctor.prototype, key, prop);
}/*makeMemberWrapper*/;
}/*makeMemberWrapper()*/;
/**
The main factory function which will be returned to the
caller.
caller. The third argument is structly for internal use.
This level of indirection is to avoid that clients can pass a
third argument to this, as that's only for internal use.
internalOpt options:
- None right now. This is for potential use in recursion.
Usages:
StructBinder(string, obj [,optObj]);
StructBinder(obj);
*/
const StructBinder = function StructBinder(structName, structInfo){
if(1===arguments.length){
structInfo = structName;
structName = structInfo.name;
}else if(!structInfo.name){
structInfo.name = structName;
}
if(!structName) toss("Struct name is required.");
let lastMember = false;
Object.keys(structInfo.members).forEach((k)=>{
// Sanity checks of sizeof/offset info...
const m = structInfo.members[k];
if(!m.sizeof) toss(structName,"member",k,"is missing sizeof.");
else if(m.sizeof===1){
(m.signature === 'c' || m.signature === 'C') ||
toss("Unexpected sizeof==1 member",
sPropName(structInfo.name,k),
"with signature",m.signature);
}else{
// sizes and offsets of size-1 members may be odd values, but
// others may not.
if(0!==(m.sizeof%4)){
console.warn("Invalid struct member description =",m,"from",structInfo);
toss(structName,"member",k,"sizeof is not aligned. sizeof="+m.sizeof);
}
if(0!==(m.offset%4)){
console.warn("Invalid struct member description =",m,"from",structInfo);
toss(structName,"member",k,"offset is not aligned. offset="+m.offset);
}
}
if(!lastMember || lastMember.offset < m.offset) lastMember = m;
});
if(!lastMember) toss("No member property descriptions found.");
else if(structInfo.sizeof < lastMember.offset+lastMember.sizeof){
toss("Invalid struct config:",structName,
"max member offset ("+lastMember.offset+") ",
"extends past end of struct (sizeof="+structInfo.sizeof+").");
}
const debugFlags = rop(SBF.__makeDebugFlags(StructBinder.debugFlags));
/** Constructor for the StructCtor. */
const zeroAsPtr = __asPtrType(0);
const StructBinderImpl = function StructBinderImpl(
structName, si, opt = Object.create(null)
){
/**
StructCtor is the eventual return value of this function. We
need to populate this early on so that we can do some trickery
in feeding it through recursion.
*/
const StructCtor = function StructCtor(externalMemory){
externalMemory = __asPtrType(externalMemory);
//console.warn("externalMemory",externalMemory,arguments[0]);
if(!(this instanceof StructCtor)){
toss("The",structName,"constructor may only be called via 'new'.");
}else if(arguments.length){
if(Number.isNaN(externalMemory) || externalMemory<=zeroAsPtr){
if( !__isPtr(externalMemory) ){
toss("Invalid pointer value",arguments[0],"for",structName,"constructor.");
}
__allocStruct(StructCtor, this, externalMemory);
@@ -705,31 +878,127 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
__allocStruct(StructCtor, this);
}
};
const self = this;
/**
"Convert" struct description x to a struct description, if
needed.
*/
const ads = (x)=>{
//console.warn("looksLikeASig(",x,") =",looksLikeASig(x));
return (('string'===typeof x) && looksLikeASig(x))
? {signature: x} : __adaptStruct2(self,x);
};
if(1===arguments.length){
si = ads(structName);
structName = si.structName || si.name;
}else if(2===arguments.length){
si = ads(si);
si.name ??= structName;
}else{
si = ads(si);
}
structName ??= si.structName;
//console.warn("arguments =",JSON.stringify(arguments));
structName ??= opt.structName;
if( !structName ) toss("One of 'name' or 'structName' are required.");
if( si.adapt ){
Object.keys(si.adapt.struct||{}).forEach((k)=>{
__adaptStruct.call(StructBinderImpl, k, si.adapt.struct[k]);
});
Object.keys(si.adapt.set||{}).forEach((k)=>{
__adaptSet.call(StructBinderImpl, k, si.adapt.set[k]);
});
Object.keys(si.adapt.get||{}).forEach((k)=>{
__adaptGet.call(StructBinderImpl, k, si.adapt.get[k]);
});
}
if(!si.members && !si.sizeof){
si.sizeof = sigSize(si.signature);
}
const debugFlags = rop(SBF.__makeDebugFlags(StructBinder.debugFlags));
Object.defineProperties(StructCtor,{
debugFlags: debugFlags,
isA: rop((v)=>v instanceof StructCtor),
memberKey: __memberKeyProp,
memberKeys: __structMemberKeys,
methodInfoForKey: rop(function(mKey){
}),
structInfo: rop(structInfo),
//methodInfoForKey: rop(function(mKey){/*???*/}),
structInfo: rop(si),
structName: rop(structName)
});
StructCtor.prototype = new StructType(structName, structInfo, rop);
StructCtor.prototype = new StructType(structName, si, rop);
Object.defineProperties(StructCtor.prototype,{
debugFlags: debugFlags,
constructor: rop(StructCtor)
/*if we assign StructCtor.prototype and don't do
this then StructCtor!==instance.constructor!*/
this then StructCtor!==instance.constructor*/
});
Object.keys(structInfo.members).forEach(
(name)=>makeMemberWrapper(StructCtor, name, structInfo.members[name])
);
let lastMember = false;
let offset = 0;
//console.warn(structName,"si =",si);
si.offset ??= 0;
Object.keys(si.members || {}).forEach((k)=>{
// Sanity checks of sizeof/offset info...
let m = ads(si.members[k]);
if(!m.members && !m.sizeof){
/* ^^^^ fixme: we need to recursively collect all sizeofs
before updating that. */
m.sizeof = sigSize(m.signature);
if(!m.sizeof){
toss(sPropName(structName,k), "is missing a sizeof property.",m);
}
}
if( undefined===m.offset ){
m.offset = offset;
}
si.members[k] = m;
if(!lastMember || lastMember.offset < m.offset) lastMember = m;
makeMemberWrapper.call(self, StructCtor, k, m)
offset += m.sizeof;
//console.warn("offset",sPropName(structName,k),offset);
});
if( !lastMember ) toss("No member property descriptions found.");
if( !si.sizeof ) si.sizeof = offset;
if(si.sizeof===1){
(si.signature === 'c' || si.signature === 'C') ||
toss("Unexpected sizeof==1 member",
sPropName(structName,k),
"with signature",si.signature);
}else{
// sizes and offsets of size-1 members may be odd values, but
// others may not.
if(0!==(si.sizeof%4)){
console.warn("Invalid struct member description",si);
toss(structName,"sizeof is not aligned. sizeof="+si.sizeof);
}
if(0!==(si.offset%4)){
console.warn("Invalid struct member description",si);
toss(structName,"offset is not aligned. offset="+si.offset);
}
}
if( si.sizeof < offset ){
console.warn("Suspect struct description:",si,"offset =",offset);
toss("Mismatch in the calculated vs. the provided sizeof/offset info.",
"Expected sizeof",offset,"but got",si.sizeof,"for",si);
}
return StructCtor;
}/*StructBinderImpl*/;
const StructBinder = function StructBinder(structName, structInfo){
return (1==arguments.length)
? StructBinderImpl.call(StructBinder, structName)
: StructBinderImpl.call(StructBinder, structName, structInfo);
};
StructBinder.StructType = StructType;
StructBinder.config = config;
StructBinder.allocCString = __allocCString;
StructBinder.adaptGet = __adaptGet;
StructBinder.adaptSet = __adaptSet;
StructBinder.adaptStruct = __adaptStruct;
if(!StructBinder.debugFlags){
StructBinder.debugFlags = SBF.__makeDebugFlags(SBF.debugFlags);
}
+2
View File
@@ -98,6 +98,7 @@ tgtFiles=(
tester1.js
tester1.mjs
)
tgtFiles+=(jswasm/sqlite3-node.mjs); # https://github.com/sqlite/sqlite-wasm/issues/118
if [[ 1 = $b64 ]]; then
tgtFiles+=(
@@ -148,6 +149,7 @@ fJ1=(
sqlite3-worker1-promiser.mjs
sqlite3-worker1-promiser-bundler-friendly.mjs
)
fJ1+=(sqlite3-node.mjs); # https://github.com/sqlite/sqlite-wasm/issues/118
fJ2=(
sqlite3.js
sqlite3.mjs
+7 -4
View File
@@ -371,7 +371,7 @@ const BuildDefs oBuildDefs = {
.node = {
.zEmo = "🍟",
.zBaseName = "sqlite3-node",
.zDotWasm = 0,
.zDotWasm = "sqlite3",
.zCmppD = "-Dtarget:node $(c-pp.D.bundler)",
.zEmcc = 0,
.zEmccExtra = 0,
@@ -382,21 +382,21 @@ const BuildDefs oBuildDefs = {
** node. */,
.zDeps = 0,
.zIfCond = 0,
.flags = CP_ALL | F_UNSUPPORTED | F_NODEJS
.flags = CP_ALL | F_UNSUPPORTED | F_ESM | F_NODEJS
},
/* 64-bit node. */
.node64 = {
.zEmo = "🍔",
.zBaseName = "sqlite3-node-64bit",
.zDotWasm = 0,
.zDotWasm = "sqlite3-64it",
.zCmppD = "-Dtarget:node $(c-pp.D.bundler)",
.zEmcc = 0,
.zEmccExtra = 0,
.zEnv = "node",
.zDeps = 0,
.zIfCond = 0,
.flags = CP_ALL | F_UNSUPPORTED | F_NODEJS | F_64BIT
.flags = CP_ALL | F_UNSUPPORTED | F_ESM | F_NODEJS | F_64BIT
},
/* Entirely unsupported. */
@@ -784,6 +784,9 @@ static void mk_lib_mode(const char *zBuildName, const BuildDef * pB){
if( pB->flags & F_64BIT ){
pf("c-pp.D.%s += $(c-pp.D.64bit)\n", zBuildName);
}
if( pB->flags & F_UNSUPPORTED ){
pf("c-pp.D.%s += -Dunsupported-build\n", zBuildName);
}
pf("emcc.environment.%s ?= %s\n", zBuildName,
pB->zEnv ? pB->zEnv : oBuildDefs.vanilla.zEnv);
+13 -5
View File
@@ -12,11 +12,19 @@
</head>
<body>
<h1 id='color-target'>sqlite3 tester #1: Worker thread (@bitness@-bit WASM)</h1>
<div>Variants:
<a href='tester1.html' target='tester1.html'>conventional UI thread</a>,
<a href='tester1-worker.html' target='tester1-worker.html'>conventional worker</a>,
<a href='tester1-esm.html' target='tester1-esm.html'>ESM in UI thread</a>,
<a href='tester1-worker.html?esm' target='tester1-worker.html?esm'>ESM worker</a>
<div>Variants (32-bit):
conventional UI thread:
(<a href='tester1.html' target='tester1.html'>32-bit</a>,
<a href='tester1-64bit.html' target='tester1-64bit.html'>64-bit</a>),
conventional worker:
(<a href='tester1-worker.html' target='tester1-worker.html'>32-bit</a>,
<a href='tester1-worker-64bit.html' target='tester1-worker-64bit.html'>64-bit</a>),
ESM in UI thread:
(<a href='tester1-esm.html' target='tester1-esm.html'>32-bit</a>,
<a href='tester1-esm-64bit.html' target='tester1-esm-64bit.html'>64-bit</a>),
ESM worker:</a>
(<a href='tester1-worker.html?esm' target='tester1-worker.html?esm'>32-bit</a>
<a href='tester1-worker-64bit.html?esm' target='tester1-worker-64bit.html?esm'>64-bit</a>)
</div>
<div class='input-wrapper'>
<input type='checkbox' id='cb-log-reverse'>
+13 -5
View File
@@ -11,11 +11,19 @@
<style></style>
</head>
<body><h1 id='color-target'></h1>
<div>Variants:
<a href='tester1.html' target='tester1.html'>conventional UI thread</a>,
<a href='tester1-worker.html' target='tester1-worker.html'>conventional worker</a>,
<a href='tester1-esm.html' target='tester1-esm.html'>ESM in UI thread</a>,
<a href='tester1-worker.html?esm' target='tester1-worker.html?esm'>ESM worker</a>
<div>Variants (32-bit):
conventional UI thread:
(<a href='tester1.html' target='tester1.html'>32-bit</a>,
<a href='tester1-64bit.html' target='tester1-64bit.html'>64-bit</a>),
conventional worker:
(<a href='tester1-worker.html' target='tester1-worker.html'>32-bit</a>,
<a href='tester1-worker-64bit.html' target='tester1-worker-64bit.html'>64-bit</a>),
ESM in UI thread:
(<a href='tester1-esm.html' target='tester1-esm.html'>32-bit</a>,
<a href='tester1-esm-64bit.html' target='tester1-esm-64bit.html'>64-bit</a>),
ESM worker:</a>
(<a href='tester1-worker.html?esm' target='tester1-worker.html?esm'>32-bit</a>
<a href='tester1-worker-64bit.html?esm' target='tester1-worker-64bit.html?esm'>64-bit</a>)
</div>
<div class='input-wrapper'>
<input type='checkbox' id='cb-log-reverse'>
+149 -231
View File
@@ -369,6 +369,88 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
clearOnInit: true,
initialCapacity: 6
};
//#if enable-see
/**
Code consolidator for SEE sanity checks for various VFSes. ctor
is the VFS's oo1.DB-type constructor. ctorOptFunc(bool) is a
function which must return a constructor args object for ctor. It
is passed true if the db needs to be cleaned up/unlinked before
opening it (OPFS) and false if not (how that is done is
VFS-dependent). dbUnlink is a function which is expected to
unlink() the db file if the ctorOpfFunc does not do so when
passed true (kvvfs).
This function initializes the db described by ctorOptFunc(...),
writes some secret info into it, and re-opens it twice to
confirmi that it can be read with an SEE key and cannot be read
without one.
*/
T.seeBaseCheck = function(ctor, ctorOptFunc, dbUnlink){
let initDb = true;
const tryKey = function(keyKey, key, expectCount){
let db;
//console.debug('tryKey()',arguments);
try {
if (initDb) {
const ctoropt = ctorOptFunc(initDb);
initDb = false;
db = new ctor({
...ctoropt,
[keyKey]: key
});
db.exec([
"drop table if exists t;",
"create table t(a);"
]);
db.close();
db = null;
// Ensure that it's actually encrypted...
let err;
try {
db = new ctor(ctorOptFunc(false));
T.assert(db, 'db opened') /* opening is fine, but... */;
db.exec("select 1 from sqlite_schema");
console.warn("(should not be reached) sessionStorage =", sessionStorage);
} catch (e) {
err = e;
} finally {
db.close()
db = null;
}
T.assert(err, "Expecting an exception")
.assert(capi.SQLITE_NOTADB == err.resultCode,
"Expecting NOTADB");
}/*initDb*/
db = new ctor({
...ctorOptFunc(false),
[keyKey]: key
});
db.exec("insert into t(a) values (1),(2)");
T.assert(expectCount === db.selectValue('select sum(a) from t'));
} finally {
if (db) db.close();
}
};
const hexFoo = new Uint8Array([0x66,0x6f,0x6f]/*=="foo"*/);
dbUnlink();
tryKey('textkey', 'foo', 3);
T.assert( !initDb );
tryKey('textkey', 'foo', 6);
dbUnlink();
initDb = true;
tryKey('key', 'foo', 3);
T.assert( !initDb );
tryKey('key', hexFoo, 6);
dbUnlink();
initDb = true;
tryKey('hexkey', hexFoo, 3);
T.assert( !initDb );
tryKey('hexkey', hexFoo, 6);
dbUnlink();
},
//#endif enable-see
////////////////////////////////////////////////////////////////////////
// End of infrastructure setup. Now define the tests...
////////////////////////////////////////////////////////////////////////
@@ -945,7 +1027,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
let ptr = k1.pointer;
k1.dispose();
T.assert(undefined === k1.pointer).
mustThrowMatching(()=>{k1.$pP=1}, /disposed instance/);
mustThrowMatching(()=>{k1.$pP=1}, /disposed struct instance/);
}finally{
k1.dispose();
k2.dispose();
@@ -1549,6 +1631,9 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
T.assert(blob instanceof Uint8Array).
assert(0x68===blob[0] && 0x69===blob[1]);
blob = null;
blob = db.selectValue("select ?1", new Uint8Array([97,0,98,0,99]),
sqlite3.capi.SQLITE_TEXT);
T.assert("a\0b\0c"===blob, "Something is amiss with embedded NULs");
let counter = 0, colNames = [];
list.length = 0;
db.exec(new TextEncoder('utf-8').encode("SELECT a a, b b FROM t"),{
@@ -2836,71 +2921,9 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
predicate: ()=>(isUIThread()
|| "Only available in main thread."),
test: function(sqlite3){
this.kvvfsUnlink();
let initDb = true;
const tryKey = function(keyKey, key, expectCount){
let db;
//console.debug('tryKey()',arguments);
const ctoropt = {
filename: this.kvvfsDbFile
//vfs: 'kvvfs'
//,flags: 'ct'
};
try {
if (initDb) {
initDb = false;
db = new this.JDb({
...ctoropt,
[keyKey]: key
});
db.exec([
"drop table if exists t;",
"create table t(a);"
]);
db.close();
// Ensure that it's actually encrypted...
let err;
try {
db = new this.JDb(ctoropt);
T.assert(db, 'db opened') /* opening is fine, but... */;
db.exec("select 1 from sqlite_schema");
console.warn("(should not be reached) sessionStorage =", sessionStorage);
} catch (e) {
err = e;
} finally {
db.close()
}
T.assert(err, "Expecting an exception")
.assert(sqlite3.capi.SQLITE_NOTADB == err.resultCode,
"Expecting NOTADB");
}/*initDb*/
//console.debug('tryKey()',arguments);
db = new sqlite3.oo1.DB({
...ctoropt,
vfs: 'kvvfs',
[keyKey]: key
});
db.exec("insert into t(a) values (1),(2)");
T.assert(expectCount === db.selectValue('select sum(a) from t'));
} finally {
if (db) db.close();
}
}.bind(this);
const hexFoo = new Uint8Array([0x66,0x6f,0x6f]/*=="foo"*/);
tryKey('textkey', 'foo', 3);
T.assert( !initDb );
tryKey('textkey', 'foo', 6);
this.kvvfsUnlink();
initDb = true;
tryKey('key', 'foo', 3);
T.assert( !initDb );
tryKey('key', hexFoo, 6);
this.kvvfsUnlink();
initDb = true;
tryKey('hexkey', hexFoo, 3);
T.assert( !initDb );
tryKey('hexkey', hexFoo, 6);
this.kvvfsUnlink();
T.seeBaseCheck(sqlite3.oo1.JsStorageDb, (isInit)=>{
return {filename: "session"};
}, ()=>this.kvvfsUnlink());
}
})/*kvvfs with SEE*/
//#endif enable-see
@@ -3315,71 +3338,14 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
.t({
name: 'OPFS with SEE encryption',
test: function(sqlite3){
const dbFile = 'file:///sqlite3-see.edb';
const dbCtor = sqlite3.oo1.OpfsDb;
const hexFoo = new Uint8Array([0x66,0x6f,0x6f]/*=="foo"*/);
let initDb = true;
const tryKey = function(keyKey, key, expectCount){
let db;
//console.debug('tryKey()',arguments);
const ctoropt = {
filename: dbFile,
flags: 'c'
};
try {
if (initDb) {
initDb = false;
const opt = {
...ctoropt,
[keyKey]: key
};
opt.filename += '?delete-before-open=1';
db = new dbCtor(opt);
db.exec([
"drop table if exists t;",
"create table t(a);"
]);
db.close();
// Ensure that it's actually encrypted...
let err;
try {
db = new dbCtor(ctoropt);
T.assert(db, 'db opened') /* opening is fine, but... */;
const rv = db.exec({
sql:"select count(*) from sqlite_schema",
returnValue: 'resultRows'
});
console.warn("(should not be reached) rv =",rv);
} catch (e) {
err = e;
} finally {
db.close()
}
T.assert(err, "Expecting an exception")
.assert(sqlite3.capi.SQLITE_NOTADB == err.resultCode,
"Expecting NOTADB");
}/*initDb*/
db = new dbCtor({
...ctoropt,
[keyKey]: key
});
db.exec("insert into t(a) values (1),(2)");
T.assert(expectCount === db.selectValue('select sum(a) from t'));
} finally {
if (db) db.close();
}
};
tryKey('textkey', 'foo', 3);
T.assert( !initDb );
tryKey('textkey', 'foo', 6);
initDb = true;
tryKey('key', 'foo', 3);
T.assert( !initDb );
tryKey('key', hexFoo, 6);
initDb = true;
tryKey('hexkey', hexFoo, 3);
T.assert( !initDb );
tryKey('hexkey', hexFoo, 6);
T.seeBaseCheck(
sqlite3.oo1.OpfsDb,
function(isInit){
const opt = {filename: 'file:///sqlite3-see.edb'};
if( isInit ) opt.filename += '?delete-before-open=1';
return opt;
},
()=>{});
}
})/*OPFS with SEE*/
//#endif enable-see
@@ -3584,69 +3550,11 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
let poolUtil;
const P1 = await inst(poolConfig).then(u=>poolUtil = u).catch(catcher);
const dbFile = '/sqlite3-see.edb';
const dbCtor = poolUtil.OpfsSAHPoolDb;
const hexFoo = new Uint8Array([0x66,0x6f,0x6f]/*=="foo"*/);
let initDb = true;
const tryKey = function(keyKey, key, expectCount){
let db;
//console.debug('tryKey()',arguments);
const ctoropt = {
filename: dbFile,
flags: 'c'
};
try {
if (initDb) {
initDb = false;
poolUtil.unlink(dbFile);
db = new dbCtor({
...ctoropt,
[keyKey]: key
});
db.exec([
"drop table if exists t;",
"create table t(a);"
]);
db.close();
// Ensure that it's actually encrypted...
let err;
try {
db = new dbCtor(ctoropt);
T.assert(db, 'db opened') /* opening is fine, but... */;
const rv = db.exec({
sql:"select count(*) from sqlite_schema",
returnValue: 'resultRows'
});
console.warn("(should not be reached) rv =",rv);
} catch (e) {
err = e;
} finally {
db.close()
}
T.assert(err, "Expecting an exception")
.assert(sqlite3.capi.SQLITE_NOTADB == err.resultCode,
"Expecting NOTADB");
}/*initDb*/
db = new dbCtor({
...ctoropt,
[keyKey]: key
});
db.exec("insert into t(a) values (1),(2)");
T.assert(expectCount === db.selectValue('select sum(a) from t'));
} finally {
if (db) db.close();
}
};
tryKey('textkey', 'foo', 3);
T.assert( !initDb );
tryKey('textkey', 'foo', 6);
initDb = true;
tryKey('key', 'foo', 3);
T.assert( !initDb );
tryKey('key', hexFoo, 6);
initDb = true;
tryKey('hexkey', hexFoo, 3);
T.assert( !initDb );
tryKey('hexkey', hexFoo, 6);
T.seeBaseCheck(
poolUtil.OpfsSAHPoolDb,
(isInit)=>{return {filename: dbFile}},
()=>poolUtil.unlink(dbFile)
);
poolUtil.removeVfs();
}
})/*opfs-sahpool with SEE*/
@@ -3715,44 +3623,54 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
.t("Misc. stmt_...", function(sqlite3){
const db = new sqlite3.oo1.DB();
db.exec("create table t(a doggiebiscuits); insert into t(a) values(123)");
const stmt = db.prepare("select a, a+1 from t");
T.assert( stmt.isReadOnly() )
.assert( 0===capi.sqlite3_stmt_isexplain(stmt) )
.assert( 0===capi.sqlite3_stmt_explain(stmt, 1) )
.assert( 0!==capi.sqlite3_stmt_isexplain(stmt) )
.assert( 0===capi.sqlite3_stmt_explain(stmt, 2) )
.assert( 0!==capi.sqlite3_stmt_isexplain(stmt) )
.assert( 0===capi.sqlite3_stmt_explain(stmt, 0) )
.assert( 0===capi.sqlite3_stmt_isexplain(stmt) );
let n = 0;
while( capi.SQLITE_ROW === capi.sqlite3_step(stmt) ){
++n;
T.assert( 0!==capi.sqlite3_stmt_explain(stmt, 1),
"Because stmt is busy" )
.assert( capi.sqlite3_stmt_busy(stmt) )
.assert( stmt.isBusy() )
.assert( 0!==capi.sqlite3_stmt_readonly(stmt) )
.assert( true===stmt.isReadOnly() );
const sv = capi.sqlite3_column_value(stmt, 0);
T.assert( 123===capi.sqlite3_value_int(sv) )
.assert( "doggiebiscuits"===capi.sqlite3_column_decltype(stmt,0) )
.assert( null===capi.sqlite3_column_decltype(stmt,1) );
let stmt;
try{
stmt = db.prepare("select a, a+1 from t");
T.assert( stmt.isReadOnly() )
.assert( 0===capi.sqlite3_stmt_isexplain(stmt) )
.assert( 0===capi.sqlite3_stmt_explain(stmt, 1) )
.assert( 0!==capi.sqlite3_stmt_isexplain(stmt) )
.assert( 0===capi.sqlite3_stmt_explain(stmt, 2) )
.assert( 0!==capi.sqlite3_stmt_isexplain(stmt) )
.assert( 0===capi.sqlite3_stmt_explain(stmt, 0) )
.assert( 0===capi.sqlite3_stmt_isexplain(stmt) );
let n = 0;
while( capi.SQLITE_ROW === capi.sqlite3_step(stmt) ){
++n;
T.assert( 0!==capi.sqlite3_stmt_explain(stmt, 1),
"Because stmt is busy" )
.assert( capi.sqlite3_stmt_busy(stmt) )
.assert( stmt.isBusy() )
.assert( 0!==capi.sqlite3_stmt_readonly(stmt) )
.assert( true===stmt.isReadOnly() );
const sv = capi.sqlite3_column_value(stmt, 0);
T.assert( 123===capi.sqlite3_value_int(sv) )
.assert( "doggiebiscuits"===capi.sqlite3_column_decltype(stmt,0) )
.assert( null===capi.sqlite3_column_decltype(stmt,1) );
}
T.assert( 1===n )
.assert( 0===capi.sqlite3_stmt_busy(stmt) )
.assert( !stmt.isBusy() );
if( wasm.exports.sqlite3_column_origin_name ){
log("Column metadata APIs enabled");
T.assert( "t" === capi.sqlite3_column_table_name(stmt, 0))
.assert("a" === capi.sqlite3_column_origin_name(stmt, 0))
.assert("main" === capi.sqlite3_column_database_name(stmt, 0))
}else{
log("Column metadata APIs not enabled");
} // column metadata APIs
stmt.finalize();
stmt = null;
stmt = db.prepare("select ?1").bind(new Uint8Array([97,0,98,0,99]));
stmt.step();
const sv = capi.sqlite3_column_value(stmt,0);
T.assert("a\0b\0c"===capi.sqlite3_value_text(sv),
"Expecting NULs to have survived.");
}finally{
if(stmt) stmt.finalize();
db.close();
}
T.assert( 1===n )
.assert( 0===capi.sqlite3_stmt_busy(stmt) )
.assert( !stmt.isBusy() );
if( wasm.exports.sqlite3_column_origin_name ){
log("Column metadata APIs enabled");
T.assert( "t" === capi.sqlite3_column_table_name(stmt, 0))
.assert("a" === capi.sqlite3_column_origin_name(stmt, 0))
.assert("main" === capi.sqlite3_column_database_name(stmt, 0))
}else{
log("Column metadata APIs not enabled");
} // column metadata APIs
stmt.finalize();
db.close();
})
////////////////////////////////////////////////////////////////////
-19
View File
@@ -952,25 +952,6 @@ FUZZDATA = \
#
TESTOPTS = --verbose=file --output=test-out.txt
#
# Extra compiler options for various shell tools
#
# Note that some of these will only apply when embedding sqlite3.c
# into the shell, as these flags are not otherwise passed on to the
# library.
SHELL_OPT += -DSQLITE_DQS=0
SHELL_OPT += -DSQLITE_ENABLE_FTS4
#SHELL_OPT += -DSQLITE_ENABLE_FTS5
SHELL_OPT += -DSQLITE_ENABLE_RTREE
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
SHELL_OPT += -DSQLITE_ENABLE_PERCENTILE
SHELL_OPT += -DSQLITE_STRICT_SUBTYPE=1
FUZZERSHELL_OPT =
FUZZCHECK_OPT += -I$(TOP)/test
FUZZCHECK_OPT += -I$(TOP)/ext/recover
+52 -56
View File
@@ -1,12 +1,12 @@
C Version\s3.51.0
D 2025-11-04T19:38:17.314
C Re-add\sthe\s(still)\sunsupported\sand\s(still\s100%)\suntested\ssqlite3-node.mjs\sback\sto\sthe\sdist\sbundle,\sas\sits\sremoval\sin\s3.51\shas\s[caused\ssome\sdownstream\sdisruption](https://github.com/sqlite/sqlite-wasm/issues/118).\sThis\sis\sstashed\sin\sa\sbranch\sfor\snow\sand\smay\snever\sbe\smerged\s-\swe're\sstill\snegotiating\sthe\sterms\sof\sits\sre-addition\sand\smy\seventual\scapitulation.
D 2025-11-13T08:36:52.956
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md 6bc480fc673fb4acbc4094e77edb326267dd460162d7723c7f30bee2d3d9e97d
F Makefile.in 3ce07126d7e87c7464301482e161fdae6a51d0a2aa06b200b8f0000ef4d6163b
F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0
F Makefile.msc 8dd676302f3165984c046f81af14b6676a334418fa30255efaf439f8033042fa
F Makefile.msc 523bab2f6569e912a0aaf2d13e0b3f9bcb36d52310b236d950b354068c9de3f3
F README.md dae499194b75deed76a13a4a83c82493f2530331882d7dfe5754d63287d3f8f7
F VERSION 16eddb43056a79c1977427ab7a05f3457c373fa159dcdced8754eb89ce7e06b8
F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5
@@ -17,12 +17,12 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
F art/sqlite370.svg 40b7e2fe8aac3add5d56dd86ab8d427a4eca5bcb3fe4f8946cb3794e1821d531
F auto.def 44a0d1bf09d78355fc88251ccbf8e64e6341fd89c11de68a01c3645e53a2bade
F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac
F autoconf/Makefile.in 118aa2c4d49173672d065fdda19eb8a28642e2c684212d7a626d6db5e6762521
F autoconf/Makefile.in 306f500fce8cae9e1af9459f1ac7fe89ce46999594ef3fdc62dc9d7d651fb091
F autoconf/Makefile.msc 803aa9e23b6a764751f6a91d0673620eefa46729fb80faf51391120e1d752966
F autoconf/README.first f1d3876e9a7852c22f275a6f06814e64934cecbc0b5b9617d64849094c1fd136
F autoconf/README.txt b749816b8452b3af994dc6d607394bef3df1736d7e09359f1087de8439a52807
F autoconf/auto.def 3d994f3a9cc9b712dbce92a5708570ddcf3b988141b6eb738f2ed16127a9f0ac
F autoconf/tea/Makefile.in bf6b43eafcd18766d81a8f0085cfc9cb051d8abae9031a8e7c3f5f1246e8f166
F autoconf/tea/Makefile.in 00e60cf3bf5580f31bfdcf3c914e9ba1831d676948363962de92ce65e5be4431
F autoconf/tea/README.txt 23475876343498ef2b514cc7510e8f1559a17e8e03fbc7a41c1c8a3b89e7b7e3
F autoconf/tea/_teaish.tester.tcl.in 8253b44be88e2e3f21de95a65d3a90c2be8e70b7bdd08a5b80e337ba7402f8f1
F autoconf/tea/auto.def ce95b9450e2fa4ba5dc857e208fe10f4e6f2d737796ac3278aee6079db417529
@@ -47,10 +47,10 @@ F autosetup/find_tclconfig.tcl e64886ffe3b982d4df42cd28ed91fe0b5940c2c5785e126c1
F autosetup/jimsh0.c a57c16e65dcffc9c76e496757cb3f7fb47e01ecbd1631a0a5e01751fc856f049
F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba
F autosetup/proj.tcl 6fc14ef82b19b77a95788ffbcfad7989b4e3cb4ce96a21dcb5cf7312f362fba9
F autosetup/sqlite-config.tcl 5d779fce20c11fde3fe99d157dcd5b5569d729b301141b8dfb8d5aacf9d48cba
F autosetup/sqlite-config.tcl 1fd7c55394051fbfba2fb9fa9192c027ee7d74612dbf772b06e27feb9f1de5df
F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9
F autosetup/teaish/README.txt b40071e6f8506500a2f7f71d5fc69e0bf87b9d7678dd9da1e5b4d0acbf40b1ca
F autosetup/teaish/core.tcl aee092fc71986d1272b835ea7492bb55ffc213a289502e4f14da80cf67b7e3c3
F autosetup/teaish/core.tcl e014dd95900c7f9a34e8e0f460f47e94841059827bce8b4c49668b0c7ae3f1a0
F autosetup/teaish/feature.tcl 18194fb79a24d30e5bbdeab40999616f39278b53a27525349ded033af2fd73be
F autosetup/teaish/tester.tcl 1799514c2652db49561b3386c5242b94534d1663f2cfac861a955e071895fdd0
F configure 9a00b21dfd13757bbfb8d89b30660a89ec1f8f3a79402b8f9f9b6fc475c3303a x
@@ -284,14 +284,14 @@ F ext/intck/intck_common.tcl a61fd2697ae55b0a3d89847ca0b590c6e0d8ff64bebb70920d9
F ext/intck/intckbusy.test d5ed4ef85a4b1dc1dee2484bd14a4bb68529659cca743327df0c775f005fa387
F ext/intck/intckcorrupt.test f6c302792326fb3db9dcfc70b554c55369bc4b52882eaaf039cfe0b74c821029
F ext/intck/intckfault.test cff3f75dff74abb3edfcb13f6aa53f6436746ab64b09fe5e2028f051e985efab
F ext/intck/sqlite3intck.c 0d10df36e2b7b438aa80ecd3f5e584d41b747586b038258fe6b407f66b81e7c5
F ext/intck/sqlite3intck.c b1c8a86f90fc00741d13314db9c58f7e2f92d1d19c5ad1c6904ec83a6bbd5c96
F ext/intck/sqlite3intck.h 2b40c38e7063ab822c974c0bd4aed97dabb579ccfe2e180a4639bb3bbef0f1c9
F ext/intck/test_intck.c 4f9eaadaedccb9df1d26ba41116a0a8e5b0c5556dc3098c8ff68633adcccdea8
F ext/jni/GNUmakefile 8a94e3a1953b88cf117fb2a5380480feada8b4f5316f02572cab425030a720b4
F ext/jni/README.md e3fbd47c774683539b7fdc95a667eb9cd6e64d8510f3ee327e7fa0c61c8aa787
F ext/jni/README.md 1479c83dbe26125264a060ee6873531795a7082dbc0d43c4067683371331559f
F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa
F ext/jni/src/c/sqlite3-jni.c 3d84a0176af779737ae977ba1c90d2ffe2537b8299c5d9f6552620493f12ac4b
F ext/jni/src/c/sqlite3-jni.h ac180ba9b21978727006c790d3006a95a2402a4c3ec7a0def92707ed89b79945
F ext/jni/src/c/sqlite3-jni.h df43024cced914c49485633d0f90168689e70577b3b17b0ecbdaf16e4a417bff
F ext/jni/src/org/sqlite/jni/annotation/Experimental.java 8603498634e41d0f7c70f661f64e05df64376562ea8f126829fd1e0cdd47e82b
F ext/jni/src/org/sqlite/jni/annotation/NotNull.java be6cc3e8e114485822331630097cc0f816377e8503af2fc02f9305ff2b353917
F ext/jni/src/org/sqlite/jni/annotation/Nullable.java 56e3dee1f3f703a545dfdeddc1c3d64d1581172b1ad01ffcae95c18547fafd90
@@ -301,7 +301,7 @@ F ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java 0e28a0df51368c7127e505f
F ext/jni/src/org/sqlite/jni/capi/AuthorizerCallback.java c045a5b47e02bb5f1af91973814a905f12048c428a3504fbc5266d1c1be3de5a
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 3d275f5f4fbdbe4fff15f4d42cf5ff559f9a4897e7373fa99f3b1dc9cf7f849c
F ext/jni/src/org/sqlite/jni/capi/CApi.java a9701cbe736b8bef5bc72ae465be0250e137f67bdb5a3ab62497972b6f51572d
F ext/jni/src/org/sqlite/jni/capi/CallbackProxy.java 1b3baf5b772f266e8baf8f35f0ddc5bd87fc8c4927ec69115c46fd6fba6701c3
F ext/jni/src/org/sqlite/jni/capi/CollationCallback.java e29bcfc540fdd343e2f5cca4d27235113f2886acb13380686756d5cabdfd065a
F ext/jni/src/org/sqlite/jni/capi/CollationNeededCallback.java 5bfa226a8e7a92e804fd52d6e42b4c7b875fa7a94f8e2c330af8cc244a8920ab
@@ -346,7 +346,7 @@ F ext/jni/src/org/sqlite/jni/test-script-interpreter.md d7987b432870d23f7c72a780
F ext/jni/src/org/sqlite/jni/wrapper1/AggregateFunction.java d5c108b02afd3c63c9e5e53f71f85273c1bfdc461ae526e0a0bb2b25e4df6483
F ext/jni/src/org/sqlite/jni/wrapper1/ScalarFunction.java 326ffba29aab836a6ea189703c3d7fb573305fd93da2d14b0f9e9dcf314c8290
F ext/jni/src/org/sqlite/jni/wrapper1/SqlFunction.java e920f7a031e04975579240d4a07ac5e4a9d0f8de31b0aa7a4be753c98ae596c9
F ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java c82bc00c1988f86246a89f721d3c41f0d952f33f934aa6677ec87f7ca42519a0
F ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java ce8aef867e06a21685658eb0173768c355e9e1e2dfdc75f382643fa62c7ee779
F ext/jni/src/org/sqlite/jni/wrapper1/SqliteException.java 982538ddb4c0719ef87dfa664cd137b09890b546029a7477810bd64d4c47ee35
F ext/jni/src/org/sqlite/jni/wrapper1/Tester2.java 08f92d52be2cec28a7b4555479cc54b7ebeeb94985256144eeb727154ec3f85b
F ext/jni/src/org/sqlite/jni/wrapper1/ValueHolder.java a84e90c43724a69c2ecebd601bc8e5139f869b7d08cb705c77ef757dacdd0593
@@ -372,7 +372,7 @@ F ext/misc/dbdump.c 678f1b9ae2317b4473f65d03132a2482c3f4b08920799ed80feedd2941a0
F ext/misc/decimal.c d4883de142f6dcd36eda23da40b55e2b51374e7b01eb54a7173940191389fc5e
F ext/misc/eval.c 04bc9aada78c888394204b4ed996ab834b99726fb59603b0ee3ed6e049755dc1
F ext/misc/explain.c 606100185fb90d6a1eade1ed0414d53503c86820d8956a06e3b0a56291894f2b
F ext/misc/fileio.c d4918ff3f59a26c447347b40ac5e5c41aef697dfa24ebb2ef61ebad3c32261f0
F ext/misc/fileio.c 61af623160c073b605b4ff1f67d278c4c348956efa08f6201756577c7a050d17
F ext/misc/fossildelta.c 2fc2dd4f34f478df674887db62586b1071c4cd3c9e73ee40f9ee669670e482d1
F ext/misc/fuzzer.c 6b231352815304ba60d8e9ec2ee73d4918e74d9b76bda8940ba2b64e8777515e
F ext/misc/ieee754.c 176c061c94857b543313959289cb60cf777c999fd002f82b53d194b95e9f347a
@@ -575,8 +575,7 @@ F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009e
F ext/session/sqlite3session.c b3de195ce668cace9b324599bf6255a70290cbfb5451e826e946f3aee6e64c54
F ext/session/sqlite3session.h 7404723606074fcb2afdc6b72c206072cdb2b7d8ba097ca1559174a80bc26f7a
F ext/session/test_session.c 8766b5973a6323934cb51248f621c3dc87ad2a98f023c3cc280d79e7d78d36fb
F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
F ext/wasm/GNUmakefile 3dc01e673c456d3b752674c9407276e8fef35dec1d304b3cc1de362f019b2a09
F ext/wasm/GNUmakefile 74c73254fb44c82d517a8907da9866d5d3ef1a533addaeb4322f470e0fb81ba3
F ext/wasm/README-dist.txt f01081a850ce38a56706af6b481e3a7878e24e42b314cfcd4b129f0f8427066a
F ext/wasm/README.md 2e87804e12c98f1d194b7a06162a88441d33bb443efcfe00dc6565a780d2f259
F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff
@@ -584,20 +583,17 @@ F ext/wasm/SQLTester/SQLTester.mjs 6b3c52ed36a5573ca4883176f326332a8d4c0cecf5efd
F ext/wasm/SQLTester/SQLTester.run.mjs 57f2adb33f43f2784abbf8026c1bfd049d8013af1998e7dcb8b50c89ffc332e0
F ext/wasm/SQLTester/index.html 64f3435084c7d6139b08d1f2a713828a73f68de2ae6a3112cbb5980d991ba06f
F ext/wasm/SQLTester/touint8array.c 2d5ece04ec1393a6a60c4bf96385bda5e1a10ad49f3038b96460fc5e5aa7e536
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-core ef34398a903d0a2425fbbfbd4ed2cd596daea55b8515e2617c8dc7ad7c0767dd
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-extras 9eae68943ce91ab145892b31370819c2103525240eb72e0fce53c498b8d8275a
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 f4c0d67caaee21a77b8938c30b5f79667bfc9d0c95d01b51df77ea35ee773884
F ext/wasm/api/extern-post-js.c-pp.js 205f55aacfc62c580985db5c790300779de3876a76a5c7e1bfb13e71c8b4506b
F ext/wasm/api/EXPORTED_FUNCTIONS.c-pp d609c22bc05e25991bdd2eeed4497485a3756446158b2794471426e5e3517056
F ext/wasm/api/README.md df476398c6d80affae807a8208c5a97d1615786e1d6767b5292bfe67edb59b18
F ext/wasm/api/extern-post-js.c-pp.js 4b310c9891886e7c1ea4e2419966ff45dfeda825b897fdaa4119332509f7e3d1
F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e7a4d11d43c5c8f41
F ext/wasm/api/post-js-footer.js 5bd7170b5e8ce7b62102702bbcf47ef7b3b49cd56ed40c043fd990aa715b74ee
F ext/wasm/api/post-js-header.js 79d078aec33d93b640a19c574b504d88bb2446432f38e2fbb3bb8e36da436e70
F ext/wasm/api/pre-js.c-pp.js a876c6399dff29b6fe9e434036beb89889164cc872334e184291723ecc7cb072
F ext/wasm/api/sqlite3-api-cleanup.js a3d6b9e449aefbb8bba283c2ba9477e2333a0eeb94a7a26b5bf952736f65a6dd
F ext/wasm/api/sqlite3-api-glue.c-pp.js d2b8263b3ce0cefc6c5a68d0a4d448a9770eda4bf9d9ded9d7eb0198e4ce4da1
F ext/wasm/api/pre-js.c-pp.js b1a7a09d14df1f36de11e801ba06cb92c0ddeb520e5b2f28836af0ec8146e288
F ext/wasm/api/sqlite3-api-cleanup.js 79b54a566291e17c0c3e165c6c4969c48ec17cd297755180151af65ac616dfa0
F ext/wasm/api/sqlite3-api-glue.c-pp.js 79a54b54ca6324d28e31e19b56bbaebb7d2cc4b3079066e7e901333fa5047c53
F ext/wasm/api/sqlite3-api-oo1.c-pp.js 31dbfd470c91ffd96d77399b749bab6b69e3ba9074188833f97ac13f087cf07b
F ext/wasm/api/sqlite3-api-prologue.js b5a55ae74efcdcd0aa6a143d59e34137e43ae732f02b563dcab22d735f1599a4
F ext/wasm/api/sqlite3-api-prologue.js b6b2fd1720c484e168705909862442b4524a1e61e16b4549a5725dd28c3cecc2
F ext/wasm/api/sqlite3-api-worker1.c-pp.js 1041dd645e8e821c082b628cd8d9acf70c667430f9d45167569633ffc7567938
F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
F ext/wasm/api/sqlite3-opfs-async-proxy.js 9654b565b346dc609b75d15337f20acfa7af7d9d558da1afeb9b6d8eaa404966
@@ -605,14 +601,14 @@ F ext/wasm/api/sqlite3-vfs-helper.c-pp.js 3f828cc66758acb40e9c5b4dcfd87fd478a14c
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 26cb41d5a62f46a106b6371eb00fef02de3cdbfaa51338ba087a45f53028e0d0
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 418c33fe284739564daab3c7a7a88882fdd3c99137497900f98eddec1e409af5
F ext/wasm/api/sqlite3-vtab-helper.c-pp.js 9097074724172e31e56ce20ccd7482259cf72a76124213cbc9469d757676da86
F ext/wasm/api/sqlite3-wasm.c dd7fc1d535281f0d5d2732bb1b662d1d403a762f07b63c2ea5663053377b2804
F ext/wasm/api/sqlite3-wasm.c 2d1cbe498f7b0fb64b11451eda481f458df74d6258baea635513e637fcbb8b1a
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js bda1c75bd674a92a0e27cc2f3d46dbbf21e422413f8046814515a0bd7409328a
F ext/wasm/api/sqlite3-worker1.c-pp.js 802d69ead8c38dc1be52c83afbfc77e757da8a91a2e159e7ed3ecda8b8dba2e7
F ext/wasm/c-pp-lite.c 8fa0148e73782a86274db688c4730e2962cd675af329490493adddaf3322f16f
F ext/wasm/c-pp-lite.c 67e86d9ea47cf3e70a4067acd92788f4f8e6271fae02a68490b069303d7597be
F ext/wasm/common/SqliteTestUtil.js 7adaeffef757d8708418dc9190f72df22367b531831775804b31598b44f6aa51
F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15
F ext/wasm/common/testing.css e97549bab24126c24e0daabfe2de9bb478fb0a69fdb2ddd0a73a992c091aad6f
F ext/wasm/common/whwasmutil.js 0d539324097fc83b953e9844267359ba0fd02286caa784ea2f597ced279ea640
F ext/wasm/common/whwasmutil.js b4fd73fac162406e67f276647ff8bae51881e15eebdf4b725aeb2b10ab1e056a
F ext/wasm/config.make.in c424ae1cc3c89274520ad312509d36c4daa34a3fce5d0c688e5f8f4365e1049a
F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed
F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508
@@ -629,10 +625,10 @@ F ext/wasm/fiddle/fiddle.js 84fd75967e0af8b69d3dd849818342227d0f81d13db92e0dcbc6
F ext/wasm/fiddle/index.html a27b8127ef9ecf19612da93b2a6a73bdb3777b5c56b5450bb7200a94bc108ff9
F ext/wasm/index-dist.html db23748044e286773f2768eec287669501703b5d5f72755e8db73607dc54d290
F ext/wasm/index.html 54e27db740695ab2cb296e02d42c4c66b3f11b65797340d19fa6590f5b287da1
F ext/wasm/jaccwabyt/jaccwabyt.js bbac67bc7a79dca34afe6215fd16b27768d84e22273507206f888c117e2ede7d
F ext/wasm/jaccwabyt/jaccwabyt.js 1e734c624205cdf621f322972dfb0fc8013d573a5882f57492a6830e5ec23e17
F ext/wasm/jaccwabyt/jaccwabyt.md 167fc0b624c9bc2c477846e336de9403842d81b1a24fc4d3b24317cb9eba734f
F ext/wasm/mkdist.sh 64d53f469c823ed311f6696f69cec9093f745e467334b34f5ceabdf9de3c5b28 x
F ext/wasm/mkwasmbuilds.c 1b53c4d2a1350c19a96a8cdfbda6a39baea9d2142bfe0cbef0ccb0e898787f47
F ext/wasm/mkdist.sh f774603c758e87fb115ceae192670aa10eeece9474ce2147671156d2e665b871 x
F ext/wasm/mkwasmbuilds.c 8f945702c48aa55d8f3a801bde70f1a2c7a8364f38defc1e026bd0628280aee8
F ext/wasm/module-symbols.html e54f42112e0aac2a31f850ab33e7f2630a2ea4f63496f484a12469a2501e07e2
F ext/wasm/scratchpad-wasmfs.html a3d7388f3c4b263676b58b526846e9d02dfcb4014ff29d3a5040935286af5b96
F ext/wasm/scratchpad-wasmfs.mjs 66034b9256b218de59248aad796760a1584c1dd842231505895eff00dbd57c63
@@ -646,9 +642,9 @@ F ext/wasm/sql/000-mandelbrot.sql 775337a4b80938ac8146aedf88808282f04d02d983d826
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/tester1-worker.c-pp.html 883881eeac14eeeecc8ff22acf9fe0f18a97cacb48be08ebb0bae891ceded584
F ext/wasm/tester1.c-pp.html 949920126dcf477925d8d540093d9cc374d3ab4c4ddee920c1dcadcf37917306
F ext/wasm/tester1.c-pp.js 2b014884dadf28928fabcb688746ca87145673eef75e154486505a266203fc15
F ext/wasm/tester1-worker.c-pp.html 0e432ec2c0d99cd470484337066e8d27e7aee4641d97115338f7d962bf7b081a
F ext/wasm/tester1.c-pp.html 52d88fe2c6f21a046030a36410b4839b632f4424028197a45a3d5669ea724ddb
F ext/wasm/tester1.c-pp.js 2c255093205a0dac9dae7475030665c2c9d6dccc857de68ee7daf49aa82e6de8
F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e
F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
@@ -658,7 +654,7 @@ F ext/wasm/tests/opfs/sahpool/index.html be736567fd92d3ecb9754c145755037cbbd2bca
F ext/wasm/tests/opfs/sahpool/sahpool-pausing.js f264925cfc82155de38cecb3d204c36e0f6991460fff0cb7c15079454679a4e2
F ext/wasm/tests/opfs/sahpool/sahpool-worker.js bd25a43fc2ab2d1bafd8f2854ad3943ef673f7c3be03e95ecf1612ff6e8e2a61
F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0
F main.mk 00dd631c66c1f7922b2d691631163899eff1c3d1da780ff37a62f8d997b368e1
F main.mk 29078d11f7545a8fae4347305b164bb4e777b801da16baeb48214014a8d63a06
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421
@@ -675,11 +671,11 @@ F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc
F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523
F src/bitvec.c e242d4496774dfc88fa278177dd23b607dce369ccafb3f61b41638eea2c9b399
F src/btmutex.c 30dada73a819a1ef5b7583786370dce1842e12e1ad941e4d05ac29695528daea
F src/btree.c cb5b8ceb9baa02a63a2f83dec09c4153e1cfbdf9c2adef5c62c26d2160eeb067
F src/btree.c 0ad524883ec4ccac3221c97bdc2c5d5f6e149504e14cf269bbed31362c3f4393
F src/btree.h e823c46d87f63d904d735a24b76146d19f51f04445ea561f71cc3382fd1307f0
F src/btreeInt.h 9c0f9ea5c9b5f4dcaea18111d43efe95f2ac276cd86d770dce10fd99ccc93886
F src/build.c 611e07299d72ff04bbcb9e7109183467e30925d203c3e121ef9bb3cf6876289b
F src/callback.c acae8c8dddda41ee85cfdf19b926eefe830f371069f8aadca3aa39adf5b1c859
F src/callback.c afa59adfaa483f668260ce69f740c8273dee3e6fee9106846e0499ebdd1ac076
F src/carray.c ff6081a31878fc34df8fa1052a9cbf17ddc22652544dcb3e2326886ed1053b55
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/date.c e19e0cfff9a41bfdd884c655755f6f00bca4c1a22272b56e0dd6667b7ea893a2
@@ -691,15 +687,15 @@ F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f
F src/func.c 0b802107498048d3dcac0b757720bcb8506507ce02159e213ab8161458eb293b
F src/global.c a19e4b1ca1335f560e9560e590fc13081e21f670643367f99cb9e8f9dc7d615b
F src/hash.c 73934a7f7ab1cb110614a9388cb516893b0cf5b7b69e4fd1a0780ac4ce166be7
F src/hash.h 46b92795a95bfefb210f52f0c316e9d7cdbcdd7e7fcfb0d8be796d3a5767cddf
F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6
F src/hash.c dff10fa89d4a8280b764df9599b29342ea98cba2b868dccb5dfb3c419841a3f0
F src/hash.h c5f4a02aaf1dca835a68b51c8b906af265c6ca3d8d53d255e0453f0abce561be
F src/hwtime.h d4d1b98c1afdc56986a5c0eba882786ef017e2180a320da25b4231b8e7e463e8
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c dfd311b0ac2d4f6359e62013db67799757f4d2cc56cca5c10f4888acfbbfa3fd
F src/json.c fb031340edee159c07ad37dbe668ffe945ed86f525b0eb3822e4a67cbc498a72
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c a3bc9a2522dc3b960e38b7582d1818f6245a49289387c2c7b19f27bfeabf1e81
F src/main.c ce69a2650e3d359ed6a8a2867ccafb27ac62ce1d39f3120a84ff513320952a6c
F src/main.c eaf5215917b7e8b34ddea013524287f6d5021ba0fc70202e7602e225ef0d16bf
F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
@@ -723,7 +719,7 @@ F src/os_setup.h 8efc64eda6a6c2f221387eefc2e7e45fd5a3d5c8337a7a83519ba4fbd2957ae
F src/os_unix.c 7945ede1e85b2d1b910e1b4af9ba342e964b1e30e79f4176480a60736445cb36
F src/os_win.c a89b501fc195085c7d6c9eec7f5bd782625e94bb2a96b000f4d009703df1083f
F src/os_win.h 4c247cdb6d407c75186c94a1e84d5a22cbae4adcec93fcae8d2bc1f956fd1f19
F src/pager.c cd562b878ea1b44d021ba199abc9d3b54f6b3347500a9fed03f66d6000620945
F src/pager.c a81461de271ac4886ad75b7ca2cca8157a48635820c4646cd2714acdc2c17e5f
F src/pager.h 6137149346e6c8a3ddc1eeb40aee46381e9bc8b0fcc6dda8a1efde993c2275b8
F src/parse.y 619c3e92a54686c5e47923688c4b9bf7ec534a4690db5677acc28b299c403250
F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
@@ -736,8 +732,8 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
F src/resolve.c 5616fbcf3b833c7c705b24371828215ad0925d0c0073216c4f153348d5753f0a
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c ba9cd07ffa3277883c1986085f6ddc4320f4d35d5f212ab58df79a7ecc1a576a
F src/shell.c.in 265015aaec4580a0bef50ff570ec8d2813498ee49dcfdf9757e76f3b2a59fc97
F src/sqlite.h.in f7944026ee89ea348f89aec56372d6d25b6cafc1d89df741278d6917e86326a3
F src/shell.c.in ceb0a9cc008ac82d8d2e6ef353db14a54bc40dfd60a8cfbb6bc98d071f538761
F src/sqlite.h.in 684c19c3b093cca7a38e3f6405d067777464285f17a58a78f7f89d6763e011e7
F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
F src/sqlite3ext.h 7f236ca1b175ffe03316d974ef57df79b3938466c28d2f95caef5e08c57f3a52
F src/sqliteInt.h 88f7fc9ce1630d9a5f7e0a8e1f3287cdc63882fba985c18e7eee1b9f457f59aa
@@ -746,7 +742,7 @@ F src/status.c 7565d63a79aa2f326339a24a0461a60096d0bd2bce711fefb50b5c89335f3592
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
F src/tclsqlite.c 3c604c49e6cf4211960a9ddb9505280fd22cde32175f40884c641c0f5a286036
F src/tclsqlite.h 614b3780a62522bc9f8f2b9fb22689e8009958e7aa77e572d0f3149050af348a
F src/test1.c f880ab766eeedf2c063662bd9538b923fd42c4341b7bfc2150a6d93ab8b9341c
F src/test1.c d27c91455865fb191eb1b2c892e7586c5e3d9d3977f54913c8e70e2e8e5148b3
F src/test2.c 62f0830958f9075692c29c6de51b495ae8969e1bef85f239ffcd9ba5fb44a5ff
F src/test3.c 432646f581d8af1bb495e58fc98234380250954f5d5535e507fc785eccc3987a
F src/test4.c 0ac87fc13cdb334ab3a71823f99b6c32a6bebe5d603cd6a71d84c823d43a25a0
@@ -805,7 +801,7 @@ F src/vacuum.c 1bacdd0a81d2b5dc1c508fbf0d938c89fa78dd8d5b46ec92686d44030d4f4789
F src/vdbe.c b44c366e83412d3b8c190feb1f029b7d02e1bd69252a57b32f195107f0d03964
F src/vdbe.h be33bd7b17f2ec92939642416030491508c51071f6c14e27cd195983fec56b63
F src/vdbeInt.h 2aaeb6df2938b181b4700a9328688a3986f2bba71e8b96f6a80671316618fa49
F src/vdbeapi.c 869a0da5d855495055f4d35c6ada582f64ce995ce14b26ff9d336274d497266c
F src/vdbeapi.c 6a2181cfd27c86b4cc1d8abb27ae11f3b3f0357567814fa276ec37b043542938
F src/vdbeaux.c 908d8a191aed444b2e4c920159249127f3ff67b94c56a16fad1dfdf9c7488f20
F src/vdbeblob.c b3f0640db9642fbdc88bd6ebcc83d6009514cafc98f062f675f2c8d505d82692
F src/vdbemem.c 48e562ff27e6386eb8613207ac27d3d98c1f67fdc4775a1ab13759d2c2a1c021
@@ -1429,7 +1425,7 @@ F test/misc5.test 02fcaf4d42405be02ec975e946270a50b0282dac98c78303ade0d1392839d2
F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
F test/misc7.test d595599972ec0b436985f0f02f243b68500ffc977b9b3194ec66c0866cfddcab
F test/misc8.test 08d2380bc435486b12161521f225043ac2be26f02471c2c1ea4cac0b1548edbd
F test/misuse.test 46d42ffdf375833ea5828796e56f84660344f7548659b493059f152f00e66840
F test/misuse.test 859f37014d9824ca66bd90c36372c08c80c51c9593a7cfa8a31d4f92cd4d5b7f
F test/mjournal.test 28a08d5cb5fb5b5702a46e19176e45e964e0800d1f894677169e79f34030e152
F test/mmap1.test 18de3fd7b70a777af6004ca2feecfcdd3d0be17fa04058e808baf530c94b1a1d
F test/mmap2.test dba452dc7db91e9df10f70bdd73dc4190c7b8ee7b5133b4684f04277ada0b9ac
@@ -1526,7 +1522,7 @@ F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2
F test/reservebytes.test 6163640b5a5120c0dee6591481e673a0fa0bf0d12d4da7513bad692c1a49a162
F test/resetdb.test 54c06f18bc832ac6d6319e5ab23d5c8dd49fdbeec7c696d791682a8006bd5fc3
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
F test/returning1.test 212cd4111bb941a60abf608f20250db666c21eb1bc4d49217e96c87ff3ab9d1a
F test/returning1.test cd32517148948859db214dd814354597dd40e7489259590fac1a4f7bf44deb97
F test/returningfault.test ae4c4b5e8745813287a359d9ccdb9d5c883c2e68afb18fb0767937d5de5692a4
F test/rollback.test 952c4d805bca96adc2be76f621ea22115fe40b330015af36fcc8028c8547fcee
F test/rollback2.test 3f3a4e20401825017df7e7671e9f31b6de5fae5620c2b9b49917f52f8c160a8f
@@ -1693,7 +1689,7 @@ F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
F test/tester.tcl 463ae33b8bf75ac77451df19bd65e7c415c2e9891227c7c9e657d0a2d8e1074a
F test/testloadext.c 862b848783eaed9985fbce46c65cd214664376b549fae252b364d5d1ef350a27
F test/testrunner.tcl 60d7efa1816c5dfc37df3e3454b94b9042c0c8c50b27ae296d4a797cd309ace6 x
F test/testrunner.tcl 86179a8e78997e9257cb8f738c5624cb23897da5297855578ba74715e64f1602 x
F test/testrunner_data.tcl c507a9afa911c03446ed90442ffd4a98aca02882c3d51bd1177c24795674def8
F test/testrunner_estwork.tcl 7927a84327259a32854926f68a75292e33a61e7e052fdbfcb01f18696c99c724
F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899
@@ -2171,11 +2167,11 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P ccabbe06d4e0650eecc91296d6a3040ed7fef06b47e4d63393a2367c8c8f55cf
R 9324db4aaf883cfc2983724be7d6c4b2
T +sym-major-release *
T +sym-release *
T +sym-version-3.51.0 *
U drh
Z bd3359fae465c4238136a20bd4edb791
P 42f95ea71e5e7e927685de3a6da2ede38abe7cabdd1fc71b9a14bebe9f54a65e
R 6ccca5a4124b16122b6a766379fbe805
T *branch * sqlite3-node.mjs
T *sym-sqlite3-node.mjs *
T -sym-trunk * Cancelled\sby\sbranch.
U stephan
Z 351cb48117de9374caee3897f1c40064
# Remove this line to create a well-formed Fossil manifest.
+2 -5
View File
@@ -1,5 +1,2 @@
branch trunk
tag trunk
tag release
tag major-release
tag version-3.51.0
branch sqlite3-node.mjs
tag sqlite3-node.mjs
+1 -1
View File
@@ -1 +1 @@
fb2c931ae597f8d00a37574ff67aeed3eced4e5547f9120744ae4bfa8e74527b
8611cf643b11335cd490da1856c34b4f10ac8b82856e0857be1192e36da31f17
+1 -1
View File
@@ -9758,7 +9758,7 @@ int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){
}while( rc==SQLITE_OK && nOut>0 );
if( rc==SQLITE_OK && nRem>0 && ALWAYS(pPgnoOut) ){
Pgno pgnoNew;
Pgno pgnoNew = 0; /* Prevent harmless static-analyzer warning */
MemPage *pNew = 0;
rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
put4byte(pPgnoOut, pgnoNew);
+10 -2
View File
@@ -504,8 +504,16 @@ void sqlite3SchemaClear(void *p){
temp2 = pSchema->trigHash;
sqlite3HashInit(&pSchema->trigHash);
sqlite3HashClear(&pSchema->idxHash);
for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
sqlite3DeleteTrigger(&xdb, (Trigger*)sqliteHashData(pElem));
for(pElem=sqliteHashFirst(&temp2); pElem; ){
HashElem *pNext = sqliteHashNext(pElem);
Trigger *pTrig = (Trigger*)sqliteHashData(pElem);
if( pTrig->bReturning ){
/* Do not remove RETURNING triggers from the temp-triggers hash */
sqlite3HashTransfer(&pSchema->trigHash, &temp2, pElem);
}else{
sqlite3DeleteTrigger(&xdb, pTrig);
}
pElem = pNext;
}
sqlite3HashClear(&temp2);
sqlite3HashInit(&pSchema->tblHash);
+23
View File
@@ -270,3 +270,26 @@ void *sqlite3HashInsert(Hash *pH, const char *pKey, void *data){
insertElement(pH, pH->ht ? &pH->ht[new_elem->h % pH->htsize] : 0, new_elem);
return 0;
}
/*
** Parameter pElem is currently part of hash table pFrom. Add it to hash
** table pTo.
**
** This procedure corrupts hash table pFrom. Specifically, it removes element
** pElem from the list of all elements in the hash table, but may leave
** a pointer to it in one of the hash buckets of pFrom. This is not a problem
** because this function is only called if hash table pFrom will be cleared
** before any further lookups or inserts are attempted.
*/
void sqlite3HashTransfer(Hash *pTo, Hash *pFrom, HashElem *pElem){
if( pElem->prev ){
pElem->prev->next = pElem->next;
}else{
assert( pFrom->first==pElem );
pFrom->first = pElem->next;
}
pTo->count++;
insertElement(pTo, pTo->ht ? &pTo->ht[pElem->h % pTo->htsize] : 0, pElem);
}
+1
View File
@@ -70,6 +70,7 @@ void sqlite3HashInit(Hash*);
void *sqlite3HashInsert(Hash*, const char *pKey, void *pData);
void *sqlite3HashFind(const Hash*, const char *pKey);
void sqlite3HashClear(Hash*);
void sqlite3HashTransfer(Hash*, Hash*, HashElem *pElem);
/*
** Macros for looping over all elements of a hash table. The idiom is
+19 -21
View File
@@ -16,17 +16,18 @@
#ifndef SQLITE_HWTIME_H
#define SQLITE_HWTIME_H
/*
** The following routine only works on Pentium-class (or newer) processors.
** It uses the RDTSC opcode to read the cycle count value out of the
** processor and returns that value. This can be used for high-res
** profiling.
*/
#if !defined(__STRICT_ANSI__) && \
(defined(__GNUC__) || defined(_MSC_VER)) && \
(defined(i386) || defined(__i386__) || defined(_M_IX86))
#if defined(_MSC_VER) && defined(_WIN32)
#if defined(__GNUC__)
#include <profileapi.h>
__inline sqlite3_uint64 sqlite3Hwtime(void){
LARGE_INTEGER tm;
QueryPerformanceCounter(&tm);
return (sqlite3_uint64)tm.QuadPart;
}
#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && \
(defined(i386) || defined(__i386__) || defined(_M_IX86))
__inline__ sqlite_uint64 sqlite3Hwtime(void){
unsigned int lo, hi;
@@ -34,17 +35,6 @@
return (sqlite_uint64)hi << 32 | lo;
}
#elif defined(_MSC_VER)
__declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
__asm {
rdtsc
ret ; return value at EDX:EAX
}
}
#endif
#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__))
__inline__ sqlite_uint64 sqlite3Hwtime(void){
@@ -52,6 +42,14 @@
__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
return (sqlite_uint64)hi << 32 | lo;
}
#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__aarch64__)
__inline__ sqlite_uint64 sqlite3Hwtime(void){
sqlite3_uint64 cnt;
__asm__ __volatile__ ("mrs %0, cntvct_el0" : "=r" (cnt));
return cnt;
}
#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__))
+11 -1
View File
@@ -1394,6 +1394,7 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
/* Clear the TEMP schema separately and last */
if( db->aDb[1].pSchema ){
sqlite3SchemaClear(db->aDb[1].pSchema);
assert( db->aDb[1].pSchema->trigHash.count==0 );
}
sqlite3VtabUnlockList(db);
@@ -2525,6 +2526,9 @@ void *sqlite3_wal_hook(
sqlite3_mutex_leave(db->mutex);
return pRet;
#else
UNUSED_PARAMETER(db);
UNUSED_PARAMETER(xCallback);
UNUSED_PARAMETER(pArg);
return 0;
#endif
}
@@ -2540,6 +2544,11 @@ int sqlite3_wal_checkpoint_v2(
int *pnCkpt /* OUT: Total number of frames checkpointed */
){
#ifdef SQLITE_OMIT_WAL
UNUSED_PARAMETER(db);
UNUSED_PARAMETER(zDb);
UNUSED_PARAMETER(eMode);
UNUSED_PARAMETER(pnLog);
UNUSED_PARAMETER(pnCkpt);
return SQLITE_OK;
#else
int rc; /* Return code */
@@ -2722,7 +2731,7 @@ const char *sqlite3_errmsg(sqlite3 *db){
*/
int sqlite3_set_errmsg(sqlite3 *db, int errcode, const char *zMsg){
int rc = SQLITE_OK;
if( !sqlite3SafetyCheckSickOrOk(db) ){
if( !sqlite3SafetyCheckOk(db) ){
return SQLITE_MISUSE_BKPT;
}
sqlite3_mutex_enter(db->mutex);
@@ -4902,6 +4911,7 @@ const char *sqlite3_filename_journal(const char *zFilename){
}
const char *sqlite3_filename_wal(const char *zFilename){
#ifdef SQLITE_OMIT_WAL
UNUSED_PARAMETER(zFilename);
return 0;
#else
zFilename = sqlite3_filename_journal(zFilename);
+4
View File
@@ -813,6 +813,8 @@ int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){
(void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
if( iRead ) return 0; /* Case (4) */
}
#else
UNUSED_PARAMETER(pgno);
#endif
assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 );
if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd)
@@ -4192,6 +4194,8 @@ int sqlite3PagerClose(Pager *pPager, sqlite3 *db){
sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a);
pPager->pWal = 0;
}
#else
UNUSED_PARAMETER(db);
#endif
pager_reset(pPager);
if( MEMDB ){
+27 -23
View File
@@ -7225,39 +7225,42 @@ static void clearTempFile(ShellState *p){
p->zTempFile = 0;
}
/* Forward reference */
static char *find_home_dir(int clearFlag);
/*
** Create a new temp file name with the given suffix.
**
** Because the classic temp folders like /tmp are no longer
** accessible to web browsers, for security reasons, create the
** temp file in the user's home directory.
*/
static void newTempFile(ShellState *p, const char *zSuffix){
char *zHome; /* Home directory */
int i; /* Loop counter */
sqlite3_uint64 r = 0; /* Integer with 64 bits of randomness */
char zRand[32]; /* Text string with 160 bits of randomness */
#ifdef _WIN32
const char cDirSep = '\\';
#else
const char cDirSep = '/';
#endif
for(i=0; i<31; i++){
if( (i%12)==0 ) sqlite3_randomness(sizeof(r),&r);
zRand[i] = "0123456789abcdefghijklmnopqrstuvwxyz"[r%36];
r /= 36;
}
zRand[i] = 0;
clearTempFile(p);
sqlite3_free(p->zTempFile);
p->zTempFile = 0;
if( p->db ){
sqlite3_file_control(p->db, 0, SQLITE_FCNTL_TEMPFILENAME, &p->zTempFile);
}
if( p->zTempFile==0 ){
/* If p->db is an in-memory database then the TEMPFILENAME file-control
** will not work and we will need to fallback to guessing */
char *zTemp;
sqlite3_uint64 r;
sqlite3_randomness(sizeof(r), &r);
zTemp = getenv("TEMP");
if( zTemp==0 ) zTemp = getenv("TMP");
if( zTemp==0 ){
#ifdef _WIN32
zTemp = "\\tmp";
#else
zTemp = "/tmp";
#endif
}
p->zTempFile = sqlite3_mprintf("%s/temp%llx.%s", zTemp, r, zSuffix);
}else{
p->zTempFile = sqlite3_mprintf("%z.%s", p->zTempFile, zSuffix);
}
zHome = find_home_dir(0);
p->zTempFile = sqlite3_mprintf("%s%ctemp-%s.%s",
zHome,cDirSep,zRand,zSuffix);
shell_check_oom(p->zTempFile);
}
/*
** The implementation of SQL scalar function fkey_collate_clause(), used
** by the ".lint fkey-indexes" command. This scalar function is always
@@ -9261,6 +9264,7 @@ static int do_meta_command(char *zLine, ShellState *p){
}
p->showHeader = savedShowHeader;
p->shellFlgs = savedShellFlags;
rc = p->nErr>0;
}else
if( c=='e' && cli_strncmp(azArg[0], "echo", n)==0 ){
+15 -11
View File
@@ -2567,12 +2567,15 @@ struct sqlite3_mem_methods {
** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]]
** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt>
** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in
** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears
** a flag that enables collection of the sqlite3_stmt_scanstatus_v2()
** statistics. For statistics to be collected, the flag must be set on
** the database handle both when the SQL statement is prepared and when it
** is stepped. The flag is set (collection of statistics is enabled)
** by default. <p>This option takes two arguments: an integer and a pointer to
** [SQLITE_ENABLE_STMT_SCANSTATUS] builds. In this case, it sets or clears
** a flag that enables collection of run-time performance statistics
** used by [sqlite3_stmt_scanstatus_v2()] and the [nexec and ncycle]
** columns of the [bytecode virtual table].
** For statistics to be collected, the flag must be set on
** the database handle both when the SQL statement is
** [sqlite3_prepare|prepared] and when it is [sqlite3_step|stepped].
** The flag is set (collection of statistics is enabled) by default.
** <p>This option takes two arguments: an integer and a pointer to
** an integer. The first argument is 1, 0, or -1 to enable, disable, or
** leave unchanged the statement scanstatus option. If the second argument
** is not NULL, then the value of the statement scanstatus setting after
@@ -4217,7 +4220,7 @@ const char *sqlite3_errstr(int);
int sqlite3_error_offset(sqlite3 *db);
/*
** CAPI3REF: Set Error Codes And Message
** CAPI3REF: Set Error Code And Message
** METHOD: sqlite3
**
** Set the error code of the database handle passed as the first argument
@@ -10426,7 +10429,7 @@ int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle);
** &nbsp; ){
** &nbsp; // do something with pVal
** &nbsp; }
** &nbsp; if( rc!=SQLITE_OK ){
** &nbsp; if( rc!=SQLITE_DONE ){
** &nbsp; // an error has occurred
** &nbsp; }
** </pre></blockquote>)^
@@ -10598,9 +10601,9 @@ int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
** a variable pointed to by the "pOut" parameter.
**
** The "flags" parameter must be passed a mask of flags. At present only
** one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX
** one flag is defined - [SQLITE_SCANSTAT_COMPLEX]. If SQLITE_SCANSTAT_COMPLEX
** is specified, then status information is available for all elements
** of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If
** of a query plan that are reported by "[EXPLAIN QUERY PLAN]" output. If
** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements
** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of
** the EXPLAIN QUERY PLAN output) are available. Invoking API
@@ -10614,7 +10617,8 @@ int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
** elements used to implement the statement - a non-zero value is returned and
** the variable that pOut points to is unchanged.
**
** See also: [sqlite3_stmt_scanstatus_reset()]
** See also: [sqlite3_stmt_scanstatus_reset()] and the
** [nexec and ncycle] columnes of the [bytecode virtual table].
*/
int sqlite3_stmt_scanstatus(
sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
+32
View File
@@ -4972,6 +4972,37 @@ static int SQLITE_TCLAPI test_errmsg16(
return TCL_OK;
}
/*
** Usage: sqlite3_set_errmsg DB ERRCODE ERRMSG
*/
static int SQLITE_TCLAPI test_set_errmsg(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
const char *zDb = 0;
const char *zErr = 0;
int iErr = 0;
sqlite3 *db = 0;
int rc;
if( objc!=4 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB ERRCODE ERRMSG");
return TCL_ERROR;
}
zDb = Tcl_GetString(objv[1]);
if( zDb[0] ){
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
}
if( Tcl_GetIntFromObj(interp, objv[2], &iErr) ) return TCL_ERROR;
zErr = Tcl_GetString(objv[3]);
rc = sqlite3_set_errmsg(db, iErr, (zErr[0] ? zErr : 0));
Tcl_SetResult(interp, (char *)t1ErrorName(rc), 0);
return TCL_OK;
}
/*
** Usage: sqlite3_prepare DB sql bytes ?tailvar?
**
@@ -9077,6 +9108,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite3_errmsg", test_errmsg ,0 },
{ "sqlite3_error_offset", test_error_offset ,0 },
{ "sqlite3_errmsg16", test_errmsg16 ,0 },
{ "sqlite3_set_errmsg", test_set_errmsg ,0 },
{ "sqlite3_open", test_open ,0 },
{ "sqlite3_open16", test_open16 ,0 },
{ "sqlite3_open_v2", test_open_v2 ,0 },
+2
View File
@@ -736,6 +736,8 @@ static int doWalCallbacks(sqlite3 *db){
}
}
}
#else
UNUSED_PARAMETER(db);
#endif
return rc;
}
+12
View File
@@ -211,4 +211,16 @@ if {[clang_sanitize_address]==0 && 0} {
} {1 {(21) bad parameter or other API misuse}}
}
#-------------------------------------------------------------------------
reset_db
do_test misuse-6.0 {
sqlite3_set_errmsg db 1 "an error has occurred"
} {SQLITE_OK}
do_test misuse-6.1 {
sqlite3_errmsg db
} {an error has occurred}
do_test misuse-6.2 {
sqlite3_set_errmsg "" 1 "an error has occurred"
} {SQLITE_MISUSE}
finish_test
+50
View File
@@ -544,4 +544,54 @@ do_catchsql_test 22.1 {
} {1 {no such column: sqlite_master.name}}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 23.0 {
PRAGMA recursive_triggers = 1;
CREATE TABLE t1(x, y);
CREATE TRIGGER t1insert AFTER INSERT ON t1 WHEN new.x<5 BEGIN
INSERT INTO t1 VALUES(new.x+1, new.y);
END;
}
do_execsql_test 23.1 {
INSERT INTO t1 VALUES(1, 'one') RETURNING *;
} {1 one}
do_execsql_test 23.2 {
SELECT * FROM t1
} {1 one 2 one 3 one 4 one 5 one}
#-------------------------------------------------------------------------
reset_db
ifcapable fts5 {
do_execsql_test 24.0 {
CREATE VIRTUAL TABLE ft USING fts5(c);
CREATE TABLE t1(x);
INSERT INTO t1 VALUES('x');
}
db close
sqlite3 db test.db
sqlite3 db2 test.db
do_execsql_test 24.1 {
SELECT * FROM t1
} {x}
do_execsql_test -db db2 24.2 {
CREATE TABLE t2(y);
INSERT INTO t2 VALUES('y');
} {}
db2 close
do_execsql_test 24.3 {
INSERT INTO ft VALUES('hello world') RETURNING *
} {{hello world}}
}
finish_test
+20
View File
@@ -1269,6 +1269,26 @@ proc add_fuzztest_jobs {buildname patternlist} {
set subcmd [lrange $interpreter 1 end]
set interpreter [lindex $interpreter 0]
# For fuzzcheck-asan and fuzzcheck-ubsan, break up some
# fuzzdata files into multiple slices, for improved
# concurrency.
#
if {[string match *fuzzcheck-*san $interpreter]} {
set newscripts {}
foreach s $scripts {
if {[string match {*fuzzdata[12].db} $s]
&& ![string match slice $s]} {
set N 6
for {set i 0} {$i<$N} {incr i} {
lappend newscripts [list --slice $i $N $s]
}
} else {
lappend newscripts $s
}
}
set scripts $newscripts
}
if {[string match fuzzcheck* $interpreter]
&& [info exists env(FUZZDB)]
&& [file readable $env(FUZZDB)]