Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions crates/catalog/glue/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,12 @@ impl SchemaVisitor for GlueSchemaBuilder {
PrimitiveType::Decimal { precision, scale } => {
format!("decimal({precision},{scale})")
}
PrimitiveType::Variant => {
return Err(Error::new(
ErrorKind::FeatureUnsupported,
"Conversion from Variant to Glue type is not supported",
));
}
};

Ok(glue_type)
Expand Down
6 changes: 6 additions & 0 deletions crates/catalog/hms/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ impl SchemaVisitor for HiveSchemaBuilder {
PrimitiveType::Decimal { precision, scale } => {
format!("decimal({precision},{scale})")
}
PrimitiveType::Variant => {
return Err(Error::new(
ErrorKind::FeatureUnsupported,
"Conversion from Variant to Hive type is not supported",
));
}
};

Ok(hive_type)
Expand Down
5 changes: 5 additions & 0 deletions crates/iceberg/src/arrow/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,10 @@ impl SchemaVisitor for ToArrowSchemaConverter {
crate::spec::PrimitiveType::Binary => {
Ok(ArrowSchemaOrFieldOrType::Type(DataType::LargeBinary))
}
crate::spec::PrimitiveType::Variant => Err(crate::Error::new(
crate::ErrorKind::FeatureUnsupported,
"Arrow schema conversion for Variant is not yet implemented",
)),
}
}
}
Expand Down Expand Up @@ -1131,6 +1135,7 @@ pub fn datum_to_arrow_type_with_ree(datum: &Datum) -> DataType {
PrimitiveType::Uuid => make_ree(DataType::Binary),
PrimitiveType::Fixed(_) => make_ree(DataType::Binary),
PrimitiveType::Binary => make_ree(DataType::Binary),
PrimitiveType::Variant => make_ree(DataType::Binary),
PrimitiveType::Decimal { precision, scale } => {
make_ree(DataType::Decimal128(*precision as u8, *scale as i8))
}
Expand Down
4 changes: 4 additions & 0 deletions crates/iceberg/src/arrow/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,10 @@ impl SchemaWithPartnerVisitor<ArrayRef> for ArrowArrayToIcebergStructConverter {
))
}
}
PrimitiveType::Variant => Err(Error::new(
ErrorKind::FeatureUnsupported,
"Arrow value extraction for Variant is not yet implemented",
)),
}
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/iceberg/src/avro/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ impl SchemaVisitor for SchemaToAvroSchema {
PrimitiveType::Uuid => AvroSchema::Uuid,
PrimitiveType::Fixed(len) => avro_fixed_schema((*len) as usize)?,
PrimitiveType::Binary => AvroSchema::Bytes,
PrimitiveType::Variant => AvroSchema::Bytes,
PrimitiveType::Decimal { precision, scale } => {
avro_decimal_schema(*precision as usize, *scale as usize)?
}
Expand Down
33 changes: 32 additions & 1 deletion crates/iceberg/src/spec/datatypes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ pub enum PrimitiveType {
Fixed(u64),
/// Arbitrary-length byte array.
Binary,
/// Semi-structured data type (Iceberg spec v3). Stored in Parquet as `LogicalType::Variant`.
Variant,
}

impl PrimitiveType {
Expand Down Expand Up @@ -382,6 +384,7 @@ impl fmt::Display for PrimitiveType {
PrimitiveType::Uuid => write!(f, "uuid"),
PrimitiveType::Fixed(size) => write!(f, "fixed({size})"),
PrimitiveType::Binary => write!(f, "binary"),
PrimitiveType::Variant => write!(f, "variant"),
Comment thread
Shekharrajak marked this conversation as resolved.
Outdated
}
}
}
Expand Down Expand Up @@ -884,7 +887,8 @@ mod tests {
{"id": 13, "name": "uuid_field", "required": true, "type": "uuid"},
{"id": 14, "name": "fixed_field", "required": true, "type": "fixed[10]"},
{"id": 15, "name": "binary_field", "required": true, "type": "binary"},
{"id": 16, "name": "string_field", "required": true, "type": "string"}
{"id": 16, "name": "string_field", "required": true, "type": "string"},
{"id": 17, "name": "variant_field", "required": false, "type": "variant"}
]
}
"#;
Expand Down Expand Up @@ -964,6 +968,12 @@ mod tests {
Type::Primitive(PrimitiveType::String),
)
.into(),
NestedField::optional(
17,
"variant_field",
Type::Primitive(PrimitiveType::Variant),
)
.into(),
],
id_lookup: OnceLock::default(),
name_lookup: OnceLock::default(),
Expand Down Expand Up @@ -1320,4 +1330,25 @@ mod tests {
.contains("expected type 'struct'")
);
}

#[test]
fn variant_type_display() {
assert_eq!(PrimitiveType::Variant.to_string(), "variant");
}

#[test]
fn variant_type_serde() {
let json = r#"{"id": 1, "name": "v", "required": false, "type": "variant"}"#;
let field: NestedField = serde_json::from_str(json).unwrap();
assert_eq!(*field.field_type, Type::Primitive(PrimitiveType::Variant));
let serialized = serde_json::to_string(&field).unwrap();
assert!(serialized.contains("\"variant\""));
}

#[test]
fn variant_type_not_compatible_with_literals() {
assert!(!PrimitiveType::Variant.compatible(&PrimitiveLiteral::Boolean(true)));
assert!(!PrimitiveType::Variant.compatible(&PrimitiveLiteral::Int(0)));
assert!(!PrimitiveType::Variant.compatible(&PrimitiveLiteral::Binary(vec![])));
}
}
1 change: 1 addition & 0 deletions crates/iceberg/src/spec/values/datum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ impl Datum {
}
PrimitiveType::Fixed(_) => PrimitiveLiteral::Binary(Vec::from(bytes)),
PrimitiveType::Binary => PrimitiveLiteral::Binary(Vec::from(bytes)),
PrimitiveType::Variant => PrimitiveLiteral::Binary(Vec::from(bytes)),
PrimitiveType::Decimal { .. } => {
PrimitiveLiteral::Int128(i128_from_be_bytes(bytes).ok_or_else(|| {
Error::new(
Expand Down
Loading