Search in sources :

Example 1 with MultisetSqlType

use of org.apache.calcite.sql.type.MultisetSqlType in project calcite by apache.

the class SqlUnnestOperator method inferReturnType.

// ~ Methods ----------------------------------------------------------------
@Override
public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
    final RelDataTypeFactory.Builder builder = opBinding.getTypeFactory().builder();
    for (Integer operand : Util.range(opBinding.getOperandCount())) {
        RelDataType type = opBinding.getOperandType(operand);
        if (type.isStruct()) {
            type = type.getFieldList().get(0).getType();
        }
        assert type instanceof ArraySqlType || type instanceof MultisetSqlType || type instanceof MapSqlType;
        if (type instanceof MapSqlType) {
            builder.add(MAP_KEY_COLUMN_NAME, type.getKeyType());
            builder.add(MAP_VALUE_COLUMN_NAME, type.getValueType());
        } else {
            if (type.getComponentType().isStruct()) {
                builder.addAll(type.getComponentType().getFieldList());
            } else {
                builder.add(SqlUtil.deriveAliasFromOrdinal(operand), type.getComponentType());
            }
        }
    }
    if (withOrdinality) {
        builder.add(ORDINALITY_COLUMN_NAME, SqlTypeName.INTEGER);
    }
    return builder.build();
}
Also used : MapSqlType(org.apache.calcite.sql.type.MapSqlType) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) MultisetSqlType(org.apache.calcite.sql.type.MultisetSqlType) RelDataType(org.apache.calcite.rel.type.RelDataType) ArraySqlType(org.apache.calcite.sql.type.ArraySqlType)

Example 2 with MultisetSqlType

use of org.apache.calcite.sql.type.MultisetSqlType in project calcite by apache.

the class RexBuilder method makeLiteral.

/**
 * Creates a literal of a given type. The value is assumed to be
 * compatible with the type.
 *
 * @param value     Value
 * @param type      Type
 * @param allowCast Whether to allow a cast. If false, value is always a
 *                  {@link RexLiteral} but may not be the exact type
 * @return Simple literal, or cast simple literal
 */
public RexNode makeLiteral(Object value, RelDataType type, boolean allowCast) {
    if (value == null) {
        return makeCast(type, constantNull);
    }
    if (type.isNullable()) {
        final RelDataType typeNotNull = typeFactory.createTypeWithNullability(type, false);
        RexNode literalNotNull = makeLiteral(value, typeNotNull, allowCast);
        return makeAbstractCast(type, literalNotNull);
    }
    value = clean(value, type);
    RexLiteral literal;
    final List<RexNode> operands;
    switch(type.getSqlTypeName()) {
        case CHAR:
            return makeCharLiteral(padRight((NlsString) value, type.getPrecision()));
        case VARCHAR:
            literal = makeCharLiteral((NlsString) value);
            if (allowCast) {
                return makeCast(type, literal);
            } else {
                return literal;
            }
        case BINARY:
            return makeBinaryLiteral(padRight((ByteString) value, type.getPrecision()));
        case VARBINARY:
            literal = makeBinaryLiteral((ByteString) value);
            if (allowCast) {
                return makeCast(type, literal);
            } else {
                return literal;
            }
        case TINYINT:
        case SMALLINT:
        case INTEGER:
        case BIGINT:
        case DECIMAL:
            return makeExactLiteral((BigDecimal) value, type);
        case FLOAT:
        case REAL:
        case DOUBLE:
            return makeApproxLiteral((BigDecimal) value, type);
        case BOOLEAN:
            return (Boolean) value ? booleanTrue : booleanFalse;
        case TIME:
            return makeTimeLiteral((TimeString) value, type.getPrecision());
        case TIME_WITH_LOCAL_TIME_ZONE:
            return makeTimeWithLocalTimeZoneLiteral((TimeString) value, type.getPrecision());
        case DATE:
            return makeDateLiteral((DateString) value);
        case TIMESTAMP:
            return makeTimestampLiteral((TimestampString) value, type.getPrecision());
        case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
            return makeTimestampWithLocalTimeZoneLiteral((TimestampString) value, type.getPrecision());
        case INTERVAL_YEAR:
        case INTERVAL_YEAR_MONTH:
        case INTERVAL_MONTH:
        case INTERVAL_DAY:
        case INTERVAL_DAY_HOUR:
        case INTERVAL_DAY_MINUTE:
        case INTERVAL_DAY_SECOND:
        case INTERVAL_HOUR:
        case INTERVAL_HOUR_MINUTE:
        case INTERVAL_HOUR_SECOND:
        case INTERVAL_MINUTE:
        case INTERVAL_MINUTE_SECOND:
        case INTERVAL_SECOND:
            return makeIntervalLiteral((BigDecimal) value, type.getIntervalQualifier());
        case MAP:
            final MapSqlType mapType = (MapSqlType) type;
            @SuppressWarnings("unchecked") final Map<Object, Object> map = (Map) value;
            operands = new ArrayList<>();
            for (Map.Entry<Object, Object> entry : map.entrySet()) {
                operands.add(makeLiteral(entry.getKey(), mapType.getKeyType(), allowCast));
                operands.add(makeLiteral(entry.getValue(), mapType.getValueType(), allowCast));
            }
            return makeCall(SqlStdOperatorTable.MAP_VALUE_CONSTRUCTOR, operands);
        case ARRAY:
            final ArraySqlType arrayType = (ArraySqlType) type;
            @SuppressWarnings("unchecked") final List<Object> listValue = (List) value;
            operands = new ArrayList<>();
            for (Object entry : listValue) {
                operands.add(makeLiteral(entry, arrayType.getComponentType(), allowCast));
            }
            return makeCall(SqlStdOperatorTable.ARRAY_VALUE_CONSTRUCTOR, operands);
        case MULTISET:
            final MultisetSqlType multisetType = (MultisetSqlType) type;
            operands = new ArrayList<>();
            for (Object entry : (List) value) {
                final RexNode e = entry instanceof RexLiteral ? (RexNode) entry : makeLiteral(entry, multisetType.getComponentType(), allowCast);
                operands.add(e);
            }
            if (allowCast) {
                return makeCall(SqlStdOperatorTable.MULTISET_VALUE, operands);
            } else {
                return new RexLiteral((Comparable) FlatLists.of(operands), type, type.getSqlTypeName());
            }
        case ROW:
            operands = new ArrayList<>();
            // noinspection unchecked
            for (Pair<RelDataTypeField, Object> pair : Pair.zip(type.getFieldList(), (List<Object>) value)) {
                final RexNode e = pair.right instanceof RexLiteral ? (RexNode) pair.right : makeLiteral(pair.right, pair.left.getType(), allowCast);
                operands.add(e);
            }
            return new RexLiteral((Comparable) FlatLists.of(operands), type, type.getSqlTypeName());
        case ANY:
            return makeLiteral(value, guessType(value), allowCast);
        default:
            throw Util.unexpected(type.getSqlTypeName());
    }
}
Also used : ByteString(org.apache.calcite.avatica.util.ByteString) RelDataType(org.apache.calcite.rel.type.RelDataType) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) MapSqlType(org.apache.calcite.sql.type.MapSqlType) MultisetSqlType(org.apache.calcite.sql.type.MultisetSqlType) NlsString(org.apache.calcite.util.NlsString) ArraySqlType(org.apache.calcite.sql.type.ArraySqlType) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) Map(java.util.Map)

