From 6bc966ff869b8bce84a3955b2a018d7cc10f66b3 Mon Sep 17 00:00:00 2001
From: Davy Verstappen <davy@davyverstappen.me>
Date: Sun, 16 Jun 2013 10:05:15 +0200
Subject: [PATCH 2/2] Fix JDBC type code for MySQL FLOAT and
 SMALLINT/INT/INTEGER UNSIGNED.

---
 .../org/mariadb/jdbc/MySQLResultSetMetaData.java   | 13 ----
 .../org/mariadb/jdbc/internal/mysql/MySQLType.java |  2 +-
 .../mariadb/jdbc/DatatypeCompatibilityTest.java    | 88 ++++++++++++++++++++++
 src/test/java/org/mariadb/jdbc/DatatypeTest.java   |  6 +-
 src/test/java/org/mariadb/jdbc/DriverTest.java     | 23 ++++--
 .../org/mariadb/jdbc/ResultSetMetaDataTest.java    |  2 +-
 6 files changed, 108 insertions(+), 26 deletions(-)
 create mode 100644 src/test/java/org/mariadb/jdbc/DatatypeCompatibilityTest.java

diff --git a/src/main/java/org/mariadb/jdbc/MySQLResultSetMetaData.java b/src/main/java/org/mariadb/jdbc/MySQLResultSetMetaData.java
index 5b18ebb..3625f09 100644
--- a/src/main/java/org/mariadb/jdbc/MySQLResultSetMetaData.java
+++ b/src/main/java/org/mariadb/jdbc/MySQLResultSetMetaData.java
@@ -269,19 +269,6 @@ public class MySQLResultSetMetaData implements ResultSetMetaData {
                     return Types.DATE;
                 else
                     return Types.SMALLINT;
-
-            case SMALLINT:
-               if(!ci.isSigned()) {
-                   return Types.INTEGER;
-               } else {
-                   return Types.SMALLINT;
-               }
-            case INTEGER:
-               if(!ci.isSigned()) {
-                   return Types.BIGINT;
-               } else {
-                   return Types.INTEGER;
-               }
             case BLOB:
                 if (ci.getLength() < 0 || ci.getLength() > 16777215)
                     return Types.LONGVARBINARY;
diff --git a/src/main/java/org/mariadb/jdbc/internal/mysql/MySQLType.java b/src/main/java/org/mariadb/jdbc/internal/mysql/MySQLType.java
index 4e7234e..0c17ff5 100644
--- a/src/main/java/org/mariadb/jdbc/internal/mysql/MySQLType.java
+++ b/src/main/java/org/mariadb/jdbc/internal/mysql/MySQLType.java
@@ -80,7 +80,7 @@ public class MySQLType implements DataType {
         TINYINT(java.sql.Types.SMALLINT),
         SMALLINT(java.sql.Types.SMALLINT),
         INTEGER(java.sql.Types.INTEGER),
-        FLOAT(java.sql.Types.FLOAT),
+        FLOAT(java.sql.Types.REAL),
         DOUBLE(java.sql.Types.DOUBLE),
         NULL(java.sql.Types.NULL),
         TIMESTAMP(java.sql.Types.TIMESTAMP),
diff --git a/src/test/java/org/mariadb/jdbc/DatatypeCompatibilityTest.java b/src/test/java/org/mariadb/jdbc/DatatypeCompatibilityTest.java
new file mode 100644
index 0000000..5281bf3
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/DatatypeCompatibilityTest.java
@@ -0,0 +1,88 @@
+package org.mariadb.jdbc;
+
+import org.junit.Test;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.*;
+import java.util.Arrays;
+
+import static org.junit.Assert.*;
+
+public class DatatypeCompatibilityTest extends BaseTest {
+
+    @Test
+    public void testIntegerTypes() throws SQLException {
+        assertType("TINYINT", Integer.class, Types.TINYINT, "127", 127);
+        assertType("TINYINT UNSIGNED", Integer.class, Types.TINYINT, "255", 255);
+        assertType("SMALLINT", Integer.class, Types.SMALLINT, "0x7FFF", 0x7FFF);
+        assertType("SMALLINT UNSIGNED", Integer.class, Types.SMALLINT, "0xFFFF", 0xFFFF);
+        assertType("MEDIUMINT", Integer.class, Types.INTEGER, "0x7FFFFF", 0x7FFFFF);
+        assertType("MEDIUMINT UNSIGNED", Integer.class, Types.INTEGER, "0xFFFFFF", 0xFFFFFF);
+        assertType("INT", Integer.class, Types.INTEGER, "0x7FFFFFFF", 0x7FFFFFFF);
+        assertType("INT UNSIGNED", Long.class, Types.INTEGER, "0xFFFFFFFF", 0xFFFFFFFFl);
+        assertType("INTEGER", Integer.class, Types.INTEGER, "0x7FFFFFFF", 0x7FFFFFFF);
+        assertType("INTEGER UNSIGNED", Long.class, Types.INTEGER, "0xFFFFFFFF", 0xFFFFFFFFl);
+        assertType("BIGINT", Long.class, Types.BIGINT, "0x7FFFFFFFFFFFFFFF", Long.MAX_VALUE);
+        assertType("BIGINT UNSIGNED", BigInteger.class, Types.BIGINT, "0xFFFFFFFFFFFFFFFF", new BigInteger("FFFFFFFFFFFFFFFF", 16));
+    }
+
+    @Test
+    public void testFixedPointTypes() throws SQLException {
+        assertType("DECIMAL(5,2)", BigDecimal.class, Types.DECIMAL, "-999.99", new BigDecimal(-99999).divide(new BigDecimal(100)));
+        assertType("DECIMAL(5,2) UNSIGNED", BigDecimal.class, Types.DECIMAL, "999.99", new BigDecimal(99999).divide(new BigDecimal(100)));
+        assertType("NUMERIC(5,2)", BigDecimal.class, Types.DECIMAL, "-999.99", new BigDecimal(-99999).divide(new BigDecimal(100))); // not Types.NUMERIC!
+        assertType("NUMERIC(5,2) UNSIGNED", BigDecimal.class, Types.DECIMAL, "999.99", new BigDecimal(99999).divide(new BigDecimal(100))); // not Types.NUMERIC!
+    }
+
+    @Test
+    public void testFloatingPointTypes() throws SQLException {
+        assertType("FLOAT", Float.class, Types.REAL, "-1.0", -1.0f); // not Types.FLOAT!
+        assertType("FLOAT UNSIGNED", Float.class, Types.REAL, "1.0", 1.0f); // not Types.FLOAT!
+        assertType("DOUBLE", Double.class, Types.DOUBLE, "-1.0", -1.0d);
+        assertType("DOUBLE UNSIGNED", Double.class, Types.DOUBLE, "1.0", 1.0d);
+    }
+
+    @Test
+    public void testBitTypes() throws SQLException {
+        assertType("BIT", Boolean.class, Types.BIT, "0", false);
+        assertType("BIT(1)", Boolean.class, Types.BIT, "1", true);
+        assertType("BIT(2)", byte[].class, Types.VARBINARY, "b'11'", new byte[]{3});
+        assertType("BIT(8)", byte[].class, Types.VARBINARY, "b'11111111'", new byte[]{-1});
+        assertType("BIT(16)", byte[].class, Types.VARBINARY, "b'1111111111111111'", new byte[]{-1, -1});
+        assertType("BIT(24)", byte[].class, Types.VARBINARY, "b'111111111111111111111111'", new byte[]{-1, -1, -1});
+        assertType("BIT(32)", byte[].class, Types.VARBINARY, "b'11111111111111111111111111111111'", new byte[]{-1, -1, -1, -1});
+        assertType("BIT(64)", byte[].class, Types.VARBINARY, "b'1111111111111111111111111111111111111111111111111111111111111111'", new byte[]{-1, -1, -1, -1, -1, -1, -1, -1});
+    }
+
+    private void assertType(String columnType, Class expectedClass, int expectedJdbcType, String strValue, Object expectedObjectValue) throws SQLException {
+        assertNotNull(expectedObjectValue);
+        assertSame("bad test spec: ", expectedClass, expectedObjectValue.getClass());
+        Statement statement = connection.createStatement();
+        try {
+            statement.execute("DROP TABLE IF EXISTS my_table");
+            statement.execute("CREATE TABLE my_table (my_col " + columnType + ")");
+            statement.execute("INSERT INTO my_table(my_col) VALUES (" + strValue + ")");
+            statement.execute("SELECT * FROM my_table");
+            ResultSet resultSet = statement.getResultSet();
+            try {
+                ResultSetMetaData metaData = resultSet.getMetaData();
+                assertEquals("class name  for " + columnType, expectedClass.getName(), metaData.getColumnClassName(1));
+                assertEquals("java.sql.Types code for " + columnType, expectedJdbcType, metaData.getColumnType(1));
+                resultSet.next();
+                Object objectValue = resultSet.getObject(1);
+                assertEquals(expectedClass, objectValue.getClass());
+                if (expectedClass.isArray()) {
+                    assertTrue(Arrays.equals((byte[]) expectedObjectValue, (byte[]) objectValue));
+                } else {
+                    assertEquals(expectedObjectValue, objectValue);
+                }
+            } finally {
+                resultSet.close();
+            }
+        } finally {
+            statement.close();
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/src/test/java/org/mariadb/jdbc/DatatypeTest.java b/src/test/java/org/mariadb/jdbc/DatatypeTest.java
index 8266de7..f7965bd 100644
--- a/src/test/java/org/mariadb/jdbc/DatatypeTest.java
+++ b/src/test/java/org/mariadb/jdbc/DatatypeTest.java
@@ -89,14 +89,14 @@ public class DatatypeTest extends BaseTest {
         checkClass("bool0", tinyInt1isBit?Boolean.class:Integer.class,"TINYINT",
                 tinyInt1isBit?Types.BIT:Types.TINYINT);
         checkClass("smallint0", Integer.class, "SMALLINT", Types.SMALLINT);
-        checkClass("smallint_unsigned", Integer.class, "SMALLINT UNSIGNED", Types.INTEGER);
+        checkClass("smallint_unsigned", Integer.class, "SMALLINT UNSIGNED", Types.SMALLINT);
         checkClass("mediumint0", Integer.class, "MEDIUMINT", Types.INTEGER);
         checkClass("mediumint_unsigned", Integer.class, "MEDIUMINT UNSIGNED", Types.INTEGER);
         checkClass("int0", Integer.class, "INTEGER", Types.INTEGER);
-        checkClass("int_unsigned", Long.class, "INTEGER UNSIGNED", Types.BIGINT);
+        checkClass("int_unsigned", Long.class, "INTEGER UNSIGNED", Types.INTEGER);
         checkClass("bigint0", Long.class, "BIGINT", Types.BIGINT);
         checkClass("bigint_unsigned", BigInteger.class, "BIGINT UNSIGNED", Types.BIGINT);
-        checkClass("float0", Float.class, "FLOAT",Types.FLOAT);
+        checkClass("float0", Float.class, "FLOAT",Types.REAL);
         checkClass("double0", Double.class, "DOUBLE", Types.DOUBLE);
         checkClass("decimal0", BigDecimal.class, "DECIMAL", Types.DECIMAL);
         checkClass("date0", java.sql.Date.class, "DATE", Types.DATE);
diff --git a/src/test/java/org/mariadb/jdbc/DriverTest.java b/src/test/java/org/mariadb/jdbc/DriverTest.java
index c1a3ed5..72c9ef4 100644
--- a/src/test/java/org/mariadb/jdbc/DriverTest.java
+++ b/src/test/java/org/mariadb/jdbc/DriverTest.java
@@ -30,8 +30,7 @@ public class DriverTest extends BaseTest{
     @Test
     public void doQuery() throws SQLException{
         Statement stmt = connection.createStatement();
-        try { stmt.execute("drop table t1"); } catch (Exception e) {}
-        stmt.execute("create table t1 (id int not null primary key auto_increment, test varchar(20))");
+        createTablet1(stmt);
         stmt.execute("insert into t1 (test) values ('hej1')");
         stmt.execute("insert into t1 (test) values ('hej2')");
         stmt.execute("insert into t1 (test) values ('hej3')");
@@ -45,11 +44,16 @@ public class DriverTest extends BaseTest{
         rs.next();
         assertEquals(null,rs.getString("test"));
     }
+
+    private void createTablet1(Statement stmt) throws SQLException {
+        try { stmt.execute("drop table t1"); } catch (Exception e) {}
+        stmt.execute("create table t1 (id int not null primary key auto_increment, test varchar(20))");
+    }
+
     @Test(expected = SQLException.class)
     public void askForBadColumnTest() throws SQLException{
         Statement stmt = connection.createStatement();
-        try { stmt.execute("drop table t1"); } catch (Exception e) {}
-        stmt.execute("create table t1 (id int not null primary key auto_increment, test varchar(20))");
+        createTablet1(stmt);
         stmt.execute("insert into t1 (test) values ('hej1')");
         stmt.execute("insert into t1 (test) values ('hej2')");
         stmt.execute("insert into t1 (test) values ('hej3')");
@@ -62,8 +66,7 @@ public class DriverTest extends BaseTest{
     public void askForBadColumnIndexTest() throws SQLException{
 
         Statement stmt = connection.createStatement();
-        try { stmt.execute("drop table t1"); } catch (Exception e) {}
-        stmt.execute("create table t1 (id int not null primary key auto_increment, test varchar(20))");
+        createTablet1(stmt);
         stmt.execute("insert into t1 (test) values ('hej1')");
         stmt.execute("insert into t1 (test) values ('hej2')");
         stmt.execute("insert into t1 (test) values ('hej3')");
@@ -110,6 +113,11 @@ public class DriverTest extends BaseTest{
     }
     @Test
     public void preparedTest() throws SQLException {
+        Statement stmt = connection.createStatement();
+        createTablet1(stmt);
+        stmt.execute("insert into t1 (test) values ('hej1')");
+        stmt.close();
+
         String query = "SELECT * FROM t1 WHERE test = ? and id = ?";
         PreparedStatement prepStmt = connection.prepareStatement(query);
         prepStmt.setString(1,"hej1");
@@ -153,8 +161,7 @@ public class DriverTest extends BaseTest{
     @Test
     public void updateTest() throws SQLException {
         Statement stmt = connection.createStatement();
-        try { stmt.execute("drop table t1"); } catch (Exception e) {}
-        stmt.execute("create table t1 (id int not null primary key auto_increment, test varchar(20))");
+        createTablet1(stmt);
         stmt.execute("insert into t1 (test) values ('hej1')");
         stmt.execute("insert into t1 (test) values ('hej2')");
         stmt.execute("insert into t1 (test) values ('hej3')");
diff --git a/src/test/java/org/mariadb/jdbc/ResultSetMetaDataTest.java b/src/test/java/org/mariadb/jdbc/ResultSetMetaDataTest.java
index 6e50320..5b9bd8b 100644
--- a/src/test/java/org/mariadb/jdbc/ResultSetMetaDataTest.java
+++ b/src/test/java/org/mariadb/jdbc/ResultSetMetaDataTest.java
@@ -34,7 +34,7 @@ public class ResultSetMetaDataTest extends BaseTest {
         assertEquals("something",rsmd.getColumnLabel(3));
         assertEquals("unikey_col",rsmd.getColumnName(3));
         assertEquals(rsmd.getColumnType(4), Types.CHAR);
-        assertEquals(rsmd.getColumnType(5), Types.INTEGER);
+        assertEquals(rsmd.getColumnType(5), Types.SMALLINT);
         
         DatabaseMetaData md = connection.getMetaData();
         ResultSet cols = md.getColumns(null, null, "test\\_rsmd",null);
-- 
1.8.3.1

