Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
1.35.0
Description
First, we need to reach a consensus to allow types of the same family to coexist in multiset such as array and map.
It means the form like `array(1, cast(2 as tinyint))` is correct(the LeastRestrictiveType is Integer). However, this function validate success in calcite but it failed in runtime, exception stack is:
java.lang.ClassCastException: class java.lang.Byte cannot be cast to class java.lang.Integer at org.apache.calcite.avatica.util.AbstractCursor$IntAccessor.getInt(AbstractCursor.java:522) at org.apache.calcite.avatica.util.AbstractCursor$ArrayAccessor.convertValue(AbstractCursor.java:1396) at org.apache.calcite.avatica.util.AbstractCursor$ArrayAccessor.getObject(AbstractCursor.java:1377) at org.apache.calcite.avatica.util.AbstractCursor$ArrayAccessor.getArray(AbstractCursor.java:1432) at org.apache.calcite.avatica.util.AbstractCursor$ArrayAccessor.getString(AbstractCursor.java:1444) at org.apache.calcite.avatica.AvaticaResultSet.getString(AvaticaResultSet.java:241) at org.apache.calcite.util.JdbcTypeImpl$10.get(JdbcTypeImpl.java:112) at org.apache.calcite.util.JdbcTypeImpl$10.get(JdbcTypeImpl.java:109) at org.apache.calcite.sql.test.ResultCheckers.compareResultSetWithMatcher(ResultCheckers.java:248) at org.apache.calcite.sql.test.ResultCheckers$MatcherResultChecker.checkResult(ResultCheckers
And `map[1, 1, 2, cast(1 as tinyint)]` is correct but calcite throw exception:
java.lang.AssertionError: Expected query to throw exception, but it did not; query [values (map[1, 1, 2, cast(1 as tinyint)])]; expected [Parameters must be of the same type] at org.apache.calcite.sql.test.SqlTests.checkEx(SqlTests.java:240) at org.apache.calcite.sql.test.AbstractSqlTester.assertExceptionIsThrown(AbstractSqlTester.java:111) at org.apache.calcite.test.SqlOperatorFixtureImpl.checkQueryFails(SqlOperatorFixtureImpl.java:174)
std ArrayConstructor.
public class SqlArrayValueConstructor extends SqlMultisetValueConstructor { public SqlArrayValueConstructor() { super("ARRAY", SqlKind.ARRAY_VALUE_CONSTRUCTOR); } @Override public RelDataType inferReturnType(SqlOperatorBinding opBinding) { RelDataType type = getComponentType( opBinding.getTypeFactory(), opBinding.collectOperandTypes()); --> we need explicit cast here requireNonNull(type, "inferred array element type"); return SqlTypeUtil.createArrayType( opBinding.getTypeFactory(), type, false); } }
std map constructor:
public class SqlMapValueConstructor extends SqlMultisetValueConstructor { public SqlMapValueConstructor() { super("MAP", SqlKind.MAP_VALUE_CONSTRUCTOR); } @Override public RelDataType inferReturnType(SqlOperatorBinding opBinding) { Pair<@Nullable RelDataType, @Nullable RelDataType> type = getComponentTypes( opBinding.getTypeFactory(), opBinding.collectOperandTypes()); --> we need explicit cast here return SqlTypeUtil.createMapType( opBinding.getTypeFactory(), requireNonNull(type.left, "inferred key type"), requireNonNull(type.right, "inferred value type"), false); } }
Attachments
Issue Links
- contains
-
CALCITE-4850 Wrong result retrieving from ARRAY with mixed INTEGER and DECIMAL elements
-
- Closed
-
- is blocked by
-
CALCITE-5960 CAST failed if SqlTypeFamily of targetType is NULL
-
- Closed
-
- relates to
-
CALCITE-5976 Function ARRAY_PREPEND/ARRAY_APPEND/ARRAY_INSERT gives exception when inserted element type not equals array component type
-
- Closed
-
- links to