Java源码示例:org.apache.flink.table.types.CollectionDataType

示例1
@Override
public DataType visit(CollectionDataType collectionDataType) {
	DataType elementType = collectionDataType.getElementDataType();
	switch (logicalType.getTypeRoot()) {
		case ARRAY:
			ArrayType arrayType = (ArrayType) logicalType;
			DataType newArrayElementType = elementType
				.accept(new DataTypePrecisionFixer(arrayType.getElementType()));
			return DataTypes
				.ARRAY(newArrayElementType)
				.bridgedTo(collectionDataType.getConversionClass());

		case MULTISET:
			MultisetType multisetType = (MultisetType) logicalType;
			DataType newMultisetElementType = elementType
				.accept(new DataTypePrecisionFixer(multisetType.getElementType()));
			return DataTypes
				.MULTISET(newMultisetElementType)
				.bridgedTo(collectionDataType.getConversionClass());

		default:
			throw new UnsupportedOperationException("Unsupported logical type : " + logicalType);
	}
}
 
示例2
private static FunctionArgumentTemplate extractDataTypeArgument(
		DataTypeFactory typeFactory,
		Class<? extends UserDefinedFunction> function,
		Method method,
		int paramPos) {
	final DataType type = DataTypeExtractor.extractFromMethodParameter(
		typeFactory,
		function,
		method,
		paramPos);
	// unwrap data type in case of varargs
	if (method.isVarArgs() && paramPos == method.getParameterCount() - 1) {
		// for ARRAY
		if (type instanceof CollectionDataType) {
			return FunctionArgumentTemplate.of(((CollectionDataType) type).getElementDataType());
		}
		// special case for varargs that have been misinterpreted as BYTES
		else {
			return FunctionArgumentTemplate.of(DataTypes.TINYINT().notNull().bridgedTo(byte.class));
		}
	}
	return FunctionArgumentTemplate.of(type);
}
 
示例3
@Override
public DataType visit(CollectionDataType collectionDataType) {
	DataType newElementType = collectionDataType.getElementDataType().accept(this);
	LogicalType logicalType = collectionDataType.getLogicalType();
	LogicalType newLogicalType;
	if (logicalType instanceof ArrayType) {
		newLogicalType = new ArrayType(
			logicalType.isNullable(),
			newElementType.getLogicalType());
	} else if (logicalType instanceof MultisetType){
		newLogicalType = new MultisetType(
			logicalType.isNullable(),
			newElementType.getLogicalType());
	} else {
		throw new UnsupportedOperationException("Unsupported logical type : " + logicalType);
	}
	return transformation.transform(new CollectionDataType(newLogicalType, newElementType));
}
 
示例4
private Optional<ResolvedExpression> convertArrayToExpectedType(
		ResolvedExpression sourceExpression,
		CollectionDataType targetDataType,
		ExpressionResolver.PostResolverFactory postResolverFactory) {
	DataType elementTargetDataType = targetDataType.getElementDataType();
	List<ResolvedExpression> resolvedChildren = sourceExpression.getResolvedChildren();
	ResolvedExpression[] castedChildren = new ResolvedExpression[resolvedChildren.size()];
	for (int i = 0; i < resolvedChildren.size(); i++) {
		Optional<ResolvedExpression> castedChild = convertToExpectedType(
			resolvedChildren.get(i),
			elementTargetDataType,
			postResolverFactory);
		if (castedChild.isPresent()) {
			castedChildren[i] = castedChild.get();
		} else {
			return Optional.empty();
		}
	}
	return Optional.of(postResolverFactory.array(targetDataType, castedChildren));
}
 
