Repository: xerial/sqlite-jdbc
Pull request #882 (2023-04-15 12:00:26)

fix(jdbc): PreparedStatement getParameterType and getParameterTypeName
Implements JDBC3PreparedStatement getParameterType and getParameterTypeName.
It returns the JDBC type based on the parameter class.


Patch:
diff --git a/pom.xml b/pom.xml
index e06b6778..0096fd96 100644
--- a/pom.xml
+++ b/pom.xml
@@ -336,7 +336,7 @@
                     <plugin>
                         <groupId>org.graalvm.buildtools</groupId>
                         <artifactId>native-maven-plugin</artifactId>
-                        <version>0.9.20</version>
+                        <version>0.9.21</version>
                         <extensions>true</extensions>
                         <executions>
                             <execution>
@@ -396,13 +396,13 @@
         <dependency>
             <groupId>org.junit-pioneer</groupId>
             <artifactId>junit-pioneer</artifactId>
-            <version>2.0.0</version>
+            <version>2.0.1</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-core</artifactId>
-            <version>5.2.0</version>
+            <version>5.3.0</version>
             <scope>test</scope>
         </dependency>
         <dependency>
diff --git a/src/main/java/org/sqlite/core/CoreStatement.java b/src/main/java/org/sqlite/core/CoreStatement.java
index 55b97c4e..c37f2c0f 100644
--- a/src/main/java/org/sqlite/core/CoreStatement.java
+++ b/src/main/java/org/sqlite/core/CoreStatement.java
@@ -140,4 +140,10 @@ public abstract class CoreStatement implements Codes {
     }
 
     public abstract ResultSet executeQuery(String sql, boolean closeStmt) throws SQLException;
+
+    protected void checkIndex(int index) throws SQLException {
+        if (index < 1 || index > batch.length) {
+            throw new SQLException("Parameter index is invalid");
+        }
+    }
 }
diff --git a/src/main/java/org/sqlite/jdbc3/JDBC3PreparedStatement.java b/src/main/java/org/sqlite/jdbc3/JDBC3PreparedStatement.java
index 6feb1e0f..62488b0b 100644
--- a/src/main/java/org/sqlite/jdbc3/JDBC3PreparedStatement.java
+++ b/src/main/java/org/sqlite/jdbc3/JDBC3PreparedStatement.java
@@ -10,6 +10,7 @@ import java.sql.Array;
 import java.sql.Blob;
 import java.sql.Clob;
 import java.sql.Date;
+import java.sql.JDBCType;
 import java.sql.ParameterMetaData;
 import java.sql.Ref;
 import java.sql.ResultSet;
@@ -154,13 +155,29 @@ public abstract class JDBC3PreparedStatement extends CorePreparedStatement {
     }
 
     /** @see java.sql.ParameterMetaData#getParameterTypeName(int) */
-    public String getParameterTypeName(int pos) {
-        return "VARCHAR";
+    public String getParameterTypeName(int pos) throws SQLException {
+        checkIndex(pos);
+        return JDBCType.valueOf(getParameterType(pos)).getName();
     }
 
     /** @see java.sql.ParameterMetaData#getParameterType(int) */
-    public int getParameterType(int pos) {
-        return Types.VARCHAR;
+    public int getParameterType(int pos) throws SQLException {
+        checkIndex(pos);
+        Object paramValue = batch[pos - 1];
+
+        if (paramValue == null) {
+            return Types.NULL;
+        } else if (paramValue instanceof Integer
+                || paramValue instanceof Short
+                || paramValue instanceof Boolean) {
+            return Types.INTEGER;
+        } else if (paramValue instanceof Long) {
+            return Types.BIGINT;
+        } else if (paramValue instanceof Double || paramValue instanceof Float) {
+            return Types.REAL;
+        } else {
+            return Types.VARCHAR;
+        }
     }
 
     /** @see java.sql.ParameterMetaData#getParameterMode(int) */


Test patch:
diff --git a/src/test/java/org/sqlite/PrepStmtTest.java b/src/test/java/org/sqlite/PrepStmtTest.java
index fb700852..fad13e64 100644
--- a/src/test/java/org/sqlite/PrepStmtTest.java
+++ b/src/test/java/org/sqlite/PrepStmtTest.java
@@ -777,4 +777,26 @@ public class PrepStmtTest {
             assertThat(meta.getColumnClassName(1)).isEqualTo("java.lang.Object");
         }
     }
+
+    @Test
+    public void getParameterTypeTest() throws SQLException {
+        stat.executeUpdate("create table t_int(i INT)");
+
+        try (PreparedStatement ps = conn.prepareStatement("INSERT INTO t_int VALUES(?)")) {
+            ps.setLong(1, 100);
+            assertThat(ps.getParameterMetaData().getParameterType(1)).isEqualTo(Types.BIGINT);
+            assertThat(ps.getParameterMetaData().getParameterTypeName(1)).isEqualTo("BIGINT");
+        }
+
+        stat.executeUpdate("create table t_real(a REAL, b REAL)");
+
+        try (PreparedStatement ps = conn.prepareStatement("INSERT INTO t_real VALUES(?, ?)")) {
+            ps.setDouble(1, 100.0);
+            ps.setFloat(2, 100.0f);
+            assertThat(ps.getParameterMetaData().getParameterType(1)).isEqualTo(Types.REAL);
+            assertThat(ps.getParameterMetaData().getParameterTypeName(1)).isEqualTo("REAL");
+            assertThat(ps.getParameterMetaData().getParameterType(2)).isEqualTo(Types.REAL);
+            assertThat(ps.getParameterMetaData().getParameterTypeName(2)).isEqualTo("REAL");
+        }
+    }
 }