in xtable-core/src/main/java/org/apache/xtable/avro/AvroSchemaConverter.java [329:473]
private Schema fromInternalSchema(InternalSchema internalSchema, String currentPath) {
switch (internalSchema.getDataType()) {
case RECORD:
List<Schema.Field> fields =
internalSchema.getFields().stream()
.map(
field ->
new Schema.Field(
field.getName(),
fromInternalSchema(
field.getSchema(),
SchemaUtils.getFullyQualifiedPath(currentPath, field.getName())),
field.getSchema().getComment(),
InternalField.Constants.NULL_DEFAULT_VALUE == field.getDefaultValue()
? Schema.Field.NULL_VALUE
: field.getDefaultValue()))
.collect(CustomCollectors.toList(internalSchema.getFields().size()));
return finalizeSchema(
Schema.createRecord(
internalSchema.getName(), internalSchema.getComment(), currentPath, false, fields),
internalSchema);
case BYTES:
return finalizeSchema(Schema.create(Schema.Type.BYTES), internalSchema);
case BOOLEAN:
return finalizeSchema(Schema.create(Schema.Type.BOOLEAN), internalSchema);
case INT:
return finalizeSchema(Schema.create(Schema.Type.INT), internalSchema);
case LONG:
if (internalSchema.getMetadata() != null
&& internalSchema
.getMetadata()
.containsKey(InternalSchema.MetadataKey.TIMESTAMP_PRECISION)) {
if (internalSchema.getMetadata().get(InternalSchema.MetadataKey.TIMESTAMP_PRECISION)
== InternalSchema.MetadataValue.MILLIS) {
return finalizeSchema(
LogicalTypes.localTimestampMillis().addToSchema(Schema.create(Schema.Type.LONG)),
internalSchema);
}
{
return finalizeSchema(
LogicalTypes.localTimestampMicros().addToSchema(Schema.create(Schema.Type.LONG)),
internalSchema);
}
}
return finalizeSchema(Schema.create(Schema.Type.LONG), internalSchema);
case STRING:
return finalizeSchema(Schema.create(Schema.Type.STRING), internalSchema);
case FLOAT:
return finalizeSchema(Schema.create(Schema.Type.FLOAT), internalSchema);
case DOUBLE:
return finalizeSchema(Schema.create(Schema.Type.DOUBLE), internalSchema);
case ENUM:
return finalizeSchema(
Schema.createEnum(
internalSchema.getName(),
internalSchema.getComment(),
null,
(List<String>)
internalSchema.getMetadata().get(InternalSchema.MetadataKey.ENUM_VALUES),
null),
internalSchema);
case DATE:
return finalizeSchema(
LogicalTypes.date().addToSchema(Schema.create(Schema.Type.INT)), internalSchema);
case TIMESTAMP:
if (internalSchema.getMetadata().get(InternalSchema.MetadataKey.TIMESTAMP_PRECISION)
== InternalSchema.MetadataValue.MICROS) {
return finalizeSchema(
LogicalTypes.timestampMicros().addToSchema(Schema.create(Schema.Type.LONG)),
internalSchema);
} else {
return finalizeSchema(
LogicalTypes.timestampMillis().addToSchema(Schema.create(Schema.Type.LONG)),
internalSchema);
}
case TIMESTAMP_NTZ:
if (internalSchema.getMetadata().get(InternalSchema.MetadataKey.TIMESTAMP_PRECISION)
== InternalSchema.MetadataValue.MICROS) {
return finalizeSchema(
LogicalTypes.localTimestampMicros().addToSchema(Schema.create(Schema.Type.LONG)),
internalSchema);
} else {
return finalizeSchema(
LogicalTypes.localTimestampMillis().addToSchema(Schema.create(Schema.Type.LONG)),
internalSchema);
}
case LIST:
InternalField elementField =
internalSchema.getFields().stream()
.filter(
field ->
InternalField.Constants.ARRAY_ELEMENT_FIELD_NAME.equals(field.getName()))
.findFirst()
.orElseThrow(() -> new SchemaExtractorException("Invalid array schema"));
return finalizeSchema(
Schema.createArray(
fromInternalSchema(elementField.getSchema(), elementField.getPath())),
internalSchema);
case MAP:
InternalField valueField =
internalSchema.getFields().stream()
.filter(
field -> InternalField.Constants.MAP_VALUE_FIELD_NAME.equals(field.getName()))
.findFirst()
.orElseThrow(() -> new SchemaExtractorException("Invalid map schema"));
return finalizeSchema(
Schema.createMap(fromInternalSchema(valueField.getSchema(), valueField.getPath())),
internalSchema);
case DECIMAL:
int precision =
(int) internalSchema.getMetadata().get(InternalSchema.MetadataKey.DECIMAL_PRECISION);
int scale =
(int) internalSchema.getMetadata().get(InternalSchema.MetadataKey.DECIMAL_SCALE);
Integer size =
(Integer) internalSchema.getMetadata().get(InternalSchema.MetadataKey.FIXED_BYTES_SIZE);
if (size == null) {
return finalizeSchema(
LogicalTypes.decimal(precision, scale).addToSchema(Schema.create(Schema.Type.BYTES)),
internalSchema);
} else {
return finalizeSchema(
LogicalTypes.decimal(precision, scale)
.addToSchema(
Schema.createFixed(
internalSchema.getName(), internalSchema.getComment(), null, size)),
internalSchema);
}
case FIXED:
Integer fixedSize =
(Integer) internalSchema.getMetadata().get(InternalSchema.MetadataKey.FIXED_BYTES_SIZE);
return finalizeSchema(
Schema.createFixed(
internalSchema.getName(), internalSchema.getComment(), null, fixedSize),
internalSchema);
case UUID:
Schema uuidSchema =
Schema.createFixed(internalSchema.getName(), internalSchema.getComment(), null, 16);
uuidSchema.addProp(InternalSchema.XTABLE_LOGICAL_TYPE, "uuid");
return finalizeSchema(uuidSchema, internalSchema);
default:
throw new UnsupportedSchemaTypeException(
"Encountered unhandled type during InternalSchema to Avro conversion: "
+ internalSchema.getDataType());
}
}