示例5
static <T> T visit(DataType dataType, FlinkTypeVisitor<T> visitor) {
  if (dataType instanceof FieldsDataType) {
    FieldsDataType fieldsType = (FieldsDataType) dataType;
    Map<String, DataType> fields = fieldsType.getFieldDataTypes();
    List<T> fieldResults = Lists.newArrayList();

    Preconditions.checkArgument(dataType.getLogicalType() instanceof RowType, "The logical type must be RowType");
    List<RowType.RowField> rowFields = ((RowType) dataType.getLogicalType()).getFields();
    // Make sure that we're traveling in the same order as the RowFields because the implementation of
    // FlinkTypeVisitor#fields may depends on the visit order, please see FlinkTypeToType#fields.
    for (RowType.RowField rowField : rowFields) {
      String name = rowField.getName();
      fieldResults.add(visit(fields.get(name), visitor));
    }

    return visitor.fields(fieldsType, fieldResults);
  } else if (dataType instanceof CollectionDataType) {
    CollectionDataType collectionType = (CollectionDataType) dataType;
    return visitor.collection(collectionType,
        visit(collectionType.getElementDataType(), visitor));
  } else if (dataType instanceof KeyValueDataType) {
    KeyValueDataType mapType = (KeyValueDataType) dataType;
    return visitor.map(mapType,
        visit(mapType.getKeyDataType(), visitor),
        visit(mapType.getValueDataType(), visitor));
  } else if (dataType instanceof AtomicDataType) {
    AtomicDataType atomic = (AtomicDataType) dataType;
    return visitor.atomic(atomic);
  } else {
    throw new UnsupportedOperationException("Unsupported data type: " + dataType);
  }
}
 
示例6
private static Schema sqlType2AvroSchema(DataType flinkType, boolean nullable, String recordName, String namespace) throws IncompatibleSchemaException {
    SchemaBuilder.TypeBuilder<Schema> builder = SchemaBuilder.builder();
    LogicalTypeRoot type = flinkType.getLogicalType().getTypeRoot();
    Schema schema = null;

    if (flinkType instanceof AtomicDataType) {
        switch (type) {
            case BOOLEAN:
                schema = builder.booleanType();
                break;
            case TINYINT:
            case SMALLINT:
            case INTEGER:
                schema = builder.intType();
                break;
            case BIGINT:
                schema = builder.longType();
                break;
            case DATE:
                schema = LogicalTypes.date().addToSchema(builder.intType());
                break;
            case TIMESTAMP_WITHOUT_TIME_ZONE:
                schema = LogicalTypes.timestampMicros().addToSchema(builder.longType());
                break;
            case FLOAT:
                schema = builder.floatType();
                break;
            case DOUBLE:
                schema = builder.doubleType();
                break;
            case VARCHAR:
                schema = builder.stringType();
                break;
            case BINARY:
            case VARBINARY:
                schema = builder.bytesType();
                break;
            case DECIMAL:
                DecimalType dt = (DecimalType) flinkType.getLogicalType();
                LogicalTypes.Decimal avroType = LogicalTypes.decimal(dt.getPrecision(), dt.getScale());
                int fixedSize = minBytesForPrecision[dt.getPrecision()];
                // Need to avoid naming conflict for the fixed fields
                String name;
                if (namespace.equals("")) {
                    name = recordName + ".fixed";
                } else {
                    name = namespace + recordName + ".fixed";
                }
                schema = avroType.addToSchema(SchemaBuilder.fixed(name).size(fixedSize));
                break;
            default:
                throw new IncompatibleSchemaException(String.format("Unsupported type %s", flinkType.toString()), null);
        }
    } else if (flinkType instanceof CollectionDataType) {
        if (type == LogicalTypeRoot.ARRAY) {
            CollectionDataType cdt = (CollectionDataType) flinkType;
            DataType elementType = cdt.getElementDataType();
            schema = builder.array().items(sqlType2AvroSchema(elementType, elementType.getLogicalType().isNullable(), recordName, namespace));
        } else {
            throw new IncompatibleSchemaException("Pulsar only support collection as array", null);
        }
    } else if (flinkType instanceof KeyValueDataType) {
        KeyValueDataType kvType = (KeyValueDataType) flinkType;
        DataType keyType = kvType.getKeyDataType();
        DataType valueType = kvType.getValueDataType();
        if (!(keyType instanceof AtomicDataType) || keyType.getLogicalType().getTypeRoot() != LogicalTypeRoot.VARCHAR) {
            throw new IncompatibleSchemaException("Pulsar only support string key map", null);
        }
        schema = builder.map().values(sqlType2AvroSchema(valueType, valueType.getLogicalType().isNullable(), recordName, namespace));
    } else if (flinkType instanceof FieldsDataType) {
        FieldsDataType fieldsDataType = (FieldsDataType) flinkType;
        String childNamespace = namespace.equals("") ? recordName : namespace + "." + recordName;
        SchemaBuilder.FieldAssembler<Schema> fieldsAssembler = builder.record(recordName).namespace(namespace).fields();
        RowType rowType = (RowType) fieldsDataType.getLogicalType();

        for (String fieldName : rowType.getFieldNames()) {
            DataType ftype = fieldsDataType.getFieldDataTypes().get(fieldName);
            Schema fieldAvroSchema = sqlType2AvroSchema(ftype, ftype.getLogicalType().isNullable(), fieldName, childNamespace);
            fieldsAssembler.name(fieldName).type(fieldAvroSchema).noDefault();
        }
        schema = fieldsAssembler.endRecord();
    } else {
        throw new IncompatibleSchemaException(String.format("Unexpected type %s", flinkType.toString()), null);
    }

    if (nullable) {
        return Schema.createUnion(schema, NULL_SCHEMA);
    } else {
        return schema;
    }
}
 
