in sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigquery/BigQueryAvroUtils.java [591:669]
private static TableFieldSchema typedTableFieldSchema(Schema type, Boolean useAvroLogicalTypes) {
TableFieldSchema fieldSchema = new TableFieldSchema();
LogicalType logicalType = useAvroLogicalTypes ? type.getLogicalType() : null;
String sqlType = useAvroLogicalTypes ? type.getProp("sqlType") : null;
switch (type.getType()) {
case INT:
if (logicalType instanceof LogicalTypes.Date) {
return fieldSchema.setType("DATE");
} else if (logicalType instanceof LogicalTypes.TimeMillis) {
return fieldSchema.setType("TIME");
} else {
return fieldSchema.setType("INTEGER");
}
case LONG:
if (logicalType instanceof LogicalTypes.TimeMicros) {
return fieldSchema.setType("TIME");
} else if (!(VERSION_AVRO.startsWith("1.8") || VERSION_AVRO.startsWith("1.9"))
&& (logicalType instanceof LogicalTypes.LocalTimestampMillis
|| logicalType instanceof LogicalTypes.LocalTimestampMicros)) {
return fieldSchema.setType("DATETIME");
} else if (logicalType instanceof LogicalTypes.TimestampMillis
|| logicalType instanceof LogicalTypes.TimestampMicros) {
return fieldSchema.setType("TIMESTAMP");
} else {
return fieldSchema.setType("INTEGER");
}
case FLOAT:
case DOUBLE:
return fieldSchema.setType("FLOAT");
case BOOLEAN:
return fieldSchema.setType("BOOLEAN");
case STRING:
if ("GEOGRAPHY".equals(sqlType)) {
return fieldSchema.setType("GEOGRAPHY");
} else if ("JSON".equals(sqlType)) {
return fieldSchema.setType("JSON");
} else {
return fieldSchema.setType("STRING");
}
case BYTES:
if (logicalType instanceof LogicalTypes.Decimal) {
LogicalTypes.Decimal decimal = (LogicalTypes.Decimal) logicalType;
int precision = decimal.getPrecision();
int scale = decimal.getScale();
if (scale <= 9 && precision - scale <= 29) {
fieldSchema.setType("NUMERIC");
if (!(precision == 38 && scale == 9)) {
fieldSchema.setPrecision((long) precision);
if (scale != 0) {
fieldSchema.setScale((long) scale);
}
}
} else {
fieldSchema.setType("BIGNUMERIC");
if (!(precision == 77 && scale == 38)) {
fieldSchema.setPrecision((long) precision);
if (scale != 0) {
fieldSchema.setScale((long) scale);
}
}
}
return fieldSchema;
} else {
return fieldSchema.setType("BYTES");
}
case ENUM:
return fieldSchema.setType("STRING");
case FIXED:
return fieldSchema.setType("BYTES");
case RECORD:
List<TableFieldSchema> recordFields =
type.getFields().stream()
.map(f -> fromAvroFieldSchema(f, useAvroLogicalTypes))
.collect(Collectors.toList());
return new TableFieldSchema().setType("RECORD").setFields(recordFields);
default:
throw new IllegalArgumentException("Unknown Avro type: " + type.getType());
}
}