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 {