示例7
public static TypeInformation<?> fromDataTypeToTypeInfo(DataType dataType) {
	Class<?> clazz = dataType.getConversionClass();
	if (clazz.isPrimitive()) {
		final TypeInformation<?> foundTypeInfo = primitiveDataTypeTypeInfoMap.get(clazz.getName());
		if (foundTypeInfo != null) {
			return foundTypeInfo;
		}
	}
	LogicalType logicalType = fromDataTypeToLogicalType(dataType);
	switch (logicalType.getTypeRoot()) {
		case DECIMAL:
			DecimalType decimalType = (DecimalType) logicalType;
			return clazz == Decimal.class ?
					new DecimalTypeInfo(decimalType.getPrecision(), decimalType.getScale()) :
					new BigDecimalTypeInfo(decimalType.getPrecision(), decimalType.getScale());
		case CHAR:
		case VARCHAR: // ignore precision
			return clazz == BinaryString.class ?
					BinaryStringTypeInfo.INSTANCE :
					BasicTypeInfo.STRING_TYPE_INFO;
		case BINARY:
		case VARBINARY: // ignore precision
			return PrimitiveArrayTypeInfo.BYTE_PRIMITIVE_ARRAY_TYPE_INFO;
		case INTERVAL_YEAR_MONTH:
			return TimeIntervalTypeInfo.INTERVAL_MONTHS;
		case INTERVAL_DAY_TIME:
			return TimeIntervalTypeInfo.INTERVAL_MILLIS;
		case ARRAY:
			if (dataType instanceof CollectionDataType &&
					!isPrimitive(((CollectionDataType) dataType).getElementDataType().getLogicalType())) {
				return ObjectArrayTypeInfo.getInfoFor(
						fromDataTypeToTypeInfo(((CollectionDataType) dataType).getElementDataType()));
			} else {
				return TypeConversions.fromDataTypeToLegacyInfo(dataType);
			}
		case MAP:
			KeyValueDataType mapType = (KeyValueDataType) dataType;
			return new MapTypeInfo(
					fromDataTypeToTypeInfo(mapType.getKeyDataType()),
					fromDataTypeToTypeInfo(mapType.getValueDataType()));
		case MULTISET:
			return MultisetTypeInfo.getInfoFor(
					fromDataTypeToTypeInfo(((CollectionDataType) dataType).getElementDataType()));
		case ROW:
			if (BaseRow.class.isAssignableFrom(dataType.getConversionClass())) {
				return BaseRowTypeInfo.of((RowType) fromDataTypeToLogicalType(dataType));
			} else if (Row.class == dataType.getConversionClass()) {
				FieldsDataType rowType = (FieldsDataType) dataType;
				RowType logicalRowType = (RowType) logicalType;
				return new RowTypeInfo(
						logicalRowType.getFieldNames().stream()
								.map(name -> rowType.getFieldDataTypes().get(name))
								.map(TypeInfoDataTypeConverter::fromDataTypeToTypeInfo)
								.toArray(TypeInformation[]::new),
						logicalRowType.getFieldNames().toArray(new String[0]));
			} else {
				return TypeConversions.fromDataTypeToLegacyInfo(dataType);
			}
		default:
			return TypeConversions.fromDataTypeToLegacyInfo(dataType);
	}
}
 
示例8
@Override
public R visit(CollectionDataType collectionDataType) {
	return defaultMethod(collectionDataType);
}
 
