in parquet/src/schema/types.rs [1409:1740]
fn test_primitive_type() {
let mut result = Type::primitive_type_builder("foo", PhysicalType::INT32)
.with_logical_type(Some(LogicalType::Integer {
bit_width: 32,
is_signed: true,
}))
.with_id(Some(0))
.build();
assert!(result.is_ok());
if let Ok(tp) = result {
assert!(tp.is_primitive());
assert!(!tp.is_group());
let basic_info = tp.get_basic_info();
assert_eq!(basic_info.repetition(), Repetition::OPTIONAL);
assert_eq!(
basic_info.logical_type(),
Some(LogicalType::Integer {
bit_width: 32,
is_signed: true
})
);
assert_eq!(basic_info.converted_type(), ConvertedType::INT_32);
assert_eq!(basic_info.id(), 0);
match tp {
Type::PrimitiveType { physical_type, .. } => {
assert_eq!(physical_type, PhysicalType::INT32);
}
_ => panic!(),
}
}
// Test illegal inputs with logical type
result = Type::primitive_type_builder("foo", PhysicalType::INT64)
.with_repetition(Repetition::REPEATED)
.with_logical_type(Some(LogicalType::Integer {
is_signed: true,
bit_width: 8,
}))
.build();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
format!("{e}"),
"Parquet error: Cannot annotate Integer { bit_width: 8, is_signed: true } from INT64 for field 'foo'"
);
}
// Test illegal inputs with converted type
result = Type::primitive_type_builder("foo", PhysicalType::INT64)
.with_repetition(Repetition::REPEATED)
.with_converted_type(ConvertedType::BSON)
.build();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
format!("{e}"),
"Parquet error: BSON cannot annotate field 'foo' because it is not a BYTE_ARRAY field"
);
}
result = Type::primitive_type_builder("foo", PhysicalType::INT96)
.with_repetition(Repetition::REQUIRED)
.with_converted_type(ConvertedType::DECIMAL)
.with_precision(-1)
.with_scale(-1)
.build();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
format!("{e}"),
"Parquet error: DECIMAL can only annotate INT32, INT64, BYTE_ARRAY and FIXED_LEN_BYTE_ARRAY"
);
}
result = Type::primitive_type_builder("foo", PhysicalType::BYTE_ARRAY)
.with_repetition(Repetition::REQUIRED)
.with_logical_type(Some(LogicalType::Decimal {
scale: 32,
precision: 12,
}))
.with_precision(-1)
.with_scale(-1)
.build();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
format!("{e}"),
"Parquet error: DECIMAL logical type scale 32 must match self.scale -1 for field 'foo'"
);
}
result = Type::primitive_type_builder("foo", PhysicalType::BYTE_ARRAY)
.with_repetition(Repetition::REQUIRED)
.with_converted_type(ConvertedType::DECIMAL)
.with_precision(-1)
.with_scale(-1)
.build();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
format!("{e}"),
"Parquet error: Invalid DECIMAL precision: -1"
);
}
result = Type::primitive_type_builder("foo", PhysicalType::BYTE_ARRAY)
.with_repetition(Repetition::REQUIRED)
.with_converted_type(ConvertedType::DECIMAL)
.with_precision(0)
.with_scale(-1)
.build();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
format!("{e}"),
"Parquet error: Invalid DECIMAL precision: 0"
);
}
result = Type::primitive_type_builder("foo", PhysicalType::BYTE_ARRAY)
.with_repetition(Repetition::REQUIRED)
.with_converted_type(ConvertedType::DECIMAL)
.with_precision(1)
.with_scale(-1)
.build();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(format!("{e}"), "Parquet error: Invalid DECIMAL scale: -1");
}
result = Type::primitive_type_builder("foo", PhysicalType::BYTE_ARRAY)
.with_repetition(Repetition::REQUIRED)
.with_converted_type(ConvertedType::DECIMAL)
.with_precision(1)
.with_scale(2)
.build();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
format!("{e}"),
"Parquet error: Invalid DECIMAL: scale (2) cannot be greater than precision (1)"
);
}
// It is OK if precision == scale
result = Type::primitive_type_builder("foo", PhysicalType::BYTE_ARRAY)
.with_repetition(Repetition::REQUIRED)
.with_converted_type(ConvertedType::DECIMAL)
.with_precision(1)
.with_scale(1)
.build();
assert!(result.is_ok());
result = Type::primitive_type_builder("foo", PhysicalType::INT32)
.with_repetition(Repetition::REQUIRED)
.with_converted_type(ConvertedType::DECIMAL)
.with_precision(18)
.with_scale(2)
.build();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
format!("{e}"),
"Parquet error: Cannot represent INT32 as DECIMAL with precision 18"
);
}
result = Type::primitive_type_builder("foo", PhysicalType::INT64)
.with_repetition(Repetition::REQUIRED)
.with_converted_type(ConvertedType::DECIMAL)
.with_precision(32)
.with_scale(2)
.build();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
format!("{e}"),
"Parquet error: Cannot represent INT64 as DECIMAL with precision 32"
);
}
result = Type::primitive_type_builder("foo", PhysicalType::FIXED_LEN_BYTE_ARRAY)
.with_repetition(Repetition::REQUIRED)
.with_converted_type(ConvertedType::DECIMAL)
.with_length(5)
.with_precision(12)
.with_scale(2)
.build();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
format!("{e}"),
"Parquet error: Cannot represent FIXED_LEN_BYTE_ARRAY as DECIMAL with length 5 and precision 12. The max precision can only be 11"
);
}
result = Type::primitive_type_builder("foo", PhysicalType::INT64)
.with_repetition(Repetition::REQUIRED)
.with_converted_type(ConvertedType::UINT_8)
.build();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
format!("{e}"),
"Parquet error: UINT_8 cannot annotate field 'foo' because it is not a INT32 field"
);
}
result = Type::primitive_type_builder("foo", PhysicalType::INT32)
.with_repetition(Repetition::REQUIRED)
.with_converted_type(ConvertedType::TIME_MICROS)
.build();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
format!("{e}"),
"Parquet error: TIME_MICROS cannot annotate field 'foo' because it is not a INT64 field"
);
}
result = Type::primitive_type_builder("foo", PhysicalType::BYTE_ARRAY)
.with_repetition(Repetition::REQUIRED)
.with_converted_type(ConvertedType::INTERVAL)
.build();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
format!("{e}"),
"Parquet error: INTERVAL cannot annotate field 'foo' because it is not a FIXED_LEN_BYTE_ARRAY(12) field"
);
}
result = Type::primitive_type_builder("foo", PhysicalType::FIXED_LEN_BYTE_ARRAY)
.with_repetition(Repetition::REQUIRED)
.with_converted_type(ConvertedType::INTERVAL)
.with_length(1)
.build();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
format!("{e}"),
"Parquet error: INTERVAL cannot annotate field 'foo' because it is not a FIXED_LEN_BYTE_ARRAY(12) field"
);
}
result = Type::primitive_type_builder("foo", PhysicalType::INT32)
.with_repetition(Repetition::REQUIRED)
.with_converted_type(ConvertedType::ENUM)
.build();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
format!("{e}"),
"Parquet error: ENUM cannot annotate field 'foo' because it is not a BYTE_ARRAY field"
);
}
result = Type::primitive_type_builder("foo", PhysicalType::INT32)
.with_repetition(Repetition::REQUIRED)
.with_converted_type(ConvertedType::MAP)
.build();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
format!("{e}"),
"Parquet error: MAP cannot be applied to primitive field 'foo'"
);
}
result = Type::primitive_type_builder("foo", PhysicalType::FIXED_LEN_BYTE_ARRAY)
.with_repetition(Repetition::REQUIRED)
.with_converted_type(ConvertedType::DECIMAL)
.with_length(-1)
.build();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
format!("{e}"),
"Parquet error: Invalid FIXED_LEN_BYTE_ARRAY length: -1 for field 'foo'"
);
}
result = Type::primitive_type_builder("foo", PhysicalType::FIXED_LEN_BYTE_ARRAY)
.with_repetition(Repetition::REQUIRED)
.with_logical_type(Some(LogicalType::Float16))
.with_length(2)
.build();
assert!(result.is_ok());
// Can't be other than FIXED_LEN_BYTE_ARRAY for physical type
result = Type::primitive_type_builder("foo", PhysicalType::FLOAT)
.with_repetition(Repetition::REQUIRED)
.with_logical_type(Some(LogicalType::Float16))
.with_length(2)
.build();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
format!("{e}"),
"Parquet error: Cannot annotate Float16 from FLOAT for field 'foo'"
);
}
// Must have length 2
result = Type::primitive_type_builder("foo", PhysicalType::FIXED_LEN_BYTE_ARRAY)
.with_repetition(Repetition::REQUIRED)
.with_logical_type(Some(LogicalType::Float16))
.with_length(4)
.build();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
format!("{e}"),
"Parquet error: FLOAT16 cannot annotate field 'foo' because it is not a FIXED_LEN_BYTE_ARRAY(2) field"
);
}
// Must have length 16
result = Type::primitive_type_builder("foo", PhysicalType::FIXED_LEN_BYTE_ARRAY)
.with_repetition(Repetition::REQUIRED)
.with_logical_type(Some(LogicalType::Uuid))
.with_length(15)
.build();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
format!("{e}"),
"Parquet error: UUID cannot annotate field 'foo' because it is not a FIXED_LEN_BYTE_ARRAY(16) field"
);
}
}