From bc8c6367b5faec5da43f1d7d6e2103d5f37dfd84 Mon Sep 17 00:00:00 2001
From: Magnus Persson <1431685+magnusp@users.noreply.github.com>
Date: Thu, 22 Oct 2026 00:45:32 +0200
Subject: [PATCH] fix(jdbc): gate getObject numeric targets on storage class
Closes #34. Part of #54.
Matches sqlite-jdbc 3.53.4.0: Integer, Long, Float, and Double convert only from INTEGER or FLOAT storage and throw 'Bad value for type X' otherwise, including NULL, TEXT, and BLOB. Short and Byte are no longer supported, and unsupported target types use SQLFeatureNotSupportedException. The target-type by storage-class matrix is documented on the method.
---
.../magnusp/libsql/jdbc/LibsqlResultSet.java | 179 +++++++++---------
.../jdbc/LibsqlResultSetGetObjectTest.java | 164 ++++++++++++++++
.../libsql/jdbc/LibsqlResultSetTest.java | 18 +-
3 files changed, 263 insertions(+), 98 deletions(-)
create mode 100644 libsql-jdbc/src/test/java/com/github/magnusp/libsql/jdbc/LibsqlResultSetGetObjectTest.java
diff --git a/libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlResultSet.java b/libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlResultSet.java
index 84dfa9c..69a58a2 100644
--- a/libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlResultSet.java
+++ b/libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlResultSet.java
@@ -20,6 +20,7 @@
import java.sql.ResultSetMetaData;
import java.sql.RowId;
import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Statement;
@@ -481,70 +482,6 @@ private static double toDouble(Value val) {
};
}
- private static int toStrictInt(Value val) throws SQLException {
- return switch (val) {
- case Value.Null n -> 0;
- case Value.Integer i -> (int) i.value();
- case Value.Float f -> (int) f.value();
- case Value.Text t -> {
- try {
- yield Integer.parseInt(t.value());
- } catch (NumberFormatException e) {
- throw new SQLException("Bad value for type Integer: " + t.value(), e);
- }
- }
- case Value.Blob b -> 0;
- };
- }
-
- private static long toStrictLong(Value val) throws SQLException {
- return switch (val) {
- case Value.Null n -> 0L;
- case Value.Integer i -> i.value();
- case Value.Float f -> (long) f.value();
- case Value.Text t -> {
- try {
- yield Long.parseLong(t.value());
- } catch (NumberFormatException e) {
- throw new SQLException("Bad value for type Long: " + t.value(), e);
- }
- }
- case Value.Blob b -> 0L;
- };
- }
-
- private static float toStrictFloat(Value val) throws SQLException {
- return switch (val) {
- case Value.Null n -> 0.0F;
- case Value.Integer i -> (float) i.value();
- case Value.Float f -> (float) f.value();
- case Value.Text t -> {
- try {
- yield Float.parseFloat(t.value());
- } catch (NumberFormatException e) {
- throw new SQLException("Bad value for type Float: " + t.value(), e);
- }
- }
- case Value.Blob b -> 0.0F;
- };
- }
-
- private static double toStrictDouble(Value val) throws SQLException {
- return switch (val) {
- case Value.Null n -> 0.0;
- case Value.Integer i -> (double) i.value();
- case Value.Float f -> f.value();
- case Value.Text t -> {
- try {
- yield Double.parseDouble(t.value());
- } catch (NumberFormatException e) {
- throw new SQLException("Bad value for type Double: " + t.value(), e);
- }
- }
- case Value.Blob b -> 0.0;
- };
- }
-
private static String blobAsText(Value.Blob b) {
return new String(b.bytes(), java.nio.charset.StandardCharsets.UTF_8);
}
@@ -1031,18 +968,65 @@ public boolean isLast() throws SQLException {
@Override public void updateNClob(int columnIndex, Reader reader) throws SQLException { throw new UnsupportedOperationException(); }
@Override public void updateNClob(String columnLabel, Reader reader) throws SQLException { throw new UnsupportedOperationException(); }
+ /**
+ * Returns a column value converted to the requested Java type.
+ *
+ *
The conversion matrix matches sqlite-jdbc 3.53.4.0. Numeric wrapper targets are gated on
+ * the current value's SQLite storage class; any other storage class raises {@code Bad value
+ * for type Integer} (or the corresponding target type name):
+ *
+ *