示例9
public static TypeInformation<?> toLegacyTypeInfo(DataType dataType) {
	// time indicators first as their hashCode/equals is shared with those of regular timestamps
	if (canConvertToTimeAttributeTypeInfo(dataType)) {
		return convertToTimeAttributeTypeInfo((TimestampType) dataType.getLogicalType());
	}

	// check in the map but relax the nullability constraint as every not null data type can be
	// stored in the corresponding nullable type information
	final TypeInformation<?> foundTypeInfo = dataTypeTypeInfoMap.get(dataType.nullable());
	if (foundTypeInfo != null) {
		return foundTypeInfo;
	}

	// we are relaxing the constraint for DECIMAL, CHAR, VARCHAR, TIMESTAMP_WITHOUT_TIME_ZONE to
	// support value literals in legacy planner
	LogicalType logicalType = dataType.getLogicalType();
	if (hasRoot(logicalType, LogicalTypeRoot.DECIMAL)) {
		return Types.BIG_DEC;
	}

	else if (hasRoot(logicalType, LogicalTypeRoot.CHAR)) {
		return Types.STRING;
	}

	else if (hasRoot(logicalType, LogicalTypeRoot.VARCHAR)) {
		return Types.STRING;
	}

	else if (canConvertToTimestampTypeInfoLenient(dataType)) {
		return Types.SQL_TIMESTAMP;
	}

	else if (canConvertToLegacyTypeInfo(dataType)) {
		return convertToLegacyTypeInfo(dataType);
	}

	else if (canConvertToRowTypeInfo(dataType)) {
		return convertToRowTypeInfo((FieldsDataType) dataType);
	}

	// this could also match for basic array type info but this is covered by legacy type info
	else if (canConvertToObjectArrayTypeInfo(dataType)) {
		return convertToObjectArrayTypeInfo((CollectionDataType) dataType);
	}

	else if (canConvertToMultisetTypeInfo(dataType)) {
		return convertToMultisetTypeInfo((CollectionDataType) dataType);
	}

	else if (canConvertToMapTypeInfo(dataType)) {
		return convertToMapTypeInfo((KeyValueDataType) dataType);
	}

	// makes the any type accessible in the legacy planner
	else if (canConvertToAnyTypeInfo(dataType)) {
		return convertToAnyTypeInfo(dataType);
	}

	throw new TableException(
		String.format(
			"Unsupported conversion from data type '%s' (conversion class: %s) to type information. Only data types " +
				"that originated from type information fully support a reverse conversion.",
			dataType,
			dataType.getConversionClass().getName()));
}
 
示例10
private static TypeInformation<?> convertToObjectArrayTypeInfo(CollectionDataType collectionDataType) {
	// Types.OBJECT_ARRAY would return a basic type info for strings
	return ObjectArrayTypeInfo.getInfoFor(
		toLegacyTypeInfo(collectionDataType.getElementDataType()));
}
 
示例11
private static TypeInformation<?> convertToMultisetTypeInfo(CollectionDataType collectionDataType) {
	return new MultisetTypeInfo<>(
		toLegacyTypeInfo(collectionDataType.getElementDataType()));
}
 
示例12
@Override
public DataType visit(ArrayType arrayType) {
	return new CollectionDataType(
		arrayType,
		arrayType.getElementType().accept(this));
}
 
示例13
@Override
public DataType visit(MultisetType multisetType) {
	return new CollectionDataType(
		multisetType,
		multisetType.getElementType().accept(this));
}
 
示例14
public T collection(CollectionDataType type, T elementResult) {
  return null;
}
 
