This is an automated email from the ASF dual-hosted git repository.

mbudiu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite-avatica.git


The following commit(s) were added to refs/heads/main by this push:
     new 9e6f95442 [CALCITE-5094] Calcite JDBC Adapter and Avatica should 
support MySQL UNSIGNED types of TINYINT, SMALLINT, INT, BIGINT
9e6f95442 is described below

commit 9e6f95442d72c73e1118a1cbdc4d3325eff0f487
Author: duanzhengqiang <[email protected]>
AuthorDate: Sun Feb 2 07:14:03 2025 -0300

    [CALCITE-5094] Calcite JDBC Adapter and Avatica should support MySQL 
UNSIGNED types of TINYINT, SMALLINT, INT, BIGINT
---
 bom/build.gradle.kts                               |   1 +
 core/build.gradle.kts                              |   1 +
 .../apache/calcite/avatica/AvaticaResultSet.java   |   2 +-
 .../org/apache/calcite/avatica/AvaticaSite.java    |  14 +-
 .../org/apache/calcite/avatica/ColumnMetaData.java |   9 ++
 .../java/org/apache/calcite/avatica/MetaImpl.java  |  16 ++-
 .../calcite/avatica/util/AbstractCursor.java       | 120 ++++++++++++++++-
 .../org/apache/calcite/avatica/util/Cursor.java    |  13 ++
 .../avatica/AvaticaResultSetConversionsTest.java   | 147 ++++++++++++++++-----
 .../AvaticaResultSetThrowsSqlExceptionTest.java    |  32 +++--
 .../calcite/avatica/CursorFactoryDeduceTest.java   | 106 ++++++++++++++-
 gradle.properties                                  |   1 +
 .../calcite/avatica/shadetest/ShadingTest.java     |   2 +-
 .../calcite/avatica/shadetest/ShadingTest.java     |   2 +-
 14 files changed, 411 insertions(+), 55 deletions(-)

