Search in sources :

Example 1 with Literal

use of com.hazelcast.jet.sql.impl.validate.literal.Literal in project hazelcast by hazelcast.

the class LiteralTypeResolutionTest method checkLiteral.

private void checkLiteral(SqlLiteral literal, Object expectedValue, Object expectedStringValue, SqlTypeName expectedTypeName, boolean expectedNullable) {
    String expectedStringValue0 = expectedStringValue != null ? expectedStringValue.toString() : null;
    Literal literal0 = LiteralUtils.literal(literal);
    assertNotNull(literal0);
    assertEquals(expectedValue, literal0.getValue());
    assertEquals(expectedStringValue0, literal0.getStringValue());
    assertEquals(expectedTypeName, literal0.getTypeName());
    assertEquals(expectedTypeName, literal0.getType(HazelcastTypeFactory.INSTANCE).getSqlTypeName());
    assertEquals(expectedNullable, literal0.getType(HazelcastTypeFactory.INSTANCE).isNullable());
    assertEquals(expectedTypeName, LiteralUtils.literalTypeName(literal));
    RelDataType type = LiteralUtils.literalType(literal, HazelcastTypeFactory.INSTANCE);
    assertNotNull(type);
    assertEquals(expectedTypeName, type.getSqlTypeName());
    assertEquals(expectedNullable, type.isNullable());
}
Also used : SqlLiteral(org.apache.calcite.sql.SqlLiteral) Literal(com.hazelcast.jet.sql.impl.validate.literal.Literal) RelDataType(org.apache.calcite.rel.type.RelDataType)

Example 2 with Literal

use of com.hazelcast.jet.sql.impl.validate.literal.Literal in project hazelcast by hazelcast.

the class HazelcastSqlToRelConverter method convertCast.

/**
 * Convert CAST expression fixing several Apache Calcite problems with literals along the way (see inline JavaDoc).
 */
private RexNode convertCast(SqlCall call, Blackboard blackboard) {
    SqlNode operand = call.operand(0);
    RexNode convertedOperand = blackboard.convertExpression(operand);
    RelDataType from = validator.getValidatedNodeType(operand);
    RelDataType to = validator.getValidatedNodeType(call);
    QueryDataType fromType = HazelcastTypeUtils.toHazelcastType(from);
    QueryDataType toType = HazelcastTypeUtils.toHazelcastType(to);
    Literal literal = LiteralUtils.literal(convertedOperand);
    if (literal != null && ((RexLiteral) convertedOperand).getTypeName() != SqlTypeName.NULL) {
        // types to ensure that we throw consistent error messages for all literal-related conversions errors.
        try {
            // The literal's type might be different from the operand type for example here:
            // CAST(CAST(42 AS SMALLINT) AS TINYINT)
            // The operand of the outer cast is validated as a SMALLINT, however the operand, thanks to the
            // simplification in RexBuilder.makeCast(), is converted to a literal [42:SMALLINT]. And LiteralUtils converts
            // this operand to [42:TINYINT] - we have to use the literal's type instead of the validated operand type.
            QueryDataType actualFromType = HazelcastTypeUtils.toHazelcastTypeFromSqlTypeName(literal.getTypeName());
            toType.getConverter().convertToSelf(actualFromType.getConverter(), literal.getValue());
        } catch (Exception e) {
            throw literalConversionException(validator, call, literal, toType, e);
        }
        // DOUBLE literals are converted to a string with scientific conventions (e.g., 1.1E1 instead of 11.0);
        if (SqlTypeName.CHAR_TYPES.contains(to.getSqlTypeName())) {
            return getRexBuilder().makeLiteral(literal.getStringValue(), to, true);
        }
        // To workaround the problem, we perform the conversion manually.
        if (SqlTypeName.CHAR_TYPES.contains(from.getSqlTypeName()) && to.getSqlTypeName() == SqlTypeName.TIME) {
            LocalTime time = fromType.getConverter().asTime(literal.getStringValue());
            TimeString timeString = new TimeString(time.getHour(), time.getMinute(), time.getSecond());
            return getRexBuilder().makeLiteral(timeString, to, true);
        }
        // be "true". See CastFunctionIntegrationTest.testApproximateTypeSimplification - it will fail without this fix.
        if (fromType.getTypeFamily().isNumeric()) {
            if (toType.getTypeFamily().isNumericApproximate()) {
                Converter converter = Converters.getConverter(literal.getValue().getClass());
                Object convertedValue = toType.getConverter().convertToSelf(converter, literal.getValue());
                return getRexBuilder().makeLiteral(convertedValue, to, false);
            }
        }
    }
    if (literal != null && HazelcastTypeUtils.isJsonType(to)) {
        return getRexBuilder().makeCall(HazelcastJsonParseFunction.INSTANCE, convertedOperand);
    }
    // Delegate to Apache Calcite.
    return getRexBuilder().makeCast(to, convertedOperand);
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) LocalTime(java.time.LocalTime) TimeString(org.apache.calcite.util.TimeString) QueryDataType(com.hazelcast.sql.impl.type.QueryDataType) RexLiteral(org.apache.calcite.rex.RexLiteral) SqlLiteral(org.apache.calcite.sql.SqlLiteral) Literal(com.hazelcast.jet.sql.impl.validate.literal.Literal) SqlToRelConverter(org.apache.calcite.sql2rel.SqlToRelConverter) Converter(com.hazelcast.sql.impl.type.converter.Converter) RelDataType(org.apache.calcite.rel.type.RelDataType) CalciteContextException(org.apache.calcite.runtime.CalciteContextException) InvocationTargetException(java.lang.reflect.InvocationTargetException) QueryException(com.hazelcast.sql.impl.QueryException) SqlValidatorException(org.apache.calcite.sql.validate.SqlValidatorException) SqlNode(org.apache.calcite.sql.SqlNode) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

Literal (com.hazelcast.jet.sql.impl.validate.literal.Literal)2 RelDataType (org.apache.calcite.rel.type.RelDataType)2 SqlLiteral (org.apache.calcite.sql.SqlLiteral)2 QueryException (com.hazelcast.sql.impl.QueryException)1 QueryDataType (com.hazelcast.sql.impl.type.QueryDataType)1 Converter (com.hazelcast.sql.impl.type.converter.Converter)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 LocalTime (java.time.LocalTime)1 RexLiteral (org.apache.calcite.rex.RexLiteral)1 RexNode (org.apache.calcite.rex.RexNode)1 CalciteContextException (org.apache.calcite.runtime.CalciteContextException)1 SqlNode (org.apache.calcite.sql.SqlNode)1 SqlValidatorException (org.apache.calcite.sql.validate.SqlValidatorException)1 SqlToRelConverter (org.apache.calcite.sql2rel.SqlToRelConverter)1 TimeString (org.apache.calcite.util.TimeString)1