示例15
public static TypeInformation<?> fromDataTypeToTypeInfo(DataType dataType) {
	Class<?> clazz = dataType.getConversionClass();
	if (clazz.isPrimitive()) {
		final TypeInformation<?> foundTypeInfo = primitiveDataTypeTypeInfoMap.get(clazz.getName());
		if (foundTypeInfo != null) {
			return foundTypeInfo;
		}
	}
	LogicalType logicalType = fromDataTypeToLogicalType(dataType);
	switch (logicalType.getTypeRoot()) {
		case TIMESTAMP_WITHOUT_TIME_ZONE:
			TimestampType timestampType = (TimestampType) logicalType;
			int precision = timestampType.getPrecision();
			if (timestampType.getKind() == TimestampKind.REGULAR) {
				return clazz == TimestampData.class ?
					new TimestampDataTypeInfo(precision) :
					(clazz == LocalDateTime.class ?
						((3 == precision) ?
							Types.LOCAL_DATE_TIME : new LegacyLocalDateTimeTypeInfo(precision)) :
						((3 == precision) ?
							Types.SQL_TIMESTAMP : new LegacyTimestampTypeInfo(precision)));
			} else {
				return TypeConversions.fromDataTypeToLegacyInfo(dataType);
			}
		case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
			LocalZonedTimestampType lzTs = (LocalZonedTimestampType) logicalType;
			int precisionLzTs = lzTs.getPrecision();
			return clazz == TimestampData.class ?
				new TimestampDataTypeInfo(precisionLzTs) :
				(clazz == Instant.class ?
					((3 == precisionLzTs) ? Types.INSTANT : new LegacyInstantTypeInfo(precisionLzTs)) :
					TypeConversions.fromDataTypeToLegacyInfo(dataType));

		case DECIMAL:
			DecimalType decimalType = (DecimalType) logicalType;
			return clazz == DecimalData.class ?
					new DecimalDataTypeInfo(decimalType.getPrecision(), decimalType.getScale()) :
					new BigDecimalTypeInfo(decimalType.getPrecision(), decimalType.getScale());
		case CHAR:
		case VARCHAR: // ignore precision
			return clazz == StringData.class ?
					StringDataTypeInfo.INSTANCE :
					BasicTypeInfo.STRING_TYPE_INFO;
		case BINARY:
		case VARBINARY: // ignore precision
			return PrimitiveArrayTypeInfo.BYTE_PRIMITIVE_ARRAY_TYPE_INFO;
		case INTERVAL_YEAR_MONTH:
			return TimeIntervalTypeInfo.INTERVAL_MONTHS;
		case INTERVAL_DAY_TIME:
			return TimeIntervalTypeInfo.INTERVAL_MILLIS;
		case ARRAY:
			if (dataType instanceof CollectionDataType &&
					!isPrimitive(((CollectionDataType) dataType).getElementDataType().getLogicalType())) {
				return ObjectArrayTypeInfo.getInfoFor(
						fromDataTypeToTypeInfo(((CollectionDataType) dataType).getElementDataType()));
			} else {
				return TypeConversions.fromDataTypeToLegacyInfo(dataType);
			}
		case MAP:
			KeyValueDataType mapType = (KeyValueDataType) dataType;
			return new MapTypeInfo(
					fromDataTypeToTypeInfo(mapType.getKeyDataType()),
					fromDataTypeToTypeInfo(mapType.getValueDataType()));
		case MULTISET:
			return MultisetTypeInfo.getInfoFor(
					fromDataTypeToTypeInfo(((CollectionDataType) dataType).getElementDataType()));
		case ROW:
			if (RowData.class.isAssignableFrom(dataType.getConversionClass())) {
				return RowDataTypeInfo.of((RowType) fromDataTypeToLogicalType(dataType));
			} else if (Row.class == dataType.getConversionClass()) {
				RowType logicalRowType = (RowType) logicalType;
				return new RowTypeInfo(
					dataType.getChildren()
						.stream()
						.map(TypeInfoDataTypeConverter::fromDataTypeToTypeInfo)
						.toArray(TypeInformation[]::new),
					logicalRowType.getFieldNames().toArray(new String[0]));
			} else {
				return TypeConversions.fromDataTypeToLegacyInfo(dataType);
			}
		case RAW:
			if (logicalType instanceof RawType) {
				final RawType<?> rawType = (RawType<?>) logicalType;
				return createWrapperTypeInfo(rawType);
			}
			return TypeConversions.fromDataTypeToLegacyInfo(dataType);
		default:
			return TypeConversions.fromDataTypeToLegacyInfo(dataType);
	}
}
 
示例16
@Override
public R visit(CollectionDataType collectionDataType) {
	return defaultMethod(collectionDataType);
}
 
