diff --git a/src/jni/duckdb_java.cpp b/src/jni/duckdb_java.cpp index f7d3a4a9..ae6a829f 100644 --- a/src/jni/duckdb_java.cpp +++ b/src/jni/duckdb_java.cpp @@ -89,6 +89,8 @@ static jmethodID J_DuckDBDate_getDaysSinceEpoch; static jmethodID J_Object_toString; +static jclass J_DuckDBTime; + void ThrowJNI(JNIEnv *env, const char *message) { D_ASSERT(J_SQLException); env->ThrowNew(J_SQLException, message); @@ -170,6 +172,8 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { J_DuckDBDate_getDaysSinceEpoch = env->GetMethodID(J_DuckDBDate, "getDaysSinceEpoch", "()J"); D_ASSERT(J_DuckDBDate_getDaysSinceEpoch); + J_DuckDBTime = GetClassRef(env, "org/duckdb/DuckDBTime"); + tmpLocalRef = env->FindClass("java/math/BigDecimal"); J_Decimal = (jclass)env->NewGlobalRef(tmpLocalRef); env->DeleteLocalRef(tmpLocalRef); @@ -595,6 +599,9 @@ jobject _duckdb_jdbc_execute(JNIEnv *env, jclass, jobject stmt_ref_buf, jobjectA duckdb_params.push_back( Value::DATE((date_t)env->CallLongMethod(param, J_DuckDBDate_getDaysSinceEpoch))); + } else if (env->IsInstanceOf(param, J_DuckDBTime)) { + duckdb_params.push_back(Value::TIME((dtime_t)env->CallLongMethod(param, J_Timestamp_getMicrosEpoch))); + } else if (env->IsInstanceOf(param, J_Timestamp)) { duckdb_params.push_back( Value::TIMESTAMP((timestamp_t)env->CallLongMethod(param, J_Timestamp_getMicrosEpoch))); diff --git a/src/main/java/org/duckdb/DuckDBPreparedStatement.java b/src/main/java/org/duckdb/DuckDBPreparedStatement.java index d00bb2d2..6488ae0e 100644 --- a/src/main/java/org/duckdb/DuckDBPreparedStatement.java +++ b/src/main/java/org/duckdb/DuckDBPreparedStatement.java @@ -248,6 +248,8 @@ public void setObject(int parameterIndex, Object x) throws SQLException { x = new DuckDBTimestampTZ((OffsetDateTime) x); } else if (x instanceof Date) { x = new DuckDBDate((Date) x); + } else if (x instanceof Time) { + x = new DuckDBTime((Time) x); } params[parameterIndex - 1] = x; } @@ -609,7 +611,7 @@ public void setDate(int parameterIndex, Date x) throws SQLException { @Override public void setTime(int parameterIndex, Time x) throws SQLException { - throw new SQLFeatureNotSupportedException("setTime"); + setObject(parameterIndex, x); } @Override diff --git a/src/main/java/org/duckdb/DuckDBTime.java b/src/main/java/org/duckdb/DuckDBTime.java new file mode 100644 index 00000000..fdf5e787 --- /dev/null +++ b/src/main/java/org/duckdb/DuckDBTime.java @@ -0,0 +1,12 @@ +package org.duckdb; + +import java.sql.Time; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.concurrent.TimeUnit; + +public class DuckDBTime extends DuckDBTimestamp { + public DuckDBTime(Time time) { + super(TimeUnit.MILLISECONDS.toMicros(time.getTime())); + } +} diff --git a/src/test/java/org/duckdb/TestDuckDBJDBC.java b/src/test/java/org/duckdb/TestDuckDBJDBC.java index 2c95b3cf..1d2425e8 100644 --- a/src/test/java/org/duckdb/TestDuckDBJDBC.java +++ b/src/test/java/org/duckdb/TestDuckDBJDBC.java @@ -1162,6 +1162,18 @@ public static void test_set_date() throws Exception { } } + public static void test_set_time() throws Exception { + try (Connection conn = DriverManager.getConnection(JDBC_URL); + PreparedStatement stmt = conn.prepareStatement("SELECT ?::VARCHAR")) { + Time time = Time.valueOf("12:40:00"); + stmt.setTime(1, time); + ResultSet rs = stmt.executeQuery(); + while (rs.next()) { + assertEquals(rs.getTime(1), time); + } + } + } + public static void test_lots_of_decimals() throws Exception { Connection conn = DriverManager.getConnection(JDBC_URL); Statement stmt = conn.createStatement();