in parquet-column/src/main/java/org/apache/parquet/schema/Types.java [429:640]
protected PrimitiveType build(String name) {
if (length == 0 && logicalTypeAnnotation instanceof LogicalTypeAnnotation.UUIDLogicalTypeAnnotation) {
length = LogicalTypeAnnotation.UUIDLogicalTypeAnnotation.BYTES;
}
if (PrimitiveTypeName.FIXED_LEN_BYTE_ARRAY == primitiveType) {
Preconditions.checkArgument(length > 0, "Invalid FIXED_LEN_BYTE_ARRAY length: %s", length);
}
DecimalMetadata meta = decimalMetadata();
// validate type annotations and required metadata
if (logicalTypeAnnotation != null) {
logicalTypeAnnotation
.accept(new LogicalTypeAnnotation.LogicalTypeAnnotationVisitor<Boolean>() {
@Override
public Optional<Boolean> visit(
LogicalTypeAnnotation.StringLogicalTypeAnnotation stringLogicalType) {
return checkBinaryPrimitiveType(stringLogicalType);
}
@Override
public Optional<Boolean> visit(
LogicalTypeAnnotation.JsonLogicalTypeAnnotation jsonLogicalType) {
return checkBinaryPrimitiveType(jsonLogicalType);
}
@Override
public Optional<Boolean> visit(
LogicalTypeAnnotation.BsonLogicalTypeAnnotation bsonLogicalType) {
return checkBinaryPrimitiveType(bsonLogicalType);
}
@Override
public Optional<Boolean> visit(
LogicalTypeAnnotation.UUIDLogicalTypeAnnotation uuidLogicalType) {
return checkFixedPrimitiveType(
LogicalTypeAnnotation.UUIDLogicalTypeAnnotation.BYTES, uuidLogicalType);
}
@Override
public Optional<Boolean> visit(
LogicalTypeAnnotation.Float16LogicalTypeAnnotation float16LogicalType) {
return checkFixedPrimitiveType(
LogicalTypeAnnotation.Float16LogicalTypeAnnotation.BYTES, float16LogicalType);
}
@Override
public Optional<Boolean> visit(
LogicalTypeAnnotation.UnknownLogicalTypeAnnotation unknownLogicalType) {
return Optional.of(true);
}
@Override
public Optional<Boolean> visit(
LogicalTypeAnnotation.DecimalLogicalTypeAnnotation decimalLogicalType) {
Preconditions.checkState(
(primitiveType == PrimitiveTypeName.INT32)
|| (primitiveType == PrimitiveTypeName.INT64)
|| (primitiveType == PrimitiveTypeName.BINARY)
|| (primitiveType == PrimitiveTypeName.FIXED_LEN_BYTE_ARRAY),
"DECIMAL can only annotate INT32, INT64, BINARY, and FIXED");
if (primitiveType == PrimitiveTypeName.INT32) {
Preconditions.checkState(
meta.getPrecision() <= MAX_PRECISION_INT32,
"INT32 cannot store %s digits (max %s)",
meta.getPrecision(),
MAX_PRECISION_INT32);
} else if (primitiveType == PrimitiveTypeName.INT64) {
Preconditions.checkState(
meta.getPrecision() <= MAX_PRECISION_INT64,
"INT64 cannot store %s digits (max %s)",
meta.getPrecision(),
MAX_PRECISION_INT64);
if (meta.getPrecision() <= MAX_PRECISION_INT32) {
LOGGER.warn(
"Decimal with {} digits is stored in an INT64, but fits in an INT32. See {}.",
precision,
LOGICAL_TYPES_DOC_URL);
}
} else if (primitiveType == PrimitiveTypeName.FIXED_LEN_BYTE_ARRAY) {
Preconditions.checkState(
meta.getPrecision() <= maxPrecision(length),
"FIXED(%s) cannot store %s digits (max %s)",
length,
meta.getPrecision(),
maxPrecision(length));
}
return Optional.of(true);
}
@Override
public Optional<Boolean> visit(
LogicalTypeAnnotation.DateLogicalTypeAnnotation dateLogicalType) {
return checkInt32PrimitiveType(dateLogicalType);
}
@Override
public Optional<Boolean> visit(
LogicalTypeAnnotation.TimeLogicalTypeAnnotation timeLogicalType) {
LogicalTypeAnnotation.TimeUnit unit = timeLogicalType.getUnit();
switch (unit) {
case MILLIS:
checkInt32PrimitiveType(timeLogicalType);
break;
case MICROS:
case NANOS:
checkInt64PrimitiveType(timeLogicalType);
break;
default:
throw new RuntimeException("Invalid time unit: " + unit);
}
return Optional.of(true);
}
@Override
public Optional<Boolean> visit(
LogicalTypeAnnotation.IntLogicalTypeAnnotation intLogicalType) {
int bitWidth = intLogicalType.getBitWidth();
switch (bitWidth) {
case 8:
case 16:
case 32:
checkInt32PrimitiveType(intLogicalType);
break;
case 64:
checkInt64PrimitiveType(intLogicalType);
break;
default:
throw new RuntimeException("Invalid bit width: " + bitWidth);
}
return Optional.of(true);
}
@Override
public Optional<Boolean> visit(
LogicalTypeAnnotation.TimestampLogicalTypeAnnotation timestampLogicalType) {
return checkInt64PrimitiveType(timestampLogicalType);
}
@Override
public Optional<Boolean> visit(
LogicalTypeAnnotation.IntervalLogicalTypeAnnotation intervalLogicalType) {
return checkFixedPrimitiveType(12, intervalLogicalType);
}
@Override
public Optional<Boolean> visit(
LogicalTypeAnnotation.EnumLogicalTypeAnnotation enumLogicalType) {
return checkBinaryPrimitiveType(enumLogicalType);
}
@Override
public Optional<Boolean> visit(
LogicalTypeAnnotation.GeometryLogicalTypeAnnotation geometryLogicalType) {
return checkBinaryPrimitiveType(geometryLogicalType);
}
@Override
public Optional<Boolean> visit(
LogicalTypeAnnotation.GeographyLogicalTypeAnnotation geographyLogicalType) {
return checkBinaryPrimitiveType(geographyLogicalType);
}
private Optional<Boolean> checkFixedPrimitiveType(
int l, LogicalTypeAnnotation logicalTypeAnnotation) {
Preconditions.checkState(
primitiveType == PrimitiveTypeName.FIXED_LEN_BYTE_ARRAY && length == l,
"%s can only annotate FIXED_LEN_BYTE_ARRAY(%s)",
logicalTypeAnnotation,
l);
return Optional.of(true);
}
private Optional<Boolean> checkBinaryPrimitiveType(
LogicalTypeAnnotation logicalTypeAnnotation) {
Preconditions.checkState(
primitiveType == PrimitiveTypeName.BINARY,
"%s can only annotate BINARY",
logicalTypeAnnotation);
return Optional.of(true);
}
private Optional<Boolean> checkInt32PrimitiveType(
LogicalTypeAnnotation logicalTypeAnnotation) {
Preconditions.checkState(
primitiveType == PrimitiveTypeName.INT32,
"%s can only annotate INT32",
logicalTypeAnnotation);
return Optional.of(true);
}
private Optional<Boolean> checkInt64PrimitiveType(
LogicalTypeAnnotation logicalTypeAnnotation) {
Preconditions.checkState(
primitiveType == PrimitiveTypeName.INT64,
"%s can only annotate INT64",
logicalTypeAnnotation);
return Optional.of(true);
}
})
.orElseThrow(() -> new IllegalStateException(
logicalTypeAnnotation + " can not be applied to a primitive type"));
}
if (newLogicalTypeSet) {
return new PrimitiveType(
repetition, primitiveType, length, name, logicalTypeAnnotation, id, columnOrder);
} else {
return new PrimitiveType(
repetition, primitiveType, length, name, getOriginalType(), meta, id, columnOrder);
}
}