示例17
public static TypeInformation<?> toLegacyTypeInfo(DataType dataType) {
	// time indicators first as their hashCode/equals is shared with those of regular timestamps
	if (canConvertToTimeAttributeTypeInfo(dataType)) {
		return convertToTimeAttributeTypeInfo((TimestampType) dataType.getLogicalType());
	}

	// check in the map but relax the nullability constraint as every not null data type can be
	// stored in the corresponding nullable type information
	final TypeInformation<?> foundTypeInfo = dataTypeTypeInfoMap.get(dataType.nullable());
	if (foundTypeInfo != null) {
		return foundTypeInfo;
	}

	// we are relaxing the constraint for DECIMAL, CHAR, VARCHAR, TIMESTAMP_WITHOUT_TIME_ZONE to
	// support value literals in legacy planner
	LogicalType logicalType = dataType.getLogicalType();
	if (hasRoot(logicalType, LogicalTypeRoot.DECIMAL)) {
		return Types.BIG_DEC;
	}

	else if (hasRoot(logicalType, LogicalTypeRoot.CHAR)) {
		return Types.STRING;
	}

	else if (hasRoot(logicalType, LogicalTypeRoot.VARCHAR)) {
		return Types.STRING;
	}

	// relax the precision constraint as Timestamp can store the highest precision
	else if (hasRoot(logicalType, LogicalTypeRoot.TIMESTAMP_WITHOUT_TIME_ZONE) &&
		dataType.getConversionClass() == Timestamp.class) {
		return Types.SQL_TIMESTAMP;
	}

	// relax the precision constraint as LocalDateTime can store the highest precision
	else if (hasRoot(logicalType, LogicalTypeRoot.TIMESTAMP_WITHOUT_TIME_ZONE) &&
		dataType.getConversionClass() == LocalDateTime.class) {
		return Types.LOCAL_DATE_TIME;
	}

	// relax the precision constraint as LocalTime can store the highest precision
	else if (hasRoot(logicalType, LogicalTypeRoot.TIME_WITHOUT_TIME_ZONE) &&
		dataType.getConversionClass() == LocalTime.class) {
		return Types.LOCAL_TIME;
	}

	else if (canConvertToLegacyTypeInfo(dataType)) {
		return convertToLegacyTypeInfo(dataType);
	}

	else if (canConvertToRowTypeInfo(dataType)) {
		return convertToRowTypeInfo((FieldsDataType) dataType);
	}

	// this could also match for basic array type info but this is covered by legacy type info
	else if (canConvertToObjectArrayTypeInfo(dataType)) {
		return convertToObjectArrayTypeInfo((CollectionDataType) dataType);
	}

	else if (canConvertToMultisetTypeInfo(dataType)) {
		return convertToMultisetTypeInfo((CollectionDataType) dataType);
	}

	else if (canConvertToMapTypeInfo(dataType)) {
		return convertToMapTypeInfo((KeyValueDataType) dataType);
	}

	// makes the raw type accessible in the legacy planner
	else if (canConvertToRawTypeInfo(dataType)) {
		return convertToRawTypeInfo(dataType);
	}

	throw new TableException(
		String.format(
			"Unsupported conversion from data type '%s' (conversion class: %s) to type information. Only data types " +
				"that originated from type information fully support a reverse conversion.",
			dataType,
			dataType.getConversionClass().getName()));
}
 
示例18
private static TypeInformation<?> convertToObjectArrayTypeInfo(CollectionDataType collectionDataType) {
	// Types.OBJECT_ARRAY would return a basic type info for strings
	return ObjectArrayTypeInfo.getInfoFor(
		toLegacyTypeInfo(collectionDataType.getElementDataType()));
}
 
示例19
private static TypeInformation<?> convertToMultisetTypeInfo(CollectionDataType collectionDataType) {
	return new MultisetTypeInfo<>(
		toLegacyTypeInfo(collectionDataType.getElementDataType()));
}
 
示例20
@Override
public DataType visit(ArrayType arrayType) {
	return new CollectionDataType(
		arrayType,
		arrayType.getElementType().accept(this));
}
 
示例21
@Override
public DataType visit(MultisetType multisetType) {
	return new CollectionDataType(
		multisetType,
		multisetType.getElementType().accept(this));
}
 
