SQLFunction is used in conjunction with the
sqlite3_create_function() JNI-bound API to give that native code
access to the callback functions needed in order to implement SQL
- functions in Java. This class is not used by itself: see the
- inner classes Scalar, Aggregate<T>, and Window<T>.
+ functions in Java.
+
+ This class is not used by itself, but is a marker base class. The
+ three UDF types are modelled by the inner classes Scalar,
+ Aggregate<T>, and Window<T>. Most simply, clients may create
+ anonymous classes from those to implement UDFs. Clients are free to
+ create their own classes for use with UDFs, so long as they conform
+ to the public interfaces defined by those three classes. The JNI
+ layer only actively relies on the SQLFunction base class.
*/
public abstract class SQLFunction {
/**
- ContextMap is a helper for use with aggregate and window
- functions, to help them manage their accumulator state across
- calls to the UDF's callbacks.
+ PerContextState assists aggregate and window functions in
+ managinga their accumulator state across calls to the UDF's
+ callbacks.
If a given aggregate or window function is called multiple times
in a single SQL statement, e.g. SELECT MYFUNC(A), MYFUNC(B)...,
then the clients need some way of knowing which call is which so
that they can map their state between their various UDF callbacks
- and reset it (if needed) via xFinal(). This class takes care of
- such mappings.
+ and reset it via xFinal(). This class takes care of such
+ mappings.
This class works by mapping
sqlite3_context.getAggregateContext() to a single piece of
This class is a helper providing commonly-needed functionality -
it is not required for use with aggregate or window functions.
Client UDFs are free to perform such mappings using custom
- approaches.
+ approaches. The provided Aggregate<T> and Window<T> classes
+ use this.
*/
- public static final class ContextMap<T> {
+ public static final class PerContextState<T> {
private final java.util.Map<Long,ValueHolder<T>> map
= new java.util.HashMap<>();
associated with cx.getAggregateContext() from the map and
returns it, returning null if no other UDF method has been
called to set up such a mapping. The latter condition will be
- the case if an aggregate is used in a statement which has no
- result rows.
+ the case if a UDF is used in a statement which has no result
+ rows.
*/
public T takeAggregateState(sqlite3_context cx){
final ValueHolder<T> h = map.remove(cx.getAggregateContext());
//! Subclass for creating scalar functions.
public static abstract class Scalar extends SQLFunction {
+
+ //! As for the xFunc() argument of the C API's sqlite3_create_function()
public abstract void xFunc(sqlite3_context cx, sqlite3_value[] args);
+
/**
Optionally override to be notified when the UDF is finalized by
SQLite.
takeAggregateState() methods.
*/
public static abstract class Aggregate<T> extends SQLFunction {
+
+ //! As for the xStep() argument of the C API's sqlite3_create_function()
public abstract void xStep(sqlite3_context cx, sqlite3_value[] args);
+
+ //! As for the xFinal() argument of the C API's sqlite3_create_function()
public abstract void xFinal(sqlite3_context cx);
- //! @see Scalar#xDestroy()
+ /**
+ Optionally override to be notified when the UDF is finalized by
+ SQLite.
+ */
public void xDestroy() {}
- private final ContextMap<T> map = new ContextMap<>();
+ //! Per-invocation state for the UDF.
+ private final PerContextState<T> map = new PerContextState<>();
- //! @see ContextMap<T>#getAggregateState()
+ /**
+ To be called from the implementation's xStep() method, as well
+ as the xValue() and xInverse() methods of the Window<T>
+ subclass, to fetch the current per-call UDF state. On the
+ first call to this method for any given sqlite3_context
+ argument, the context is set to the given initial value. On all other
+ calls, the 2nd argument is ignored.
+
+ @see PerContextState<T>#takeAggregateState()
+ */
protected final ValueHolder<T> getAggregateState(sqlite3_context cx, T initialValue){
return map.getAggregateState(cx, initialValue);
}
- //! @see ContextMap<T>#takeAggregateState()
+ /**
+ To be called from the implementation's xFinal() method to fetch
+ the final state of the UDF and remove its mapping.
+
+ @see PerContextState<T>#takeAggregateState()
+ */
protected final T takeAggregateState(sqlite3_context cx){
return map.takeAggregateState(cx);
}
invocation-specific state.
*/
public static abstract class Window<T> extends Aggregate<T> {
+
+ //! As for the xInverse() argument of the C API's sqlite3_create_window_function()
public abstract void xInverse(sqlite3_context cx, sqlite3_value[] args);
+
+ //! As for the xValue() argument of the C API's sqlite3_create_window_function()
public abstract void xValue(sqlite3_context cx);
}
}
-C Internal\sexception-handling\scleanups\sin\sthe\sJNI\sbindings.
-D 2023-08-01T09:44:26.568
+C More\sdocs\sfor\sthe\sJava\sside\sof\sthe\sJNI\sbindings.
+D 2023-08-01T10:19:05.727
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a32075a8
F ext/jni/GNUmakefile 3d1f106e7a08bb54279c12979b31492b3dea702a732eab445dbc765120995182
F ext/jni/README.md d5cfc3037236dee3efa1c5ce62ddee8ad9d6d43c329a10a491888f272e90edc8
-F ext/jni/src/c/sqlite3-jni.c a2f53b91a905a2ac0cc5a71a9157c6ec684d64a343a59b0c503a61bd12163aa6
+F ext/jni/src/c/sqlite3-jni.c dc0a2de7249f8e76ba729cd0d6248d373fce63e565611fa0d868837f6fe58a0e
F ext/jni/src/c/sqlite3-jni.h 74aaf87e77f99857aa3afc013517c934cbc2c16618c83d8f5d6294351bc8e7b1
F ext/jni/src/org/sqlite/jni/BusyHandler.java 1b1d3e5c86cd796a0580c81b6af6550ad943baa25e47ada0dcca3aff3ebe978c
F ext/jni/src/org/sqlite/jni/Collation.java 8dffbb00938007ad0967b2ab424d3c908413af1bbd3d212b9c9899910f1218d1
F ext/jni/src/org/sqlite/jni/OutputPointer.java c7868f1f4ad63435ee44d409377df7dd7e02592a3734df8887a22a9f74b12751
F ext/jni/src/org/sqlite/jni/ProgressHandler.java 5979450e996416d28543f1d42634d308439565a99332a8bd84e424af667116cc
F ext/jni/src/org/sqlite/jni/RollbackHook.java b04c8abcc6ade44a8a57129e33765793f69df0ba909e49ba18d73f4268d92564
-F ext/jni/src/org/sqlite/jni/SQLFunction.java 663a4e479ec65bfbf893586439e12d30b8237898064a22ab64f5658b57315f37
-F ext/jni/src/org/sqlite/jni/SQLite3Jni.java b522c6456ab66026af5c487e4ac40410be36374d0550c2a03ea28421c4d39029
+F ext/jni/src/org/sqlite/jni/SQLFunction.java 09ce81c1c637e31c3a830d4c859cce95d65f5e02ff45f8bd1985b3479381bc46
+F ext/jni/src/org/sqlite/jni/SQLite3Jni.java d654fb8a43504b91059739eb0d435127423a195bd8f321b6c7aeedd394ed5887
F ext/jni/src/org/sqlite/jni/Tester1.java 9443cdbd2b10f6a8e1f3abd1694983a16b17960f8ed2f7e06bcc7e535fb5abcf
F ext/jni/src/org/sqlite/jni/Tracer.java a5cece9f947b0af27669b8baec300b6dd7ff859c3e6a6e4a1bd8b50f9714775d
F ext/jni/src/org/sqlite/jni/UpdateHook.java e58645a1727f8a9bbe72dc072ec5b40d9f9362cb0aa24acfe93f49ff56a9016d
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P b663b27e425966f34fb62482a18048f0e2934380e5c411ae3627f1fe6a765c04
-R 2f5470dcd701417296bafb0eecce52d9
+P 057b1d4f6ffff73c120566895f61ea3fd8118968464d67ec9262096a7aa03f39
+R f7f15dd74dc41170d62a8df321c4d11e
U stephan
-Z 5b2b767d2f48d93a46b3cc4865630bdc
+Z e680719e67af1a30c3a9b7bfb130a5b0
# Remove this line to create a well-formed Fossil manifest.