Java Code Examples for org.apache.flink.table.types.logical.LogicalType#supportsInputConversion()

The following examples show how to use org.apache.flink.table.types.logical.LogicalType#supportsInputConversion() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: DataType.java    From flink with Apache License 2.0 6 votes vote down vote up
/**
 * This method should catch the most common errors. However, another validation is required in
 * deeper layers as we don't know whether the data type is used for input or output declaration.
 */
private static <C> Class<C> performEarlyClassValidation(
		LogicalType logicalType,
		Class<C> candidate) {

	if (candidate != null &&
			!logicalType.supportsInputConversion(candidate) &&
			!logicalType.supportsOutputConversion(candidate)) {
		throw new ValidationException(
			String.format(
				"Logical type '%s' does not support a conversion from or to class '%s'.",
				logicalType.asSummaryString(),
				candidate.getName()));
	}
	return candidate;
}
 
Example 2
Source File: DataType.java    From flink with Apache License 2.0 6 votes vote down vote up
/**
 * This method should catch the most common errors. However, another validation is required in
 * deeper layers as we don't know whether the data type is used for input or output declaration.
 */
private static <C> Class<C> performEarlyClassValidation(
		LogicalType logicalType,
		Class<C> candidate) {

	if (candidate != null &&
			!logicalType.supportsInputConversion(candidate) &&
			!logicalType.supportsOutputConversion(candidate)) {
		throw new ValidationException(
			String.format(
				"Logical type '%s' does not support a conversion from or to class '%s'.",
				logicalType.asSummaryString(),
				candidate.getName()));
	}
	return candidate;
}
 
Example 3
Source File: ValueLiteralExpression.java    From flink with Apache License 2.0 5 votes vote down vote up
private static void validateValueDataType(Object value, DataType dataType) {
	final LogicalType logicalType = dataType.getLogicalType();
	if (value == null) {
		if (!logicalType.isNullable()) {
			throw new ValidationException(
				String.format(
					"Data type '%s' does not support null values.",
					dataType));
		}
		return;
	}
	final Class<?> candidate = value.getClass();
	// ensure value and data type match
	if (!dataType.getConversionClass().isAssignableFrom(candidate)) {
		throw new ValidationException(
			String.format(
				"Data type '%s' with conversion class '%s' does not support a value literal of class '%s'.",
				dataType,
				dataType.getConversionClass().getName(),
				value.getClass().getName()));
	}
	// check for proper input as this cannot be checked in data type
	if (!logicalType.supportsInputConversion(candidate)) {
		throw new ValidationException(
			String.format(
				"Data type '%s' does not support a conversion from class '%s'.",
				dataType,
				candidate.getName()));
	}
}
 
Example 4
Source File: ValueLiteralExpression.java    From flink with Apache License 2.0 5 votes vote down vote up
private static void validateValueDataType(Object value, DataType dataType) {
	final LogicalType logicalType = dataType.getLogicalType();
	if (value == null) {
		if (!logicalType.isNullable()) {
			throw new ValidationException(
				String.format(
					"Data type '%s' does not support null values.",
					dataType));
		}
		return;
	}

	if (logicalType.isNullable()) {
		throw new ValidationException("Literals that have a non-null value must not have a nullable data type.");
	}

	final Class<?> candidate = value.getClass();
	// ensure value and data type match
	if (!dataType.getConversionClass().isAssignableFrom(candidate)) {
		throw new ValidationException(
			String.format(
				"Data type '%s' with conversion class '%s' does not support a value literal of class '%s'.",
				dataType,
				dataType.getConversionClass().getName(),
				value.getClass().getName()));
	}
	// check for proper input as this cannot be checked in data type
	if (!logicalType.supportsInputConversion(candidate)) {
		throw new ValidationException(
			String.format(
				"Data type '%s' does not support a conversion from class '%s'.",
				dataType,
				candidate.getName()));
	}
}
 
Example 5
Source File: DataTypeExtractor.java    From flink with Apache License 2.0 5 votes vote down vote up
/**
 * Use closest class for data type if possible. Even though a hint might have provided some data
 * type, in many cases, the conversion class can be enriched with the extraction type itself.
 */
private DataType closestBridging(DataType dataType, @Nullable Class<?> clazz) {
	// no context class or conversion class is already more specific than context class
	if (clazz == null || clazz.isAssignableFrom(dataType.getConversionClass())) {
		return dataType;
	}
	final LogicalType logicalType = dataType.getLogicalType();
	final boolean supportsConversion = logicalType.supportsInputConversion(clazz) ||
		logicalType.supportsOutputConversion(clazz);
	if (supportsConversion) {
		return dataType.bridgedTo(clazz);
	}
	return dataType;
}
 
Example 6
Source File: ValuesOperationFactory.java    From flink with Apache License 2.0 4 votes vote down vote up
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();
	}
}