示例22
private Optional<ResolvedExpression> convertToExpectedType(
		ResolvedExpression sourceExpression,
		DataType targetDataType,
		ExpressionResolver.PostResolverFactory postResolverFactory) {

	LogicalType sourceLogicalType = sourceExpression.getOutputDataType().getLogicalType();
	LogicalType targetLogicalType = targetDataType.getLogicalType();

	// if the expression is a literal try converting the literal in place instead of casting
	if (sourceExpression instanceof ValueLiteralExpression) {
		// Assign a type to a null literal
		if (hasRoot(sourceLogicalType, LogicalTypeRoot.NULL)) {
			return Optional.of(valueLiteral(null, targetDataType));
		}

		// Check if the source value class is a valid input conversion class of the target type
		// It may happen that a user wanted to use a secondary input conversion class as a value for
		// a different type than what we derived.
		//
		// Example: we interpreted 1L as BIGINT, but user wanted to interpret it as a TIMESTAMP
		// In this case long is a valid conversion class for TIMESTAMP, but a
		// cast from BIGINT to TIMESTAMP is an invalid operation.
		Optional<Object> value = ((ValueLiteralExpression) sourceExpression).getValueAs(Object.class);
		if (value.isPresent() && targetLogicalType.supportsInputConversion(value.get().getClass())) {
			ValueLiteralExpression convertedLiteral = valueLiteral(
				value.get(),
				targetDataType.notNull().bridgedTo(value.get().getClass()));
			if (targetLogicalType.isNullable()) {
				return Optional.of(postResolverFactory.cast(convertedLiteral, targetDataType));
			} else {
				return Optional.of(convertedLiteral);
			}
		}
	}

	if (sourceExpression instanceof CallExpression) {
		FunctionDefinition functionDefinition = ((CallExpression) sourceExpression).getFunctionDefinition();
		if (functionDefinition == BuiltInFunctionDefinitions.ROW &&
				hasRoot(targetLogicalType, LogicalTypeRoot.ROW)) {
			return convertRowToExpectedType(sourceExpression, (FieldsDataType) targetDataType, postResolverFactory);
		} else if (functionDefinition == BuiltInFunctionDefinitions.ARRAY &&
					hasRoot(targetLogicalType, LogicalTypeRoot.ARRAY)) {
			return convertArrayToExpectedType(
				sourceExpression,
				(CollectionDataType) targetDataType,
				postResolverFactory);
		} else if (functionDefinition == BuiltInFunctionDefinitions.MAP &&
					hasRoot(targetLogicalType, LogicalTypeRoot.MAP)) {
			return convertMapToExpectedType(
				sourceExpression,
				(KeyValueDataType) targetDataType,
				postResolverFactory);
		}
	}

	// We might not be able to cast to the expected type if the expected type was provided by the user
	// we ignore nullability constraints here, as we let users override what we expect there, e.g. they
	// might know that a certain function will not produce nullable values for a given input
	if (supportsExplicitCast(
			sourceLogicalType.copy(true),
			targetLogicalType.copy(true))) {
		return Optional.of(postResolverFactory.cast(sourceExpression, targetDataType));
	} else {
		return Optional.empty();
	}
}
 
示例23
/**
 * Data type of an array of elements with same subtype.
 *
 * <p>Compared to the SQL standard, the maximum cardinality of an array cannot be specified but
 * is fixed at {@link Integer#MAX_VALUE}. Also, any valid type is supported as a subtype.
 *
 * @see ArrayType
 */
public static DataType ARRAY(DataType elementDataType) {
	Preconditions.checkNotNull(elementDataType, "Element data type must not be null.");
	return new CollectionDataType(new ArrayType(elementDataType.getLogicalType()), elementDataType);
}
 
示例24
/**
 * Data type of a multiset (=bag). Unlike a set, it allows for multiple instances for each of its
 * elements with a common subtype. Each unique value (including {@code NULL}) is mapped to some
 * multiplicity.
 *
 * <p>There is no restriction of element types; it is the responsibility of the user to ensure
 * uniqueness.
 *
 * @see MultisetType
 */
public static DataType MULTISET(DataType elementDataType) {
	Preconditions.checkNotNull(elementDataType, "Element data type must not be null.");
	return new CollectionDataType(new MultisetType(elementDataType.getLogicalType()), elementDataType);
}
 
示例25
/**
 * Data type of an array of elements with same subtype.
 *
 * <p>Compared to the SQL standard, the maximum cardinality of an array cannot be specified but
 * is fixed at {@link Integer#MAX_VALUE}. Also, any valid type is supported as a subtype.
 *
 * @see ArrayType
 */
public static DataType ARRAY(DataType elementDataType) {
	Preconditions.checkNotNull(elementDataType, "Element data type must not be null.");
	return new CollectionDataType(new ArrayType(elementDataType.getLogicalType()), elementDataType);
}
 
示例26
/**
 * Data type of a multiset (=bag). Unlike a set, it allows for multiple instances for each of its
 * elements with a common subtype. Each unique value (including {@code NULL}) is mapped to some
 * multiplicity.
 *
 * <p>There is no restriction of element types; it is the responsibility of the user to ensure
 * uniqueness.
 *
 * @see MultisetType
 */
public static DataType MULTISET(DataType elementDataType) {
	Preconditions.checkNotNull(elementDataType, "Element data type must not be null.");
	return new CollectionDataType(new MultisetType(elementDataType.getLogicalType()), elementDataType);
}