Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -592,8 +592,12 @@ add_library(duckdb_java SHARED
src/jni/bindings_data_chunk.cpp
src/jni/bindings_logical_type.cpp
src/jni/bindings_scalar_function.cpp
src/jni/bindings_table_function.cpp
src/jni/bindings_table_function_bind.cpp
src/jni/bindings_table_function_init.cpp
src/jni/bindings_validity.cpp
src/jni/bindings_vector.cpp
src/jni/bindings_value.cpp
src/jni/config.cpp
src/jni/duckdb_java.cpp
src/jni/functions.cpp
Expand Down
4 changes: 4 additions & 0 deletions CMakeLists.txt.in
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,12 @@ add_library(duckdb_java SHARED
src/jni/bindings_data_chunk.cpp
src/jni/bindings_logical_type.cpp
src/jni/bindings_scalar_function.cpp
src/jni/bindings_table_function.cpp
src/jni/bindings_table_function_bind.cpp
src/jni/bindings_table_function_init.cpp
src/jni/bindings_validity.cpp
src/jni/bindings_vector.cpp
src/jni/bindings_value.cpp
src/jni/config.cpp
src/jni/duckdb_java.cpp
src/jni/functions.cpp
Expand Down
73 changes: 68 additions & 5 deletions UDF.MD
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,9 @@ Common class mappings include:

Notes:

- `UHUGEINT` is supported through explicit `DuckDBColumnType.UHUGEINT`/`DuckDBLogicalType` declarations.
- Java class auto-mapping for `BigInteger` remains `HUGEINT`.
- `UHUGEINT` is supported through explicit `DuckDBColumnType.UHUGEINT`/`DuckDBLogicalType` declarations
- Java class auto-mapping for `BigInteger` remains `HUGEINT`
- composite types like `STRUCT` or `LIST` are currently not supported, this intended to be added in future versions

Use `DuckDBLogicalType.decimal(width, scale)` for explicit DECIMAL precision/scale.

Expand Down Expand Up @@ -153,9 +154,6 @@ This registry provides bookkeeping for functions registered through the JDBC API

- `name()`
- `functionKind()`
- `isScalar()`
- parameter and return type metadata
- callback and flags used at registration time

To inspect Java-side registrations:

Expand Down Expand Up @@ -207,3 +205,68 @@ try (Connection conn = DriverManager.getConnection("jdbc:duckdb:"); Statement st
```sql
SELECT java_event_label(TIMESTAMP '2026-04-04 12:00:00', 'launch', 4.5);
```

## Table functions (`DuckDBTableFunction`)

Similar to scalar functions, a table function can be registered using `DuckDBFunctions.tableFunction()`.

Table function callback must implement `DuckDBTableFunction` interface:

- `bind` - called during `PREPARE` stage, must register output columns; has access to input parameters using `.getParameter()` and `.getNamedParameter()`; can return a "bind data" object
that can be used during function execution
- `init` - called once before the function execution, has access to bind data, returns an object used to track the state during function execution
- `localInit` (optional) - called once for every thread before the function execution, returns an object used to track thread-local state during function execution
- `apply` - has access to bind data, global init data and local init date, writes results into output vectors, returns a number of written row, is called by the engine repeatedly until it return zero rows

All callback arguments (including parameter objects) are only valid during the callback execution.

In general, Java table functions interface exposes the [C API table function interface](https://github.com/duckdb/duckdb-java/blob/2f4ed44df2fd1f89594cc7af28f9f8daba5fa582/src/duckdb/src/include/duckdb.h#L4145-L4478)
as close as possible.

Example:

```java
try (Connection conn = DriverManager.getConnection("jdbc:duckdb:"); Statement stmt = conn.createStatement()) {
DuckDBFunctions.tableFunction()
.withName("java_table_basic")
.withParameter(int.class)
.withNamedParameter("param1", String.class)
.withFunction(new DuckDBTableFunction<Integer, AtomicBoolean, Object>() {
@Override
public Integer bind(DuckDBTableFunctionBindInfo info) throws Exception {
info.addResultColumn("col1", Integer.TYPE).addResultColumn("col2", String.class);
DuckDBValue param = info.getParameter(0);
assertThrows(param::getBoolean, FunctionException.class);
DuckDBValue namedParam = info.getNamedParameter("param1");
assertEquals(namedParam.getString(), "foobar");
return param.getInt();
}

@Override
public AtomicBoolean init(DuckDBTableFunctionInitInfo info) throws Exception {
return new AtomicBoolean(false);
}

@Override
public long apply(DuckDBTableFunctionCallInfo info, DuckDBDataChunkWriter output) throws Exception {
Integer bindData = info.getBindData();
AtomicBoolean done = info.getInitData();
if (done.get()) {
return 0;
}
output.vector(0).setInt(0, bindData);
output.vector(1).setString(0, "foo");
output.vector(0).setNull(1);
output.vector(1).setString(1, "bar");
done.set(true);
return 2;
}
})
.register(conn);
...
}
```
```sql
FROM java_table_basic(42, param1='foobar')
```

61 changes: 61 additions & 0 deletions duckdb_java.def
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,67 @@ Java_org_duckdb_DuckDBBindings_duckdb_1appender_1column_1type
Java_org_duckdb_DuckDBBindings_duckdb_1append_1data_1chunk
Java_org_duckdb_DuckDBBindings_duckdb_1append_1default_1to_1chunk

Java_org_duckdb_DuckDBBindings_duckdb_1bind_1add_1result_1column
Java_org_duckdb_DuckDBBindings_duckdb_1bind_1get_1parameter_1count
Java_org_duckdb_DuckDBBindings_duckdb_1bind_1get_1parameter
Java_org_duckdb_DuckDBBindings_duckdb_1bind_1get_1named_1parameter
Java_org_duckdb_DuckDBBindings_duckdb_1bind_1set_1bind_1data
Java_org_duckdb_DuckDBBindings_duckdb_1bind_1set_1cardinality
Java_org_duckdb_DuckDBBindings_duckdb_1bind_1set_1error

Java_org_duckdb_DuckDBBindings_duckdb_1init_1get_1bind_1data
Java_org_duckdb_DuckDBBindings_duckdb_1init_1set_1init_1data
Java_org_duckdb_DuckDBBindings_duckdb_1init_1get_1column_1count
Java_org_duckdb_DuckDBBindings_duckdb_1init_1get_1column_1index
Java_org_duckdb_DuckDBBindings_duckdb_1init_1set_1max_1threads
Java_org_duckdb_DuckDBBindings_duckdb_1init_1set_1error

Java_org_duckdb_DuckDBBindings_duckdb_1create_1table_1function
Java_org_duckdb_DuckDBBindings_duckdb_1destroy_1table_1function
Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1set_1name
Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1add_1parameter
Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1add_1named_1parameter
Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1set_1extra_1info
Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1set_1bind
Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1set_1init
Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1set_1local_1init
Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1set_1function
Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1supports_1projection_1pushdown
Java_org_duckdb_DuckDBBindings_duckdb_1register_1table_1function
Java_org_duckdb_DuckDBBindings_duckdb_1function_1get_1bind_1data
Java_org_duckdb_DuckDBBindings_duckdb_1function_1get_1init_1data
Java_org_duckdb_DuckDBBindings_duckdb_1function_1get_1local_1init_1data
Java_org_duckdb_DuckDBBindings_duckdb_1function_1set_1error

Java_org_duckdb_DuckDBBindings_duckdb_1is_1null_1value
Java_org_duckdb_DuckDBBindings_duckdb_1get_1value_1type
Java_org_duckdb_DuckDBBindings_duckdb_1destroy_1value
Java_org_duckdb_DuckDBBindings_duckdb_1get_1bool
Java_org_duckdb_DuckDBBindings_duckdb_1get_1int8
Java_org_duckdb_DuckDBBindings_duckdb_1get_1uint8
Java_org_duckdb_DuckDBBindings_duckdb_1get_1int16
Java_org_duckdb_DuckDBBindings_duckdb_1get_1uint16
Java_org_duckdb_DuckDBBindings_duckdb_1get_1int32
Java_org_duckdb_DuckDBBindings_duckdb_1get_1uint32
Java_org_duckdb_DuckDBBindings_duckdb_1get_1int64
Java_org_duckdb_DuckDBBindings_duckdb_1get_1uint64
Java_org_duckdb_DuckDBBindings_duckdb_1get_1hugeint
Java_org_duckdb_DuckDBBindings_duckdb_1get_1uhugeint
Java_org_duckdb_DuckDBBindings_duckdb_1get_1bignum
Java_org_duckdb_DuckDBBindings_duckdb_1get_1decimal
Java_org_duckdb_DuckDBBindings_duckdb_1get_1float
Java_org_duckdb_DuckDBBindings_duckdb_1get_1double
Java_org_duckdb_DuckDBBindings_duckdb_1get_1date
Java_org_duckdb_DuckDBBindings_duckdb_1get_1time
Java_org_duckdb_DuckDBBindings_duckdb_1get_1time_1ns
Java_org_duckdb_DuckDBBindings_duckdb_1get_1time_1tz
Java_org_duckdb_DuckDBBindings_duckdb_1get_1timestamp
Java_org_duckdb_DuckDBBindings_duckdb_1get_1timestamp_1tz
Java_org_duckdb_DuckDBBindings_duckdb_1get_1timestamp_1s
Java_org_duckdb_DuckDBBindings_duckdb_1get_1timestamp_1ms
Java_org_duckdb_DuckDBBindings_duckdb_1get_1timestamp_1ns
Java_org_duckdb_DuckDBBindings_duckdb_1get_1varchar

duckdb_adbc_init
duckdb_add_aggregate_function_to_set
duckdb_add_replacement_scan
Expand Down
61 changes: 61 additions & 0 deletions duckdb_java.exp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,67 @@ _Java_org_duckdb_DuckDBBindings_duckdb_1appender_1column_1type
_Java_org_duckdb_DuckDBBindings_duckdb_1append_1data_1chunk
_Java_org_duckdb_DuckDBBindings_duckdb_1append_1default_1to_1chunk

_Java_org_duckdb_DuckDBBindings_duckdb_1bind_1add_1result_1column
_Java_org_duckdb_DuckDBBindings_duckdb_1bind_1get_1parameter_1count
_Java_org_duckdb_DuckDBBindings_duckdb_1bind_1get_1parameter
_Java_org_duckdb_DuckDBBindings_duckdb_1bind_1get_1named_1parameter
_Java_org_duckdb_DuckDBBindings_duckdb_1bind_1set_1bind_1data
_Java_org_duckdb_DuckDBBindings_duckdb_1bind_1set_1cardinality
_Java_org_duckdb_DuckDBBindings_duckdb_1bind_1set_1error

_Java_org_duckdb_DuckDBBindings_duckdb_1init_1get_1bind_1data
_Java_org_duckdb_DuckDBBindings_duckdb_1init_1set_1init_1data
_Java_org_duckdb_DuckDBBindings_duckdb_1init_1get_1column_1count
_Java_org_duckdb_DuckDBBindings_duckdb_1init_1get_1column_1index
_Java_org_duckdb_DuckDBBindings_duckdb_1init_1set_1max_1threads
_Java_org_duckdb_DuckDBBindings_duckdb_1init_1set_1error

_Java_org_duckdb_DuckDBBindings_duckdb_1create_1table_1function
_Java_org_duckdb_DuckDBBindings_duckdb_1destroy_1table_1function
_Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1set_1name
_Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1add_1parameter
_Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1add_1named_1parameter
_Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1set_1extra_1info
_Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1set_1bind
_Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1set_1init
_Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1set_1local_1init
_Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1set_1function
_Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1supports_1projection_1pushdown
_Java_org_duckdb_DuckDBBindings_duckdb_1register_1table_1function
_Java_org_duckdb_DuckDBBindings_duckdb_1function_1get_1bind_1data
_Java_org_duckdb_DuckDBBindings_duckdb_1function_1get_1init_1data
_Java_org_duckdb_DuckDBBindings_duckdb_1function_1get_1local_1init_1data
_Java_org_duckdb_DuckDBBindings_duckdb_1function_1set_1error

_Java_org_duckdb_DuckDBBindings_duckdb_1is_1null_1value
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1value_1type
_Java_org_duckdb_DuckDBBindings_duckdb_1destroy_1value
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1bool
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1int8
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1uint8
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1int16
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1uint16
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1int32
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1uint32
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1int64
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1uint64
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1hugeint
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1uhugeint
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1bignum
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1decimal
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1float
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1double
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1date
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1time
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1time_1ns
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1time_1tz
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1timestamp
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1timestamp_1tz
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1timestamp_1s
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1timestamp_1ms
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1timestamp_1ns
_Java_org_duckdb_DuckDBBindings_duckdb_1get_1varchar

_duckdb_adbc_init
_duckdb_add_aggregate_function_to_set
_duckdb_add_replacement_scan
Expand Down
61 changes: 61 additions & 0 deletions duckdb_java.map
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,67 @@ DUCKDB_JAVA {
Java_org_duckdb_DuckDBBindings_duckdb_1append_1data_1chunk;
Java_org_duckdb_DuckDBBindings_duckdb_1append_1default_1to_1chunk;

Java_org_duckdb_DuckDBBindings_duckdb_1bind_1add_1result_1column;
Java_org_duckdb_DuckDBBindings_duckdb_1bind_1get_1parameter_1count;
Java_org_duckdb_DuckDBBindings_duckdb_1bind_1get_1parameter;
Java_org_duckdb_DuckDBBindings_duckdb_1bind_1get_1named_1parameter;
Java_org_duckdb_DuckDBBindings_duckdb_1bind_1set_1bind_1data;
Java_org_duckdb_DuckDBBindings_duckdb_1bind_1set_1cardinality;
Java_org_duckdb_DuckDBBindings_duckdb_1bind_1set_1error;

Java_org_duckdb_DuckDBBindings_duckdb_1init_1get_1bind_1data;
Java_org_duckdb_DuckDBBindings_duckdb_1init_1set_1init_1data;
Java_org_duckdb_DuckDBBindings_duckdb_1init_1get_1column_1count;
Java_org_duckdb_DuckDBBindings_duckdb_1init_1get_1column_1index;
Java_org_duckdb_DuckDBBindings_duckdb_1init_1set_1max_1threads;
Java_org_duckdb_DuckDBBindings_duckdb_1init_1set_1error;

Java_org_duckdb_DuckDBBindings_duckdb_1create_1table_1function;
Java_org_duckdb_DuckDBBindings_duckdb_1destroy_1table_1function;
Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1set_1name;
Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1add_1parameter;
Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1add_1named_1parameter;
Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1set_1extra_1info;
Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1set_1bind;
Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1set_1init;
Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1set_1local_1init;
Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1set_1function;
Java_org_duckdb_DuckDBBindings_duckdb_1table_1function_1supports_1projection_1pushdown;
Java_org_duckdb_DuckDBBindings_duckdb_1register_1table_1function;
Java_org_duckdb_DuckDBBindings_duckdb_1function_1get_1bind_1data;
Java_org_duckdb_DuckDBBindings_duckdb_1function_1get_1init_1data;
Java_org_duckdb_DuckDBBindings_duckdb_1function_1get_1local_1init_1data;
Java_org_duckdb_DuckDBBindings_duckdb_1function_1set_1error;

Java_org_duckdb_DuckDBBindings_duckdb_1is_1null_1value;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1value_1type;
Java_org_duckdb_DuckDBBindings_duckdb_1destroy_1value;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1bool;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1int8;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1uint8;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1int16;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1uint16;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1int32;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1uint32;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1int64;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1uint64;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1hugeint;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1uhugeint;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1bignum;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1decimal;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1float;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1double;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1date;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1time;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1time_1ns;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1time_1tz;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1timestamp;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1timestamp_1tz;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1timestamp_1s;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1timestamp_1ms;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1timestamp_1ns;
Java_org_duckdb_DuckDBBindings_duckdb_1get_1varchar;

duckdb_adbc_init;
duckdb_add_aggregate_function_to_set;
duckdb_add_replacement_scan;
Expand Down
Loading
Loading