diff --git a/bom/build.gradle.kts b/bom/build.gradle.kts
index da4b7326c..e5ebd2bf5 100644
--- a/bom/build.gradle.kts
+++ b/bom/build.gradle.kts
@@ -54,6 +54,7 @@ dependencies {
         apiv("com.google.protobuf:protobuf-java", "protobuf")
         apiv("com.h2database:h2")
         apiv("javax.servlet:javax.servlet-api", "servlet")
+        apiv("org.jooq:joou-java-6", "joou-java-6")
         apiv("junit:junit")
         apiv("net.bytebuddy:byte-buddy", "bytebuddy")
         apiv("net.bytebuddy:byte-buddy-agent", "bytebuddy")
diff --git a/core/build.gradle.kts b/core/build.gradle.kts
index 0374aaaf6..0868348b9 100644
--- a/core/build.gradle.kts
+++ b/core/build.gradle.kts
@@ -34,6 +34,7 @@ dependencies {
     api("com.fasterxml.jackson.core:jackson-annotations")
     api("com.fasterxml.jackson.core:jackson-databind")
     api("com.google.protobuf:protobuf-java")
+    api("org.jooq:joou-java-6")
     implementation("com.fasterxml.jackson.core:jackson-core")
     implementation("org.apache.httpcomponents.client5:httpclient5")
     implementation("org.apache.httpcomponents.core5:httpcore5")
diff --git 
a/core/src/main/java/org/apache/calcite/avatica/AvaticaResultSet.java 
b/core/src/main/java/org/apache/calcite/avatica/AvaticaResultSet.java
index 33ed5be0b..80e943113 100644
--- a/core/src/main/java/org/apache/calcite/avatica/AvaticaResultSet.java
+++ b/core/src/main/java/org/apache/calcite/avatica/AvaticaResultSet.java
@@ -392,7 +392,7 @@ public ResultSetMetaData getMetaData() throws SQLException {
   public Object getObject(int columnIndex) throws SQLException {
     final Cursor.Accessor accessor = getAccessor(columnIndex);
     final ColumnMetaData metaData = columnMetaDataList.get(columnIndex - 1);
-    return AvaticaSite.get(accessor, metaData.type.id, localCalendar);
+    return AvaticaSite.get(accessor, metaData.type.id, metaData.signed, 
localCalendar);
   }
 
   public Object getObject(String columnLabel) throws SQLException {
diff --git a/core/src/main/java/org/apache/calcite/avatica/AvaticaSite.java 
b/core/src/main/java/org/apache/calcite/avatica/AvaticaSite.java
index e70aa87c0..18e12f082 100644
--- a/core/src/main/java/org/apache/calcite/avatica/AvaticaSite.java
+++ b/core/src/main/java/org/apache/calcite/avatica/AvaticaSite.java
@@ -291,7 +291,7 @@ public void setObject(Object x, int targetSqlType) {
 
   /** Similar logic to {@link #setObject}. */
   public static Object get(Cursor.Accessor accessor, int targetSqlType,
-      Calendar localCalendar) throws SQLException {
+      boolean signed, Calendar localCalendar) throws SQLException {
     switch (targetSqlType) {
     case Types.CLOB:
     case Types.DATALINK:
@@ -304,6 +304,9 @@ public static Object get(Cursor.Accessor accessor, int 
targetSqlType,
     case Types.ARRAY:
       return accessor.getArray();
     case Types.BIGINT:
+      if (!signed) {
+        return accessor.wasNull() ? null : accessor.getULong();
+      }
       final long aLong = accessor.getLong();
       if (aLong == 0 && accessor.wasNull()) {
         return null;
@@ -337,6 +340,9 @@ public static Object get(Cursor.Accessor accessor, int 
targetSqlType,
       }
       return aDouble;
     case Types.INTEGER:
+      if (!signed) {
+        return accessor.wasNull() ? null : accessor.getUInt();
+      }
       final int anInt = accessor.getInt();
       if (anInt == 0 && accessor.wasNull()) {
         return null;
@@ -362,6 +368,9 @@ public static Object get(Cursor.Accessor accessor, int 
targetSqlType,
     case Types.ROWID:
       throw notImplemented();
     case Types.SMALLINT:
+      if (!signed) {
+        return accessor.wasNull() ? null : accessor.getUShort();
+      }
       final short aShort = accessor.getShort();
       if (aShort == 0 && accessor.wasNull()) {
         return null;
@@ -372,6 +381,9 @@ public static Object get(Cursor.Accessor accessor, int 
targetSqlType,
     case Types.TIMESTAMP:
       return accessor.getTimestamp(localCalendar);
     case Types.TINYINT:
+      if (!signed) {
+        return accessor.wasNull() ? null : accessor.getUByte();
+      }
       final byte aByte = accessor.getByte();
       if (aByte == 0 && accessor.wasNull()) {
         return null;
diff --git a/core/src/main/java/org/apache/calcite/avatica/ColumnMetaData.java 
b/core/src/main/java/org/apache/calcite/avatica/ColumnMetaData.java
index 2c5d55b71..5399bcdd0 100644
--- a/core/src/main/java/org/apache/calcite/avatica/ColumnMetaData.java
+++ b/core/src/main/java/org/apache/calcite/avatica/ColumnMetaData.java
@@ -25,6 +25,11 @@
 import com.fasterxml.jackson.annotation.JsonTypeInfo;
 import com.google.protobuf.Descriptors.FieldDescriptor;
 
+import org.joou.UByte;
+import org.joou.UInteger;
+import org.joou.ULong;
+import org.joou.UShort;
+
 import java.lang.reflect.Type;
 import java.math.BigDecimal;
 import java.sql.Array;
@@ -327,10 +332,14 @@ public enum Rep {
     PRIMITIVE_DOUBLE(double.class, Types.DOUBLE),
     BOOLEAN(Boolean.class, Types.BOOLEAN),
     BYTE(Byte.class, Types.TINYINT),
+    UBYTE(UByte.class, Types.TINYINT),
     CHARACTER(Character.class, Types.CHAR),
     SHORT(Short.class, Types.SMALLINT),
+    USHORT(UShort.class, Types.SMALLINT),
     INTEGER(Integer.class, Types.INTEGER),
+    UINTEGER(UInteger.class, Types.INTEGER),
     LONG(Long.class, Types.BIGINT),
+    ULONG(ULong.class, Types.BIGINT),
     FLOAT(Float.class, Types.FLOAT),
     DOUBLE(Double.class, Types.DOUBLE),
     JAVA_SQL_TIME(Time.class, Types.TIME),
diff --git a/core/src/main/java/org/apache/calcite/avatica/MetaImpl.java 
b/core/src/main/java/org/apache/calcite/avatica/MetaImpl.java
index 4eb6a2ebe..482208232 100644
--- a/core/src/main/java/org/apache/calcite/avatica/MetaImpl.java
+++ b/core/src/main/java/org/apache/calcite/avatica/MetaImpl.java
@@ -221,7 +221,12 @@ public static ColumnMetaData columnMetaData(String name, 
int index,
 
   public static ColumnMetaData columnMetaData(String name, int index, 
AvaticaType type,
       boolean columnNullable) {
-    return columnMetaData(name, index, type, 
intForColumnNullable(columnNullable));
+    return columnMetaData(name, index, type, 
intForColumnNullable(columnNullable), true);
+  }
+
+  public static ColumnMetaData columnMetaData(String name, int index, 
AvaticaType type,
+      boolean columnNullable, boolean signed) {
+    return columnMetaData(name, index, type, 
intForColumnNullable(columnNullable), signed);
   }
 
   public static ColumnMetaData columnMetaData(String name, int index,
@@ -231,15 +236,20 @@ public static ColumnMetaData columnMetaData(String name, 
int index,
         ColumnMetaData.Rep.VALUE_MAP.get(type);
     ColumnMetaData.AvaticaType scalarType =
         ColumnMetaData.scalar(pair.sqlType, pair.sqlTypeName, rep);
-    return columnMetaData(name, index, scalarType, columnNullable);
+    return columnMetaData(name, index, scalarType, columnNullable, true);
   }
 
   public static ColumnMetaData columnMetaData(String name, int index, 
AvaticaType type,
       int columnNullable) {
+    return columnMetaData(name, index, type, columnNullable, true);
+  }
+
+  public static ColumnMetaData columnMetaData(String name, int index, 
AvaticaType type,
+      int columnNullable, boolean signed) {
     return new ColumnMetaData(
         index, false, true, false, false,
         columnNullable,
-        true, -1, name, name, null,
+        signed, -1, name, name, null,
         0, 0, null, null, type, true, false, false,
         type.columnClassName());
   }
diff --git 
a/core/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java 
b/core/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java
index 2c5653ae0..e63ac7172 100644
--- a/core/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java
+++ b/core/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java
@@ -20,6 +20,11 @@
 import org.apache.calcite.avatica.AvaticaUtils;
 import org.apache.calcite.avatica.ColumnMetaData;
 
+import org.joou.UByte;
+import org.joou.UInteger;
+import org.joou.ULong;
+import org.joou.UShort;
+
 import java.io.InputStream;
 import java.io.Reader;
 import java.lang.reflect.Field;
@@ -102,13 +107,13 @@ protected Accessor createAccessor(ColumnMetaData 
columnMetaData,
     }
     switch (columnMetaData.type.id) {
     case Types.TINYINT:
-      return new ByteAccessor(getter);
+      return columnMetaData.signed ? new ByteAccessor(getter) : new 
UByteAccessor(getter);
     case Types.SMALLINT:
-      return new ShortAccessor(getter);
+      return columnMetaData.signed ? new ShortAccessor(getter) : new 
UShortAccessor(getter);
     case Types.INTEGER:
-      return new IntAccessor(getter);
+      return columnMetaData.signed ? new IntAccessor(getter) : new 
UIntAccessor(getter);
     case Types.BIGINT:
-      return new LongAccessor(getter);
+      return columnMetaData.signed ? new LongAccessor(getter) : new 
ULongAccessor(getter);
     case Types.BOOLEAN:
     case Types.BIT:
       return new BooleanAccessor(getter);
@@ -288,18 +293,38 @@ public byte getByte() throws SQLException {
       return (byte) getLong();
     }
 
+    @Override
+    public UByte getUByte() throws SQLException {
+      return UByte.valueOf(getLong());
+    }
+
     public short getShort() throws SQLException {
       return (short) getLong();
     }
 
+    @Override
+    public UShort getUShort() throws SQLException {
+      return UShort.valueOf(String.valueOf(getLong()));
+    }
+
     public int getInt() throws SQLException {
       return (int) getLong();
     }
 
+    @Override
+    public UInteger getUInt() throws SQLException {
+      return UInteger.valueOf(getLong());
+    }
+
     public long getLong() throws SQLException {
       throw cannotConvert("long");
     }
 
+    @Override
+    public ULong getULong() throws SQLException {
+      return ULong.valueOf(getBigDecimal().toBigInteger());
+    }
+
     public float getFloat() throws SQLException {
       return (float) getDouble();
     }
@@ -485,6 +510,30 @@ public long getLong() throws SQLException {
     }
   }
 
+  /**
+   * Accessor that assumes that the underlying value is a {@link UByte};
+   * corresponds to {@link java.sql.Types#TINYINT} with unsigned flag.
+   */
+  private static class UByteAccessor extends ExactNumericAccessor {
+    private UByteAccessor(Getter getter) {
+      super(getter);
+    }
+
+    public UByte getUByte() throws SQLException {
+      Object obj = getObject();
+      if (null == obj) {
+        return UByte.valueOf(0);
+      } else if (obj instanceof Integer) {
+        return UByte.valueOf(((Integer) obj).byteValue());
+      }
+      return UByte.valueOf(String.valueOf(obj));
+    }
+
+    public long getLong() throws SQLException {
+      return getUByte().longValue();
+    }
+  }
+
   /**
    * Accessor that assumes that the underlying value is a {@link Short};
    * corresponds to {@link java.sql.Types#SMALLINT}.
@@ -509,6 +558,30 @@ public long getLong() throws SQLException {
     }
   }
 
+  /**
+   * Accessor that assumes that the underlying value is a {@link UShort};
+   * corresponds to {@link java.sql.Types#SMALLINT} with unsigned flag.
+   */
+  private static class UShortAccessor extends ExactNumericAccessor {
+    private UShortAccessor(Getter getter) {
+      super(getter);
+    }
+
+    public UShort getUShort() throws SQLException {
+      Object obj = getObject();
+      if (null == obj) {
+        return UShort.valueOf(0);
+      } else if (obj instanceof Integer) {
+        return UShort.valueOf(((Integer) obj).shortValue());
+      }
+      return UShort.valueOf(String.valueOf(obj));
+    }
+
+    public long getLong() throws SQLException {
+      return getUShort().longValue();
+    }
+  }
+
   /**
    * Accessor that assumes that the underlying value is an {@link Integer};
    * corresponds to {@link java.sql.Types#INTEGER}.
@@ -528,6 +601,25 @@ public long getLong() throws SQLException {
     }
   }
 
+  /**
+   * Accessor that assumes that the underlying value is an {@link UInteger};
+   * corresponds to {@link java.sql.Types#INTEGER} with unsigned flag.
+   */
+  private static class UIntAccessor extends ExactNumericAccessor {
+    private UIntAccessor(Getter getter) {
+      super(getter);
+    }
+
+    public UInteger getUInt() throws SQLException {
+      Object o = getObject();
+      return UInteger.valueOf(o == null ? "0" : String.valueOf(o));
+    }
+
+    public long getLong() throws SQLException {
+      return getUInt().longValue();
+    }
+  }
+
   /**
    * Accessor that assumes that the underlying value is a {@link Long};
    * corresponds to {@link java.sql.Types#BIGINT}.
@@ -543,6 +635,26 @@ public long getLong() throws SQLException {
     }
   }
 
+  /**
+   * Accessor that assumes that the underlying value is a {@link ULong};
+   * corresponds to {@link java.sql.Types#BIGINT} with unsigned flag.
+   */
+  private static class ULongAccessor extends ExactNumericAccessor {
+    private ULongAccessor(Getter getter) {
+      super(getter);
+    }
+
+    public ULong getULong() throws SQLException {
+      Object o = getObject();
+      return ULong.valueOf(o == null ? "0" : String.valueOf(o));
+    }
+
+    @Override
+    public long getLong() throws SQLException {
+      return getULong().longValue();
+    }
+  }
+
   /**
    * Accessor of values that are {@link Double} or null.
    */
diff --git a/core/src/main/java/org/apache/calcite/avatica/util/Cursor.java 
b/core/src/main/java/org/apache/calcite/avatica/util/Cursor.java
index 9eeb2df7c..8d9be8dad 100644
--- a/core/src/main/java/org/apache/calcite/avatica/util/Cursor.java
+++ b/core/src/main/java/org/apache/calcite/avatica/util/Cursor.java
@@ -18,6 +18,11 @@
 
 import org.apache.calcite.avatica.ColumnMetaData;
 
+import org.joou.UByte;
+import org.joou.UInteger;
+import org.joou.ULong;
+import org.joou.UShort;
+
 import java.io.InputStream;
 import java.io.Reader;
 import java.math.BigDecimal;
@@ -87,12 +92,20 @@ interface Accessor {
 
     byte getByte() throws SQLException;
 
+    UByte getUByte() throws SQLException;
+
     short getShort() throws SQLException;
 
+    UShort getUShort() throws SQLException;
+
     int getInt() throws SQLException;
 
+    UInteger getUInt() throws SQLException;
+
     long getLong() throws SQLException;
 
+    ULong getULong() throws SQLException;
+
     float getFloat() throws SQLException;
 
     double getDouble() throws SQLException;
diff --git 
a/core/src/test/java/org/apache/calcite/avatica/AvaticaResultSetConversionsTest.java
 
b/core/src/test/java/org/apache/calcite/avatica/AvaticaResultSetConversionsTest.java
index 065ebf43b..d427a2fd8 100644
--- 
a/core/src/test/java/org/apache/calcite/avatica/AvaticaResultSetConversionsTest.java
+++ 
b/core/src/test/java/org/apache/calcite/avatica/AvaticaResultSetConversionsTest.java
@@ -33,6 +33,7 @@
 import java.io.InputStream;
 import java.io.Reader;
 import java.math.BigDecimal;
+import java.math.BigInteger;
 import java.net.URL;
 import java.sql.Array;
 import java.sql.Blob;
@@ -147,46 +148,70 @@ public TestMetaImpl(AvaticaConnection connection) {
               ColumnMetaData.scalar(Types.SMALLINT, "SMALLINT",
                   ColumnMetaData.Rep.PRIMITIVE_SHORT),
               DatabaseMetaData.columnNoNulls),
-          columnMetaData("int", 3,
+          columnMetaData("medium", 3,
+              ColumnMetaData.scalar(Types.INTEGER, "MEDIUMINT",
+                  ColumnMetaData.Rep.PRIMITIVE_INT),
+              DatabaseMetaData.columnNoNulls),
+          columnMetaData("int", 4,
               ColumnMetaData.scalar(Types.INTEGER, "INTEGER",
                   ColumnMetaData.Rep.PRIMITIVE_INT),
               DatabaseMetaData.columnNoNulls),
-          columnMetaData("long", 4,
+          columnMetaData("long", 5,
               ColumnMetaData.scalar(Types.BIGINT, "BIGINT",
                   ColumnMetaData.Rep.PRIMITIVE_LONG),
               DatabaseMetaData.columnNoNulls),
-          columnMetaData("float", 5,
+          columnMetaData("byte_unsigned", 6,
+              ColumnMetaData.scalar(Types.TINYINT, "TINYINT_UNSIGNED",
+                  ColumnMetaData.Rep.PRIMITIVE_SHORT),
+              DatabaseMetaData.columnNoNulls, false),
+          columnMetaData("short_unsigned", 7,
+              ColumnMetaData.scalar(Types.SMALLINT, "SMALLINT_UNSIGNED",
+                  ColumnMetaData.Rep.PRIMITIVE_INT),
+              DatabaseMetaData.columnNoNulls, false),
+          columnMetaData("medium_unsigned", 8,
+              ColumnMetaData.scalar(Types.INTEGER, "MEDIUMINT_UNSIGNED",
+                  ColumnMetaData.Rep.PRIMITIVE_INT),
+              DatabaseMetaData.columnNoNulls, false),
+          columnMetaData("int_unsigned", 9,
+              ColumnMetaData.scalar(Types.INTEGER, "INTEGER_UNSIGNED",
+                  ColumnMetaData.Rep.PRIMITIVE_LONG),
+              DatabaseMetaData.columnNoNulls, false),
+          columnMetaData("long_unsigned", 10,
+              ColumnMetaData.scalar(Types.BIGINT, "BIGINT_UNSIGNED",
+                  ColumnMetaData.Rep.NUMBER),
+              DatabaseMetaData.columnNoNulls, false),
+          columnMetaData("float", 11,
               ColumnMetaData.scalar(Types.REAL, "REAL",
                   ColumnMetaData.Rep.FLOAT),
               DatabaseMetaData.columnNoNulls),
-          columnMetaData("double", 6,
+          columnMetaData("double", 12,
               ColumnMetaData.scalar(Types.FLOAT, "FLOAT",
                   ColumnMetaData.Rep.DOUBLE),
               DatabaseMetaData.columnNoNulls),
-          columnMetaData("string", 7,
+          columnMetaData("string", 13,
               ColumnMetaData.scalar(Types.VARCHAR, "VARCHAR",
                   ColumnMetaData.Rep.STRING),
               DatabaseMetaData.columnNoNulls),
-          columnMetaData("date", 8,
+          columnMetaData("date", 14,
               ColumnMetaData.scalar(Types.DATE, "DATE",
                   ColumnMetaData.Rep.JAVA_SQL_DATE),
               DatabaseMetaData.columnNoNulls),
-          columnMetaData("time", 9,
+          columnMetaData("time", 15,
               ColumnMetaData.scalar(Types.TIME, "TIME",
                   ColumnMetaData.Rep.JAVA_SQL_TIME),
               DatabaseMetaData.columnNoNulls),
-          columnMetaData("timestamp", 10,
+          columnMetaData("timestamp", 16,
               ColumnMetaData.scalar(Types.TIMESTAMP, "TIMESTAMP",
                   ColumnMetaData.Rep.JAVA_SQL_TIMESTAMP),
               DatabaseMetaData.columnNoNulls),
-          columnMetaData("array", 11,
+          columnMetaData("array", 17,
               ColumnMetaData.array(
                   ColumnMetaData.scalar(Types.INTEGER, "INTEGER",
                       ColumnMetaData.Rep.PRIMITIVE_INT),
                   "ARRAY",
                   ColumnMetaData.Rep.ARRAY),
               DatabaseMetaData.columnNoNulls),
-          columnMetaData("struct", 12,
+          columnMetaData("struct", 18,
               ColumnMetaData.struct(
                   Arrays.asList(
                       columnMetaData("int", 0,
@@ -198,36 +223,36 @@ public TestMetaImpl(AvaticaConnection connection) {
                               ColumnMetaData.Rep.PRIMITIVE_BOOLEAN),
                           DatabaseMetaData.columnNoNulls))),
               DatabaseMetaData.columnNoNulls),
-          columnMetaData("bit", 13,
+          columnMetaData("bit", 19,
               ColumnMetaData.scalar(Types.BIT, "BIT",
                   ColumnMetaData.Rep.PRIMITIVE_BOOLEAN),
               DatabaseMetaData.columnNoNulls),
-          columnMetaData("null", 14,
+          columnMetaData("null", 20,
               ColumnMetaData.scalar(Types.NULL, "NULL",
                   ColumnMetaData.Rep.OBJECT),
               DatabaseMetaData.columnNullable),
-          columnMetaData("date_array", 15,
+          columnMetaData("date_array", 21,
               ColumnMetaData.array(
                   ColumnMetaData.scalar(Types.DATE, "DATE",
                       ColumnMetaData.Rep.PRIMITIVE_INT),
                   "ARRAY",
                   ColumnMetaData.Rep.ARRAY),
               DatabaseMetaData.columnNoNulls),
-          columnMetaData("timestamp_array", 16,
+          columnMetaData("timestamp_array", 22,
               ColumnMetaData.array(
                   ColumnMetaData.scalar(Types.TIMESTAMP, "TIMESTAMP",
                       ColumnMetaData.Rep.PRIMITIVE_LONG),
                   "ARRAY",
                   ColumnMetaData.Rep.ARRAY),
               DatabaseMetaData.columnNoNulls),
-          columnMetaData("time_array", 17,
+          columnMetaData("time_array", 23,
               ColumnMetaData.array(
                   ColumnMetaData.scalar(Types.TIME, "TIME",
                       ColumnMetaData.Rep.NUMBER),
                   "ARRAY",
                   ColumnMetaData.Rep.ARRAY),
               DatabaseMetaData.columnNoNulls),
-          columnMetaData("decimal_array", 18,
+          columnMetaData("decimal_array", 24,
               ColumnMetaData.array(
                   ColumnMetaData.scalar(Types.DECIMAL, "DECIMAL",
                       ColumnMetaData.Rep.PRIMITIVE_DOUBLE),
@@ -237,7 +262,8 @@ public TestMetaImpl(AvaticaConnection connection) {
 
       List<Object> row = Collections.<Object>singletonList(
           new Object[] {
-              true, (byte) 1, (short) 2, 3, 4L, 5.0f, 6.0d, "testvalue",
+              true, (byte) 1, (short) 2, 3, 3, 4L, (short) 2, 3, 4L, 4L,
+              new BigInteger("7"), 5.0f, 6.0d, "testvalue",
               new Date(DST_INSTANT), new Time(DST_INSTANT),
               new Timestamp(DST_INSTANT),
               Arrays.asList(1, 2, 3),
@@ -910,6 +936,51 @@ private LongAccessorTestHelper(Getter g) {
     }
   }
 
+  /**
+   * Accessor test helper for the long unsigned column.
+   */
+  private static final class LongUnsingedAccessorTestHelper extends 
AccessorTestHelper {
+    private LongUnsingedAccessorTestHelper(Getter g) {
+      super(g);
+    }
+
+    @Override public void testGetString(ResultSet resultSet) throws 
SQLException {
+      assertEquals("7", g.getString(resultSet));
+    }
+
+    @Override public void testGetBoolean(ResultSet resultSet) throws 
SQLException {
+      assertEquals(true, g.getBoolean(resultSet));
+    }
+
+    @Override public void testGetByte(ResultSet resultSet) throws SQLException 
{
+      assertEquals((byte) 7, g.getByte(resultSet));
+    }
+
+    @Override public void testGetShort(ResultSet resultSet) throws 
SQLException {
+      assertEquals((short) 7, g.getShort(resultSet));
+    }
+
+    @Override public void testGetInt(ResultSet resultSet) throws SQLException {
+      assertEquals(7, g.getInt(resultSet));
+    }
+
+    @Override public void testGetLong(ResultSet resultSet) throws SQLException 
{
+      assertEquals(7L, g.getLong(resultSet));
+    }
+
+    @Override public void testGetDecimal(ResultSet resultSet) throws 
SQLException {
+      assertEquals(new BigDecimal(7), g.getBigDecimal(resultSet));
+    }
+
+    @Override public void testGetFloat(ResultSet resultSet) throws 
SQLException {
+      assertEquals(7.0f, g.getFloat(resultSet), 0);
+    }
+
+    @Override public void testGetDouble(ResultSet resultSet) throws 
SQLException {
+      assertEquals(7.0d, g.getDouble(resultSet), 0);
+    }
+  }
+
   /**
    * accessor test helper for the float column
    */
@@ -1169,36 +1240,48 @@ public static Collection<AccessorTestHelper> data() {
         new ShortAccessorTestHelper(new OrdinalGetter(3)),
         new ShortAccessorTestHelper(new LabelGetter("short")),
         new IntAccessorTestHelper(new OrdinalGetter(4)),
+        new IntAccessorTestHelper(new LabelGetter("medium")),
+        new IntAccessorTestHelper(new OrdinalGetter(5)),
         new IntAccessorTestHelper(new LabelGetter("int")),
-        new LongAccessorTestHelper(new OrdinalGetter(5)),
+        new LongAccessorTestHelper(new OrdinalGetter(6)),
         new LongAccessorTestHelper(new LabelGetter("long")),
-        new FloatAccessorTestHelper(new OrdinalGetter(6)),
+        new ShortAccessorTestHelper(new OrdinalGetter(7)),
+        new ShortAccessorTestHelper(new LabelGetter("byte_unsigned")),
+        new IntAccessorTestHelper(new OrdinalGetter(8)),
+        new IntAccessorTestHelper(new LabelGetter("short_unsigned")),
+        new LongAccessorTestHelper(new OrdinalGetter(9)),
+        new LongAccessorTestHelper(new LabelGetter("medium_unsigned")),
+        new LongAccessorTestHelper(new OrdinalGetter(10)),
+        new LongAccessorTestHelper(new LabelGetter("int_unsigned")),
+        new LongUnsingedAccessorTestHelper(new OrdinalGetter(11)),
+        new LongUnsingedAccessorTestHelper(new LabelGetter("long_unsigned")),
+        new FloatAccessorTestHelper(new OrdinalGetter(12)),
         new FloatAccessorTestHelper(new LabelGetter("float")),
-        new DoubleAccessorTestHelper(new OrdinalGetter(7)),
+        new DoubleAccessorTestHelper(new OrdinalGetter(13)),
         new DoubleAccessorTestHelper(new LabelGetter("double")),
-        new StringAccessorTestHelper(new OrdinalGetter(8)),
+        new StringAccessorTestHelper(new OrdinalGetter(14)),
         new StringAccessorTestHelper(new LabelGetter("string")),
-        new DateAccessorTestHelper(new OrdinalGetter(9)),
+        new DateAccessorTestHelper(new OrdinalGetter(15)),
         new DateAccessorTestHelper(new LabelGetter("date")),
-        new TimeAccessorTestHelper(new OrdinalGetter(10)),
+        new TimeAccessorTestHelper(new OrdinalGetter(16)),
         new TimeAccessorTestHelper(new LabelGetter("time")),
-        new TimestampAccessorTestHelper(new OrdinalGetter(11)),
+        new TimestampAccessorTestHelper(new OrdinalGetter(17)),
         new TimestampAccessorTestHelper(new LabelGetter("timestamp")),
-        new ArrayAccessorTestHelper(new OrdinalGetter(12)),
+        new ArrayAccessorTestHelper(new OrdinalGetter(18)),
         new ArrayAccessorTestHelper(new LabelGetter("array")),
-        new StructAccessorTestHelper(new OrdinalGetter(13)),
+        new StructAccessorTestHelper(new OrdinalGetter(19)),
         new StructAccessorTestHelper(new LabelGetter("struct")),
-        new BooleanAccessorTestHelper(new OrdinalGetter(14)),
+        new BooleanAccessorTestHelper(new OrdinalGetter(20)),
         new BooleanAccessorTestHelper(new LabelGetter("bit")),
-        new NullObjectAccessorTestHelper(new OrdinalGetter(15)),
+        new NullObjectAccessorTestHelper(new OrdinalGetter(21)),
         new NullObjectAccessorTestHelper(new LabelGetter("null")),
-        new DateArrayAccessorTestHelper(new OrdinalGetter(16)),
+        new DateArrayAccessorTestHelper(new OrdinalGetter(22)),
         new DateArrayAccessorTestHelper(new LabelGetter("date_array")),
-        new TimestampArrayAccessorTestHelper(new OrdinalGetter(17)),
+        new TimestampArrayAccessorTestHelper(new OrdinalGetter(23)),
         new TimestampArrayAccessorTestHelper(new 
LabelGetter("timestamp_array")),
-        new TimeArrayAccessorTestHelper(new OrdinalGetter(18)),
+        new TimeArrayAccessorTestHelper(new OrdinalGetter(24)),
         new TimeArrayAccessorTestHelper(new LabelGetter("time_array")),
-        new DecimalArrayAccessorTestHelper(new OrdinalGetter(19)),
+        new DecimalArrayAccessorTestHelper(new OrdinalGetter(25)),
         new DecimalArrayAccessorTestHelper(new LabelGetter("decimal_array")));
   }
 
diff --git 
a/core/src/test/java/org/apache/calcite/avatica/AvaticaResultSetThrowsSqlExceptionTest.java
 
b/core/src/test/java/org/apache/calcite/avatica/AvaticaResultSetThrowsSqlExceptionTest.java
index 1eebdd979..4725fed5a 100644
--- 
a/core/src/test/java/org/apache/calcite/avatica/AvaticaResultSetThrowsSqlExceptionTest.java
+++ 
b/core/src/test/java/org/apache/calcite/avatica/AvaticaResultSetThrowsSqlExceptionTest.java
@@ -138,28 +138,44 @@ private boolean getColumn(final ResultSet resultSet, 
final int index,
       case 3: // SMALLINT
         resultSet.getShort(index);
         break;
-      case 4: // INTEGER
+      case 4: // MEDIUMINT
+      case 5: // INTEGER
         resultSet.getInt(index);
         break;
-      case 5: // BIGINT
+      case 6: // BIGINT
         resultSet.getLong(index);
         break;
-      case 6: // REAL
+      case 7: // TINYINT_UNSIGNED
+        resultSet.getShort(index);
+        break;
+      case 8: // SMALLINT_UNSIGNED
+        resultSet.getInt(index);
+        break;
+      case 9: // MEDIUMINT_UNSIGNED
+        resultSet.getLong(index);
+        break;
+      case 10: // INTEGER_UNSIGNED
+        resultSet.getLong(index);
+        break;
+      case 11: // BIGINT_UNSIGNED
+        resultSet.getBigDecimal(index);
+        break;
+      case 12: // REAL
         resultSet.getFloat(index);
         break;
-      case 7: // FLOAT
+      case 13: // FLOAT
         resultSet.getDouble(index);
         break;
-      case 8: // VARCHAR
+      case 14: // VARCHAR
         resultSet.getString(index);
         break;
-      case 9: // DATE
+      case 15: // DATE
         resultSet.getDate(index);
         break;
-      case 10: // TIME
+      case 16: // TIME
         resultSet.getTime(index);
         break;
-      case 11: // TIMESTAMP
+      case 17: // TIMESTAMP
         resultSet.getTimestamp(index);
         break;
       default:
diff --git 
a/core/src/test/java/org/apache/calcite/avatica/CursorFactoryDeduceTest.java 
b/core/src/test/java/org/apache/calcite/avatica/CursorFactoryDeduceTest.java
index 6050ba425..3ef769d28 100644
--- a/core/src/test/java/org/apache/calcite/avatica/CursorFactoryDeduceTest.java
+++ b/core/src/test/java/org/apache/calcite/avatica/CursorFactoryDeduceTest.java
@@ -21,6 +21,7 @@
 
 import org.junit.Test;
 
+import java.math.BigInteger;
 import java.sql.Types;
 import java.util.Arrays;
 import java.util.Collections;
@@ -49,19 +50,29 @@ public class CursorFactoryDeduceTest {
       ColumnMetaData.scalar(Types.DOUBLE, "DOUBLE", ColumnMetaData.Rep.DOUBLE);
 
   static final List<Object> ROWS = IntStream.range(1, 5)
-      .mapToObj(i -> (Object) new SimplePOJO(i, Integer.toString(i), (double) 
i))
+      .mapToObj(i -> (Object) new SimplePOJO((byte) i, (short) i, i, i,
+          new BigInteger(Integer.toString(i)), Integer.toString(i), (double) 
i))
       .collect(Collectors.toList());
 
   /**
    * Simple POJO for testing cursors over Java objects.
    */
   protected static class SimplePOJO {
+    public byte byteField;
+    public short shortField;
     public int intField;
+    public long longField;
+    public BigInteger bigIntField;
     public String stringField;
     public Double doubleField;
 
-    SimplePOJO(int intField, String stringField, Double doubleField) {
+    SimplePOJO(byte byteField, short shortField, int intField, long longField,
+               BigInteger bigIntField, String stringField, Double doubleField) 
{
+      this.byteField = byteField;
+      this.shortField = shortField;
       this.intField = intField;
+      this.longField = longField;
+      this.bigIntField = bigIntField;
       this.stringField = stringField;
       this.doubleField = doubleField;
     }
@@ -81,13 +92,18 @@ protected static class SimplePOJO {
 
       SimplePOJO pjo = (SimplePOJO) o;
 
-      return Objects.equals(stringField, pjo.stringField)
+      return Objects.equals(byteField, pjo.byteField)
+          && Objects.equals(shortField, pjo.shortField)
           && Objects.equals(intField, pjo.intField)
+          && Objects.equals(longField, pjo.longField)
+          && Objects.equals(bigIntField, pjo.bigIntField)
+          && Objects.equals(stringField, pjo.stringField)
           && Objects.equals(doubleField, pjo.doubleField);
     }
 
     @Override public int hashCode() {
-      return Objects.hash(stringField, intField, doubleField);
+      return Objects.hash(byteField, shortField, intField,
+          longField, bigIntField, stringField, doubleField);
     }
   }
 
@@ -244,6 +260,88 @@ protected static class SimplePOJO {
       assertFalse(cursor.next());
     }
   }
+
+  @Test public void deduceRecordCursorFactoryProjectedSignedField() throws 
Exception {
+    List<ColumnMetaData> columnsMetaDataList = Arrays.asList(
+        MetaImpl.columnMetaData("byteField", 1, ColumnMetaData.scalar(
+            Types.TINYINT, "TINYINT", ColumnMetaData.Rep.BYTE), true, true),
+        MetaImpl.columnMetaData("shortField", 2, ColumnMetaData.scalar(
+            Types.SMALLINT, "SMALLINT", ColumnMetaData.Rep.SHORT), true, true),
+        MetaImpl.columnMetaData("intField", 3, ColumnMetaData.scalar(
+            Types.INTEGER, "MEDIUMINT", ColumnMetaData.Rep.INTEGER), true, 
true),
+        MetaImpl.columnMetaData("intField", 4, ColumnMetaData.scalar(
+            Types.INTEGER, "INT", ColumnMetaData.Rep.INTEGER), true, true),
+        MetaImpl.columnMetaData("longField", 5, ColumnMetaData.scalar(
+            Types.BIGINT, "BIGINT", ColumnMetaData.Rep.LONG), true, true)
+    );
+    Meta.CursorFactory cursorFactory =
+        Meta.CursorFactory.deduce(columnsMetaDataList, SimplePOJO.class);
+
+    try (Cursor cursor = MetaImpl.createCursor(cursorFactory, ROWS)) {
+      List<Cursor.Accessor> accessors =
+          cursor.createAccessors(columnsMetaDataList, Unsafe.localCalendar(), 
null);
+
+      assertEquals(columnsMetaDataList.size(), accessors.size());
+      Cursor.Accessor byteAccessor = accessors.get(0);
+      Cursor.Accessor shortAccessor = accessors.get(1);
+      Cursor.Accessor intAccessor = accessors.get(2);
+      Cursor.Accessor intAccessor2 = accessors.get(3);
+      Cursor.Accessor longAccessor = accessors.get(4);
+
+      for (Object row : ROWS) {
+        assertTrue(cursor.next());
+        SimplePOJO pjo = (SimplePOJO) row;
+        assertEquals(pjo.byteField, byteAccessor.getObject());
+        assertEquals(pjo.shortField, shortAccessor.getObject());
+        assertEquals(pjo.intField, intAccessor.getObject());
+        assertEquals(pjo.intField, intAccessor2.getObject());
+        assertEquals(pjo.longField, longAccessor.getObject());
+      }
+
+      assertFalse(cursor.next());
+    }
+  }
+
+  @Test public void deduceRecordCursorFactoryProjectedUnsignedField() throws 
Exception {
+    List<ColumnMetaData> columnsMetaDataList = Arrays.asList(
+        MetaImpl.columnMetaData("shortField", 1, ColumnMetaData.scalar(
+            Types.TINYINT, "TINYINT_UNSIGNED", ColumnMetaData.Rep.UBYTE), 
true, false),
+        MetaImpl.columnMetaData("intField", 2, ColumnMetaData.scalar(
+            Types.SMALLINT, "SMALLINT_UNSIGNED", ColumnMetaData.Rep.USHORT), 
true, false),
+        MetaImpl.columnMetaData("longField", 3, ColumnMetaData.scalar(
+            Types.INTEGER, "MEDIUMINT_UNSIGNED", ColumnMetaData.Rep.UINTEGER), 
true, false),
+        MetaImpl.columnMetaData("longField", 4, ColumnMetaData.scalar(
+            Types.INTEGER, "INT_UNSIGNED", ColumnMetaData.Rep.UINTEGER), true, 
false),
+        MetaImpl.columnMetaData("bigIntField", 5, ColumnMetaData.scalar(
+            Types.BIGINT, "BIGINT_UNSIGNED", ColumnMetaData.Rep.ULONG), true, 
false)
+    );
+    Meta.CursorFactory cursorFactory =
+        Meta.CursorFactory.deduce(columnsMetaDataList, SimplePOJO.class);
+
+    try (Cursor cursor = MetaImpl.createCursor(cursorFactory, ROWS)) {
+      List<Cursor.Accessor> accessors =
+          cursor.createAccessors(columnsMetaDataList, Unsafe.localCalendar(), 
null);
+
+      assertEquals(columnsMetaDataList.size(), accessors.size());
+      Cursor.Accessor shortAccessor = accessors.get(0);
+      Cursor.Accessor intAccessor = accessors.get(1);
+      Cursor.Accessor longAccessor = accessors.get(2);
+      Cursor.Accessor longAccessor2 = accessors.get(3);
+      Cursor.Accessor bigIntAccessor = accessors.get(4);
+
+      for (Object row : ROWS) {
+        assertTrue(cursor.next());
+        SimplePOJO pjo = (SimplePOJO) row;
+        assertEquals(pjo.shortField, shortAccessor.getObject());
+        assertEquals(pjo.intField, intAccessor.getObject());
+        assertEquals(pjo.longField, longAccessor.getObject());
+        assertEquals(pjo.longField, longAccessor2.getObject());
+        assertEquals(pjo.bigIntField, bigIntAccessor.getObject());
+      }
+
+      assertFalse(cursor.next());
+    }
+  }
 }
 
 // End CursorFactoryDeduceTest.java
diff --git a/gradle.properties b/gradle.properties
index d2359c1df..a252b718a 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -71,6 +71,7 @@ jackson.version=2.15.4
 jcip-annotations.version=1.0-1
 jcommander.version=1.72
 jetty.version=9.4.56.v20240826
+joou-java-6.version=0.9.4
 junit.version=4.13.2
 kerby.version=2.1.0
 log4j2.version=2.17.1
diff --git 
a/shaded/core/src/test/java/org/apache/calcite/avatica/shadetest/ShadingTest.java
 
b/shaded/core/src/test/java/org/apache/calcite/avatica/shadetest/ShadingTest.java
index 7a0e565c6..0be81419d 100644
--- 
a/shaded/core/src/test/java/org/apache/calcite/avatica/shadetest/ShadingTest.java
+++ 
b/shaded/core/src/test/java/org/apache/calcite/avatica/shadetest/ShadingTest.java
@@ -35,7 +35,7 @@ public class ShadingTest {
   // Note that many of these files could be excluded.
   // This is for regression testing, and not the minimum file set.
   String[] allowedPathPatterns = { "^META-INF", "^org/apache/calcite/",  
".*\\.proto",
-      "^org/slf4j/", "^org/publicsuffix/" };
+      "^org/slf4j/", "^org/publicsuffix/", "^org/joou/" };
 
   @Test
   public void validateShadedJar() throws Exception {
diff --git 
a/standalone-server/src/test/java/org/apache/calcite/avatica/shadetest/ShadingTest.java
 
b/standalone-server/src/test/java/org/apache/calcite/avatica/shadetest/ShadingTest.java
index 0774d45de..5b1a27a61 100644
--- 
a/standalone-server/src/test/java/org/apache/calcite/avatica/shadetest/ShadingTest.java
+++ 
b/standalone-server/src/test/java/org/apache/calcite/avatica/shadetest/ShadingTest.java
@@ -39,7 +39,7 @@ public class ShadingTest {
       "^google/protobuf/", "^about.html$", "^org/eclipse/jetty/", 
"^jetty-dir.css",
       "^com/google/thirdparty/", "^org/checkerframework/", 
"^javax/annotation/",
       "^com/google/errorprone/", "^Log4j-.*\\.xsd$", "^Log4j-.*\\.dtd$", 
"^Log4j-.*\\.properties$",
-      "^org/apache/logging/log4j/", "^org/codehaus/mojo/animal_sniffer/" };
+      "^org/apache/logging/log4j/", "^org/codehaus/mojo/animal_sniffer/", 
"^org/joou/" };
 
   @Test
   public void validateShadedJar() throws Exception {


Reply via email to