@Override public List<CompatibilityError> accept( Context context, Optional<Field> left, Optional<Field> right) { if (!left.isPresent() && !right.isPresent()) { return Collections.emptyList(); } else if (left.isPresent() && !right.isPresent()) { return Collections.emptyList(); } else if (!left.isPresent() && right.isPresent()) { return Collections.singletonList( CompatibilityError.create(context.path(), "Field is missing in output schema")); } else { if (left.get().getNullable() && !right.get().getNullable()) { return Collections.singletonList( CompatibilityError.create( context.path(), "Can't cast nullable field to non-nullable field")); } } return Collections.emptyList(); }
public void verifyCompatibility(Schema inputSchema) { List<CompatibilityError> errors = validator().apply(inputSchema, outputSchema()); if (!errors.isEmpty()) { String reason = errors .stream() .map(x -> Joiner.on('.').join(x.path()) + ": " + x.message()) .collect(Collectors.joining("\n\t")); throw new IllegalArgumentException( "Cast isn't compatible using " + validator() + ":\n\t" + reason); } }
@Override public List<CompatibilityError> accept(Context context, FieldType input, FieldType output) { TypeName inputType = input.getTypeName(); TypeName outputType = output.getTypeName(); boolean supertype = outputType.isSupertypeOf(inputType); if (isIntegral(inputType) && isDecimal(outputType)) { return Collections.emptyList(); } else if (!supertype) { return Collections.singletonList( CompatibilityError.create( context.path(), "Can't cast '" + inputType + "' to '" + outputType + "'")); } return Collections.emptyList(); } }
@Override public List<CompatibilityError> accept(Context context, FieldType input, FieldType output) { TypeName inputType = input.getTypeName(); TypeName outputType = output.getTypeName(); boolean supertype = outputType.isSupertypeOf(inputType); boolean subtype = outputType.isSubtypeOf(inputType); if (isDecimal(inputType) && isIntegral(outputType)) { return Collections.emptyList(); } else if (!supertype && !subtype) { return Collections.singletonList( CompatibilityError.create( context.path(), "Can't cast '" + inputType + "' to '" + outputType + "'")); } return Collections.emptyList(); } }
@Override public List<CompatibilityError> accept( Context context, Optional<Field> left, Optional<Field> right) { if (!left.isPresent() && right.isPresent()) { return Collections.singletonList( CompatibilityError.create(context.path(), "Field is missing in output schema")); } return Collections.emptyList(); }
@Test public void testWideningNullableToNotNullable() { Schema input = Schema.of(Schema.Field.nullable("f0", FieldType.INT32)); Schema output = Schema.of(Schema.Field.of("f0", FieldType.INT32)); List<Cast.CompatibilityError> errors = Cast.Widening.of().apply(input, output); Cast.CompatibilityError expected = Cast.CompatibilityError.create( Arrays.asList("f0"), "Can't cast nullable field to non-nullable field"); assertThat(errors, containsInAnyOrder(expected)); }