Add SQLTester dup() and dup_count() UDFs. Correct arg handling of the --run command.

FossilOrigin-Name: 0dba3073f44685a51a5db7ff8886295fe04dfd43f69cbf53ad3d5afce741076b
This commit is contained in:
stephan 2023-08-08 21:05:39 +00:00
parent 4d3aa08f67
commit c783fd36dc
4 changed files with 100 additions and 26 deletions

View File

@ -4016,9 +4016,90 @@ JDECLFtsXA(jobject,xUserData)(JENV_OSELF,jobject jFcx){
#endif /* SQLITE_ENABLE_FTS5 */ #endif /* SQLITE_ENABLE_FTS5 */
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// End of the main API bindings. What follows are internal utilities. // End of the main API bindings. Start of SQLTester bits...
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
typedef struct SQLTesterJni SQLTesterJni;
struct SQLTesterJni {
sqlite3_int64 nDup;
};
static SQLTesterJni SQLTester = {
0
};
static void SQLTester_dup_destructor(void*pToFree){
u64 *p = (u64*)pToFree;
assert( p!=0 );
p--;
assert( p[0]==0x2bbf4b7c );
p[0] = 0;
p[1] = 0;
sqlite3_free(p);
}
/*
** Implementation of
**
** dup(TEXT)
**
** This SQL function simply makes a copy of its text argument. But it
** returns the result using a custom destructor, in order to provide
** tests for the use of Mem.xDel() in the SQLite VDBE.
*/
static void SQLTester_dup_func(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
u64 *pOut;
char *z;
int n = sqlite3_value_bytes(argv[0]);
SQLTesterJni * const p = (SQLTesterJni *)sqlite3_user_data(context);
++p->nDup;
if( n>0 && (pOut = sqlite3_malloc( (n+16)&~7 ))!=0 ){
pOut[0] = 0x2bbf4b7c;
z = (char*)&pOut[1];
memcpy(z, sqlite3_value_text(argv[0]), n);
z[n] = 0;
sqlite3_result_text(context, z, n, SQLTester_dup_destructor);
}
return;
}
/*
** Return the number of calls to the dup() SQL function since the
** SQLTester context was opened or since the last dup_count() call.
*/
static void SQLTester_dup_count_func(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
SQLTesterJni * const p = (SQLTesterJni *)sqlite3_user_data(context);
sqlite3_result_int64(context, p->nDup);
p->nDup = 0;
}
static int SQLTester_auto_extension(sqlite3 *pDb, const char **pzErr,
const struct sqlite3_api_routines *ignored){
sqlite3_create_function(pDb, "dup", 1, SQLITE_UTF8, &SQLTester,
SQLTester_dup_func, 0, 0);
sqlite3_create_function(pDb, "dup_count", 0, SQLITE_UTF8, &SQLTester,
SQLTester_dup_count_func, 0, 0);
return 0;
}
JNIEXPORT void JNICALL
Java_org_sqlite_jni_tester_SQLTester_installCustomExtensions(JENV_CSELF){
sqlite3_auto_extension( (void(*)(void))SQLTester_auto_extension );
}
////////////////////////////////////////////////////////////////////////
// End of SQLTester bindings. Start of lower-level bits.
////////////////////////////////////////////////////////////////////////
/** /**
Uncaches the current JNIEnv from the S3JniGlobal state, clearing any Uncaches the current JNIEnv from the S3JniGlobal state, clearing any
resources owned by that cache entry and making that slot available resources owned by that cache entry and making that slot available
@ -4030,18 +4111,6 @@ Java_org_sqlite_jni_SQLite3Jni_uncacheJniEnv(JENV_CSELF){
return S3JniGlobal_env_uncache(env) ? JNI_TRUE : JNI_FALSE; return S3JniGlobal_env_uncache(env) ? JNI_TRUE : JNI_FALSE;
} }
static int SQLTester_auto_extension(sqlite3 *pDb, const char **pzErr,
const struct sqlite3_api_routines *ignored){
//MARKER(("TODO: DUP() UDF\n"));
return 0;
}
JNIEXPORT void JNICALL
Java_org_sqlite_jni_tester_SQLTester_installCustomExtensions(JENV_CSELF){
sqlite3_auto_extension( (void(*)(void))SQLTester_auto_extension );
}
/** /**
Called during static init of the SQLite3Jni class to sync certain Called during static init of the SQLite3Jni class to sync certain
compile-time constants to Java-space. compile-time constants to Java-space.

View File

@ -156,9 +156,9 @@ public class SQLTester {
int getCurrentDbId(){ return iCurrentDb; } int getCurrentDbId(){ return iCurrentDb; }
SQLTester affirmDbId(int n) throws Exception{ SQLTester affirmDbId(int n) throws IndexOutOfBoundsException {
if(n<0 || n>=aDb.length){ if(n<0 || n>=aDb.length){
Util.toss(IllegalArgumentException.class,"illegal db number."); throw new IndexOutOfBoundsException("illegal db number.");
} }
return this; return this;
} }
@ -169,6 +169,10 @@ public class SQLTester {
sqlite3 getCurrentDb(){ return aDb[iCurrentDb]; } sqlite3 getCurrentDb(){ return aDb[iCurrentDb]; }
sqlite3 getDbById(int id) throws Exception{
return affirmDbId(id).aDb[iCurrentDb];
}
void closeDb(int id) throws Exception{ void closeDb(int id) throws Exception{
final sqlite3 db = affirmDbId(id).aDb[id]; final sqlite3 db = affirmDbId(id).aDb[id];
if( null != db ){ if( null != db ){
@ -533,11 +537,12 @@ class ResultCommand extends Command {
class RunCommand extends Command { class RunCommand extends Command {
public RunCommand(SQLTester t, String[] argv, String content) throws Exception{ public RunCommand(SQLTester t, String[] argv, String content) throws Exception{
argcCheck(argv,0); argcCheck(argv,0,1);
affirmHasContent(content); affirmHasContent(content);
int rc = t.execSql(null, false, false, content); final sqlite3 db = (1==argv.length)
? t.getCurrentDb() : t.getDbById( Integer.parseInt(argv[1]) );
int rc = t.execSql(db, false, false, content);
if( 0!=rc ){ if( 0!=rc ){
sqlite3 db = t.getCurrentDb();
String msg = sqlite3_errmsg(db); String msg = sqlite3_errmsg(db);
t.verbose(argv[0]," non-fatal command error #",rc,": ", t.verbose(argv[0]," non-fatal command error #",rc,": ",
msg,"\nfor SQL:\n",content); msg,"\nfor SQL:\n",content);

View File

@ -1,5 +1,5 @@
C Correct\s--result\sarg\scount\scheck\sand\sadd\sinfrastructure\sto\slet\sus\sadd\scustom\sC-side\sbehavior\sto\sSQLTester\svia\san\sauto\sextension. C Add\sSQLTester\sdup()\sand\sdup_count()\sUDFs.\sCorrect\sarg\shandling\sof\sthe\s--run\scommand.
D 2023-08-08T20:41:29.013 D 2023-08-08T21:05:39.810
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -232,7 +232,7 @@ F ext/icu/icu.c c074519b46baa484bb5396c7e01e051034da8884bad1a1cb7f09bbe6be3f0282
F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a32075a8 F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a32075a8
F ext/jni/GNUmakefile dcd9595bf9b218c8c97a60f558eaacedbd3901f63ed59475f38c73a7692dd084 F ext/jni/GNUmakefile dcd9595bf9b218c8c97a60f558eaacedbd3901f63ed59475f38c73a7692dd084
F ext/jni/README.md e965674505e105626127ad45e628e4d19fcd379cdafc4d23c814c1ac2c55681d F ext/jni/README.md e965674505e105626127ad45e628e4d19fcd379cdafc4d23c814c1ac2c55681d
F ext/jni/src/c/sqlite3-jni.c 6ab1fa79b54b918e63f8ad02b97ed99300b1904ac8542b224fc819a3e7b41c60 F ext/jni/src/c/sqlite3-jni.c 684d22ba352c300118a05918081b7219926469252c904896aa86c3a31025dbe1
F ext/jni/src/c/sqlite3-jni.h ec38592e88d32f09ba4bde13f2e135bb7cf8712356b807df521b3fc99edeab32 F ext/jni/src/c/sqlite3-jni.h ec38592e88d32f09ba4bde13f2e135bb7cf8712356b807df521b3fc99edeab32
F ext/jni/src/org/sqlite/jni/Authorizer.java 1308988f7f40579ea0e4deeaec3c6be971630566bd021c31367fe3f5140db892 F ext/jni/src/org/sqlite/jni/Authorizer.java 1308988f7f40579ea0e4deeaec3c6be971630566bd021c31367fe3f5140db892
F ext/jni/src/org/sqlite/jni/AutoExtension.java 3409ad8954d6466bf772e6be9379e0e337312b446b668287062845755a16844d F ext/jni/src/org/sqlite/jni/AutoExtension.java 3409ad8954d6466bf772e6be9379e0e337312b446b668287062845755a16844d
@ -266,7 +266,7 @@ F ext/jni/src/org/sqlite/jni/sqlite3_context.java d26573fc7b309228cb49786e907859
F ext/jni/src/org/sqlite/jni/sqlite3_stmt.java 78e6d1b95ac600a9475e9db4623f69449322b0c93d1bd4e1616e76ed547ed9fc F ext/jni/src/org/sqlite/jni/sqlite3_stmt.java 78e6d1b95ac600a9475e9db4623f69449322b0c93d1bd4e1616e76ed547ed9fc
F ext/jni/src/org/sqlite/jni/sqlite3_value.java 3d1d4903e267bc0bc81d57d21f5e85978eff389a1a6ed46726dbe75f85e6914a F ext/jni/src/org/sqlite/jni/sqlite3_value.java 3d1d4903e267bc0bc81d57d21f5e85978eff389a1a6ed46726dbe75f85e6914a
F ext/jni/src/org/sqlite/jni/tester/Outer.java 3d9c40f8ed58ec0df05ca160986ea06ec84ec1f338b069cfba9604bbba467a01 F ext/jni/src/org/sqlite/jni/tester/Outer.java 3d9c40f8ed58ec0df05ca160986ea06ec84ec1f338b069cfba9604bbba467a01
F ext/jni/src/org/sqlite/jni/tester/SQLTester.java 1a7fe4607b80336f0bcb5e0cb7237d987d42c1dfdf59029566c3bc75c2053fbe F ext/jni/src/org/sqlite/jni/tester/SQLTester.java 1d54d137405287b7b88b9428134c6208f2c60fb01ad5d0e9126829e4044df1a7
F ext/jni/src/org/sqlite/jni/tester/TestScript.java 52350fb458d7d2816377a824c18c498c4a97f0026b64278f62ff1c382a92a070 F ext/jni/src/org/sqlite/jni/tester/TestScript.java 52350fb458d7d2816377a824c18c498c4a97f0026b64278f62ff1c382a92a070
F ext/jni/src/org/sqlite/jni/tester/test-script-interpreter.md 4a4868c70a68aa1829c1f7659daa78198187199d176778efb86a239c9e58802c F ext/jni/src/org/sqlite/jni/tester/test-script-interpreter.md 4a4868c70a68aa1829c1f7659daa78198187199d176778efb86a239c9e58802c
F ext/jni/src/tests/000_first.test bd912c4d88f4f85264de1b53267114891bdb4c6d0d2e847343bc3ff482ec296e F ext/jni/src/tests/000_first.test bd912c4d88f4f85264de1b53267114891bdb4c6d0d2e847343bc3ff482ec296e
@ -2090,8 +2090,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 49005ca5cc191c52279bc7fdb45d95eeb6f8e344f78ce9dbd97aac814bc21202 P bb8321702eea52fa9d42987a4b053b32d8eba15580a39d7831cd8d6f1ceb62bf
R 2e62d651a234281d8736039a6472287a R 20b8372fe27975edee36fa6d84512581
U stephan U stephan
Z 6b00d1de9eb6d40c30f757066262f00c Z 9a23750fa7c3396fc72fc1349e829a3b
# Remove this line to create a well-formed Fossil manifest. # Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
bb8321702eea52fa9d42987a4b053b32d8eba15580a39d7831cd8d6f1ceb62bf 0dba3073f44685a51a5db7ff8886295fe04dfd43f69cbf53ad3d5afce741076b