Example 3 with MultisetSqlType

use of org.apache.calcite.sql.type.MultisetSqlType in project calcite by apache.

the class SqlMultisetMemberOfOperator method checkOperandTypes.

// ~ Methods ----------------------------------------------------------------
public boolean checkOperandTypes(SqlCallBinding callBinding, boolean throwOnFailure) {
    if (!OperandTypes.MULTISET.checkSingleOperandType(callBinding, callBinding.operand(1), 0, throwOnFailure)) {
        return false;
    }
    MultisetSqlType mt = (MultisetSqlType) callBinding.getValidator().deriveType(callBinding.getScope(), callBinding.operand(1));
    RelDataType t0 = callBinding.getValidator().deriveType(callBinding.getScope(), callBinding.operand(0));
    RelDataType t1 = mt.getComponentType();
    if (t0.getFamily() != t1.getFamily()) {
        if (throwOnFailure) {
            throw callBinding.newValidationError(RESOURCE.typeNotComparableNear(t0.toString(), t1.toString()));
        }
        return false;
    }
    return true;
}
Also used : MultisetSqlType(org.apache.calcite.sql.type.MultisetSqlType) RelDataType(org.apache.calcite.rel.type.RelDataType)

Example 4 with MultisetSqlType

use of org.apache.calcite.sql.type.MultisetSqlType in project calcite by apache.

the class UnnestNamespace method inferReturnType.

/**
 * Returns the type of the argument to UNNEST.
 */
private RelDataType inferReturnType() {
    final SqlNode operand = unnest.operand(0);
    RelDataType type = validator.getValidatedNodeType(operand);
    // TODO: Handle this using usual sub-select validation.
    if (type.isStruct()) {
        type = type.getFieldList().get(0).getType();
    }
    MultisetSqlType t = (MultisetSqlType) type;
    return t.getComponentType();
}
Also used : MultisetSqlType(org.apache.calcite.sql.type.MultisetSqlType) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlNode(org.apache.calcite.sql.SqlNode)

Aggregations

RelDataType (org.apache.calcite.rel.type.RelDataType)4 MultisetSqlType (org.apache.calcite.sql.type.MultisetSqlType)4 ArraySqlType (org.apache.calcite.sql.type.ArraySqlType)2 MapSqlType (org.apache.calcite.sql.type.MapSqlType)2 ImmutableList (com.google.common.collect.ImmutableList)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Map (java.util.Map)1 ByteString (org.apache.calcite.avatica.util.ByteString)1 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)1 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)1 SqlNode (org.apache.calcite.sql.SqlNode)1 NlsString (org.apache.calcite.util.NlsString)1