private boolean typesMatchForInsert(Iterable<Type> tableTypes, Iterable<Type> queryTypes) { if (Iterables.size(tableTypes) != Iterables.size(queryTypes)) { return false; } Iterator<Type> tableTypesIterator = tableTypes.iterator(); Iterator<Type> queryTypesIterator = queryTypes.iterator(); while (tableTypesIterator.hasNext()) { Type tableType = tableTypesIterator.next(); Type queryType = queryTypesIterator.next(); if (!metadata.getTypeManager().canCoerce(queryType, tableType)) { return false; } } return true; }
private boolean typesMatchForInsert(Iterable<Type> tableTypes, Iterable<Type> queryTypes) { if (Iterables.size(tableTypes) != Iterables.size(queryTypes)) { return false; } Iterator<Type> tableTypesIterator = tableTypes.iterator(); Iterator<Type> queryTypesIterator = queryTypes.iterator(); while (tableTypesIterator.hasNext()) { Type tableType = tableTypesIterator.next(); Type queryType = queryTypesIterator.next(); if (!metadata.getTypeManager().canCoerce(queryType, tableType)) { return false; } } return true; }
private void coerceType(Expression expression, Type actualType, Type expectedType, String message) { if (!actualType.equals(expectedType)) { if (!typeManager.canCoerce(actualType, expectedType)) { throw new SemanticException(TYPE_MISMATCH, expression, message + " must evaluate to a %s (actual: %s)", expectedType, actualType); } addOrReplaceExpressionCoercion(expression, actualType, expectedType); } }
private void coerceType(Expression expression, Type actualType, Type expectedType, String message) { if (!actualType.equals(expectedType)) { if (!typeManager.canCoerce(actualType, expectedType)) { throw new SemanticException(TYPE_MISMATCH, expression, message + " must evaluate to a %s (actual: %s)", expectedType, actualType); } addOrReplaceExpressionCoercion(expression, actualType, expectedType); } }
private boolean isViewStale(List<ViewDefinition.ViewColumn> columns, Collection<Field> fields) { if (columns.size() != fields.size()) { return true; } List<Field> fieldList = ImmutableList.copyOf(fields); for (int i = 0; i < columns.size(); i++) { ViewDefinition.ViewColumn column = columns.get(i); Field field = fieldList.get(i); if (!column.getName().equalsIgnoreCase(field.getName().orElse(null)) || !metadata.getTypeManager().canCoerce(field.getType(), column.getType())) { return true; } } return false; }
private boolean isViewStale(List<ViewDefinition.ViewColumn> columns, Collection<Field> fields) { if (columns.size() != fields.size()) { return true; } List<Field> fieldList = ImmutableList.copyOf(fields); for (int i = 0; i < columns.size(); i++) { ViewDefinition.ViewColumn column = columns.get(i); Field field = fieldList.get(i); if (!column.getName().equalsIgnoreCase(field.getName().orElse(null)) || !metadata.getTypeManager().canCoerce(field.getType(), column.getType())) { return true; } } return false; }
@Test public void testCanCoerceIsTransitive() { Set<Type> types = getStandardPrimitiveTypes(); for (Type transitiveType : types) { for (Type resultType : types) { if (typeRegistry.canCoerce(transitiveType, resultType)) { for (Type sourceType : types) { if (typeRegistry.canCoerce(sourceType, transitiveType)) { if (!typeRegistry.canCoerce(sourceType, resultType)) { fail(format("'%s' -> '%s' coercion is missing when transitive coercion is possible: '%s' -> '%s' -> '%s'", sourceType, resultType, sourceType, transitiveType, resultType)); } } } } } } }
private boolean isImplicitCoercion(Cast cast) { Map<NodeRef<Expression>, Type> expressionTypes = analyzeExpression(cast); Type actualType = expressionTypes.get(NodeRef.of(cast.getExpression())); Type expectedType = expressionTypes.get(NodeRef.<Expression>of(cast)); return metadata.getTypeManager().canCoerce(actualType, expectedType); }
@Test public void testCanCoerceIsTransitive() { Set<Type> types = getStandardPrimitiveTypes(); for (Type transitiveType : types) { for (Type resultType : types) { if (typeRegistry.canCoerce(transitiveType, resultType)) { for (Type sourceType : types) { if (typeRegistry.canCoerce(sourceType, transitiveType)) { if (!typeRegistry.canCoerce(sourceType, resultType)) { fail(format("'%s' -> '%s' coercion is missing when transitive coercion is possible: '%s' -> '%s' -> '%s'", sourceType, resultType, sourceType, transitiveType, resultType)); } } } } } } }
private boolean satisfiesCoercion(boolean allowCoercion, Type fromType, TypeSignature toTypeSignature) { if (allowCoercion) { return typeManager.canCoerce(fromType, typeManager.getType(toTypeSignature)); } else { return fromType.getTypeSignature().equals(toTypeSignature); } }
private boolean isImplicitCoercion(Cast cast) { Map<NodeRef<Expression>, Type> expressionTypes = analyzeExpression(cast); Type actualType = expressionTypes.get(NodeRef.of(cast.getExpression())); Type expectedType = expressionTypes.get(NodeRef.<Expression>of(cast)); return metadata.getTypeManager().canCoerce(actualType, expectedType); }
private boolean satisfiesCoercion(boolean allowCoercion, Type fromType, TypeSignature toTypeSignature) { if (allowCoercion) { return typeManager.canCoerce(fromType, typeManager.getType(toTypeSignature)); } else { return fromType.getTypeSignature().equals(toTypeSignature); } }
private CompatibilityAssertion assertThat(Type firstType, Type secondType) { Optional<Type> commonSuperType1 = typeRegistry.getCommonSuperType(firstType, secondType); Optional<Type> commonSuperType2 = typeRegistry.getCommonSuperType(secondType, firstType); assertEquals(commonSuperType1, commonSuperType2, "Expected getCommonSuperType to return the same result when invoked in either order"); boolean canCoerceFirstToSecond = typeRegistry.canCoerce(firstType, secondType); boolean canCoerceSecondToFirst = typeRegistry.canCoerce(secondType, firstType); return new CompatibilityAssertion(commonSuperType1, canCoerceFirstToSecond, canCoerceSecondToFirst); }
@Test public void testCastOperatorsExistForCoercions() { Set<Type> types = getStandardPrimitiveTypes(); for (Type sourceType : types) { for (Type resultType : types) { if (typeRegistry.canCoerce(sourceType, resultType) && sourceType != UNKNOWN && resultType != UNKNOWN) { assertTrue(functionRegistry.canResolveOperator(OperatorType.CAST, resultType, ImmutableList.of(sourceType)), format("'%s' -> '%s' coercion exists but there is no cast operator", sourceType, resultType)); } } } }
private CompatibilityAssertion assertThat(Type firstType, Type secondType) { Optional<Type> commonSuperType1 = typeRegistry.getCommonSuperType(firstType, secondType); Optional<Type> commonSuperType2 = typeRegistry.getCommonSuperType(secondType, firstType); assertEquals(commonSuperType1, commonSuperType2, "Expected getCommonSuperType to return the same result when invoked in either order"); boolean canCoerceFirstToSecond = typeRegistry.canCoerce(firstType, secondType); boolean canCoerceSecondToFirst = typeRegistry.canCoerce(secondType, firstType); return new CompatibilityAssertion(commonSuperType1, canCoerceFirstToSecond, canCoerceSecondToFirst); }
@Test public void testCastOperatorsExistForCoercions() { Set<Type> types = getStandardPrimitiveTypes(); for (Type sourceType : types) { for (Type resultType : types) { if (typeRegistry.canCoerce(sourceType, resultType) && sourceType != UNKNOWN && resultType != UNKNOWN) { assertTrue(functionRegistry.canResolveOperator(OperatorType.CAST, resultType, ImmutableList.of(sourceType)), format("'%s' -> '%s' coercion exists but there is no cast operator", sourceType, resultType)); } } } }
private Type coerceToSingleType(StackableAstVisitorContext<Context> context, String message, List<Expression> expressions) { // determine super type Type superType = UNKNOWN; for (Expression expression : expressions) { Optional<Type> newSuperType = typeManager.getCommonSuperType(superType, process(expression, context)); if (!newSuperType.isPresent()) { throw new SemanticException(TYPE_MISMATCH, expression, message, superType); } superType = newSuperType.get(); } // verify all expressions can be coerced to the superType for (Expression expression : expressions) { Type type = process(expression, context); if (!type.equals(superType)) { if (!typeManager.canCoerce(type, superType)) { throw new SemanticException(TYPE_MISMATCH, expression, message, superType); } addOrReplaceExpressionCoercion(expression, type, superType); } } return superType; }
public static Object evaluateConstantExpression(Expression expression, Type expectedType, Metadata metadata, Session session, List<Expression> parameters) { ExpressionAnalyzer analyzer = createConstantAnalyzer(metadata, session, parameters, WarningCollector.NOOP); analyzer.analyze(expression, Scope.create()); Type actualType = analyzer.getExpressionTypes().get(NodeRef.of(expression)); if (!metadata.getTypeManager().canCoerce(actualType, expectedType)) { throw new SemanticException(SemanticErrorCode.TYPE_MISMATCH, expression, format("Cannot cast type %s to %s", actualType.getTypeSignature(), expectedType.getTypeSignature())); } Map<NodeRef<Expression>, Type> coercions = ImmutableMap.<NodeRef<Expression>, Type>builder() .putAll(analyzer.getExpressionCoercions()) .put(NodeRef.of(expression), expectedType) .build(); return evaluateConstantExpression(expression, coercions, analyzer.getTypeOnlyCoercions(), metadata, session, ImmutableSet.of(), parameters); }
private Type coerceToSingleType(StackableAstVisitorContext<Context> context, String message, List<Expression> expressions) { // determine super type Type superType = UNKNOWN; for (Expression expression : expressions) { Optional<Type> newSuperType = typeManager.getCommonSuperType(superType, process(expression, context)); if (!newSuperType.isPresent()) { throw new SemanticException(TYPE_MISMATCH, expression, message, superType); } superType = newSuperType.get(); } // verify all expressions can be coerced to the superType for (Expression expression : expressions) { Type type = process(expression, context); if (!type.equals(superType)) { if (!typeManager.canCoerce(type, superType)) { throw new SemanticException(TYPE_MISMATCH, expression, message, superType); } addOrReplaceExpressionCoercion(expression, type, superType); } } return superType; }
public static Object evaluateConstantExpression(Expression expression, Type expectedType, Metadata metadata, Session session, List<Expression> parameters) { ExpressionAnalyzer analyzer = createConstantAnalyzer(metadata, session, parameters, WarningCollector.NOOP); analyzer.analyze(expression, Scope.create()); Type actualType = analyzer.getExpressionTypes().get(NodeRef.of(expression)); if (!metadata.getTypeManager().canCoerce(actualType, expectedType)) { throw new SemanticException(SemanticErrorCode.TYPE_MISMATCH, expression, format("Cannot cast type %s to %s", actualType.getTypeSignature(), expectedType.getTypeSignature())); } Map<NodeRef<Expression>, Type> coercions = ImmutableMap.<NodeRef<Expression>, Type>builder() .putAll(analyzer.getExpressionCoercions()) .put(NodeRef.of(expression), expectedType) .build(); return evaluateConstantExpression(expression, coercions, analyzer.getTypeOnlyCoercions(), metadata, session, ImmutableSet.of(), parameters); }