** Which sqlite3.c we're using needs to be configurable to enable
** building against a custom copy, e.g. the SEE variant. We have to
** include sqlite3.c, as opposed to sqlite3.h, in order to get access
-** to some internal details like SQLITE_MAX_... and friends. This
-** increases the rebuild time considerably but we need this in order
-** to access some internal functionality and keep the to-Java-exported
-** values of SQLITE_MAX_... and SQLITE_LIMIT_... in sync with the C
-** build.
+** to some internal details like SQLITE_MAX_... and friends, and keep
+** those consistent with this build. This increases the rebuild time
+** considerably, however.
*/
#ifndef SQLITE_C
# define SQLITE_C sqlite3.c
const char * const zMember /* Name of member property */;
const char * const zTypeSig /* JNI type signature of zMember */;
/*
- ** klazz is a global ref to the class represented by pRef.
+ ** klazz is a global ref to the class represented by zName.
**
** According to:
**
** JNI bindings such as sqlite3_prepare_v2/v3(), and definitely not
** from client code.
**
-** Returns err_code.
+** Returns err_code _unless_ err_code is 0 and sqlite3_set_errmsg()
+** fails with OOM, in which case it may return SQLITE_OOM or fail
+** fatally.
+**
+** This function predates sqlite3_set_errmsg(), which is why it has a
+** slightly different interface. Before that function was introduced,
+** this code used the SQLite-internal APIs to do this.
*/
-static int s3jni_db_error(sqlite3* const db, int err_code,
- const char * const zMsg){
+static int s3jni_db_error(JNIEnv * env, sqlite3* const db,
+ int err_code, const char * const zMsg){
if( db!=0 ){
- if( 0==zMsg ){
- sqlite3Error(db, err_code);
- }else{
- const int nMsg = sqlite3Strlen30(zMsg);
- sqlite3_mutex_enter(sqlite3_db_mutex(db));
- sqlite3ErrorWithMsg(db, err_code, "%.*s", nMsg, zMsg);
- sqlite3_mutex_leave(sqlite3_db_mutex(db));
- }
+ int const rc = sqlite3_set_errmsg(db, err_code, zMsg);
+ s3jni_oom_fatal(0==rc);
+ if( rc && !err_code ) err_code=rc;
}
return err_code;
}
char * zMsg;
S3JniExceptionClear;
zMsg = s3jni_exception_error_msg(env, ex);
- s3jni_db_error(pDb, errCode, zMsg ? zMsg : zDfltMsg);
+ s3jni_db_error(env, pDb, errCode, zMsg ? zMsg : zDfltMsg);
sqlite3_free(zMsg);
S3JniUnrefLocal(ex);
}else if( zDfltMsg ){
- s3jni_db_error(pDb, errCode, zDfltMsg);
+ s3jni_db_error(env, pDb, errCode, zDfltMsg);
}
return errCode;
}
S3JniDb_mutex_enter;
ps = S3JniDb_from_jlong(jpDb);
if( !ps ){
- s3jni_db_error(ps->pDb, SQLITE_MISUSE, 0);
+ s3jni_db_error(env, ps->pDb, SQLITE_MISUSE, 0);
S3JniDb_mutex_leave;
return 0;
}
else sqlite3_rollback_hook(ps->pDb, 0, 0);
}else{
jclass const klazz = (*env)->GetObjectClass(env, jHook);
- jmethodID const xCallback = (*env)->GetMethodID(env, klazz, "call",
- isCommit ? "()I" : "()V");
+ jmethodID const xCallback =
+ (*env)->GetMethodID(env, klazz, "call",
+ isCommit ? "()I" : "()V");
S3JniUnrefLocal(klazz);
S3JniIfThrew {
S3JniExceptionReport;
S3JniExceptionClear;
- s3jni_db_error(ps->pDb, SQLITE_ERROR,
+ s3jni_db_error(env, ps->pDb, SQLITE_ERROR,
"Cannot not find matching call() method in"
"hook object.");
}else{
(*env)->GetMethodID(env, klazz, "call", "([B[B)I");
S3JniUnrefLocal(klazz);
S3JniIfThrew{
- rc = s3jni_db_error(ps->pDb, SQLITE_ERROR,
+ rc = s3jni_db_error(env, ps->pDb, SQLITE_ERROR,
"Could not get call() method from "
"CollationCallback object.");
}else{
if( !pDb || !jFuncName ){
return SQLITE_MISUSE;
}else if( !encodingTypeIsValid(eTextRep) ){
- return s3jni_db_error(pDb, SQLITE_FORMAT,
+ return s3jni_db_error(env, pDb, SQLITE_FORMAT,
"Invalid function encoding option.");
}
s = S3JniUdf_alloc(env, jFunctor);
if( !s ) return SQLITE_NOMEM;
if( UDF_UNKNOWN_TYPE==s->type ){
- rc = s3jni_db_error(pDb, SQLITE_MISUSE,
+ rc = s3jni_db_error(env, pDb, SQLITE_MISUSE,
"Cannot unambiguously determine function type.");
S3JniUdf_free(env, s, 1);
goto error_cleanup;
zStr = jStr
? s3jni_jstring_to_utf8( jStr, 0)
: NULL;
- rc = s3jni_db_error( ps->pDb, (int)jRc, zStr );
+ rc = s3jni_db_error(env, ps->pDb, (int)jRc, zStr );
sqlite3_free(zStr);
}
return rc;
jTable = jDbName ? s3jni_utf8_to_jstring( zTable, -1) : 0;
S3JniIfThrew {
S3JniExceptionClear;
- s3jni_db_error(ps->pDb, SQLITE_NOMEM, 0);
+ s3jni_db_error(env, ps->pDb, SQLITE_NOMEM, 0);
}else{
assert( hook.jObj );
assert( hook.midCallback );
S3JniUnrefLocal(klazz);
S3JniIfThrew {
S3JniExceptionClear;
- s3jni_db_error(ps->pDb, SQLITE_ERROR,
+ s3jni_db_error(env, ps->pDb, SQLITE_ERROR,
"Cannot not find matching callback on "
"(pre)update hook object.");
}else{
S3JniUnrefLocal(klazz);
S3JniIfThrew {
S3JniExceptionClear;
- s3jni_db_error(ps->pDb, SQLITE_ERROR,
+ s3jni_db_error(env, ps->pDb, SQLITE_ERROR,
"Cannot not find matching xCallback() on "
"ProgressHandler object.");
}else{
")I");
S3JniUnrefLocal(klazz);
S3JniIfThrew {
- rc = s3jni_db_error(ps->pDb, SQLITE_ERROR,
- "Error setting up Java parts of authorizer hook.");
+ rc = s3jni_db_error(env, ps->pDb, SQLITE_ERROR,
+ "Error setting up Java parts of "
+ "authorizer hook.");
}else{
rc = sqlite3_set_authorizer(ps->pDb, s3jni_xAuth, ps);
}
S3JniUnrefLocal(klazz);
S3JniIfThrew {
S3JniExceptionClear;
- rc = s3jni_db_error(ps->pDb, SQLITE_ERROR,
+ rc = s3jni_db_error(env, ps->pDb, SQLITE_ERROR,
"Cannot not find matching call() on "
"TracerCallback object.");
}else{
-C Random\sJS\sbuild\scleanups\sand\sparallel\sbuild\smkdir\srace\sfixes.\sReinstate\sthe\srecently-removed\s[a65bd978cbc646ec]\safter\sfinding\sa\sreformulation\swhich\sworks\son\sEmscripten\s4.0.19\s(and\ssaves\sabout\s85kb\son\sthe\sJS\sdeliverables).
-D 2025-11-15T13:30:13.350
+C Replace\sthe\sJNI\sbinding's\sinternal\suse\sof\ssqlite3ErrorWithMsg()\swith\ssqlite3_set_errmsg()\sand\shave\sit\shandle\sOOM\sin\sa\sway\sconsistent\swith\sthe\srest\sof\sthe\sJNI\sbindings.
+D 2025-11-15T15:09:04.569
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F ext/jni/GNUmakefile 8a94e3a1953b88cf117fb2a5380480feada8b4f5316f02572cab425030a720b4
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.c b28ca2a083743dbc0f14dd0b41be30034a0284d66587060dfaf825e9d885a0fd
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 tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 2bd0addb6068cd2b34f6151a824c578e2253f541a8c55b578219b09c42afd82b
-R cb76483e55da810a9fb38d6425ffedc4
+P acb1525a49463de67716638626406ccde9a282907d0de218ab88bf474ba830ee
+R 401c7736be7e7154dc5b54d0e020a24a
U stephan
-Z 3f713550333ee0705fe41873843f5246
+Z b31456e0517faa0fcb62a707b78caf87
# Remove this line to create a well-formed Fossil manifest.