diff --git a/crates/catalog/glue/src/schema.rs b/crates/catalog/glue/src/schema.rs index 59d51f3dc1..d9779d27da 100644 --- a/crates/catalog/glue/src/schema.rs +++ b/crates/catalog/glue/src/schema.rs @@ -26,7 +26,7 @@ use std::collections::HashMap; use aws_sdk_glue::types::Column; use iceberg::spec::{PrimitiveType, SchemaVisitor, TableMetadata, VariantType, visit_schema}; -use iceberg::{Error, ErrorKind, Result}; +use iceberg::Result; use crate::error::from_aws_build_error; @@ -157,12 +157,10 @@ impl SchemaVisitor for GlueSchemaBuilder { PrimitiveType::Date => "date".to_string(), PrimitiveType::Timestamp => "timestamp".to_string(), PrimitiveType::TimestampNs => "timestamp_ns".to_string(), - PrimitiveType::Timestamptz | PrimitiveType::TimestamptzNs => { - return Err(Error::new( - ErrorKind::FeatureUnsupported, - format!("Conversion from {p:?} is not supported"), - )); - } + // Glue has no timezone-aware timestamp type; map to the equivalent non-tz type, + // matching the behavior of the AWS Glue catalog module in apache/iceberg. + PrimitiveType::Timestamptz => "timestamp".to_string(), + PrimitiveType::TimestamptzNs => "timestamp_ns".to_string(), PrimitiveType::Time | PrimitiveType::String | PrimitiveType::Uuid => { "string".to_string() } @@ -342,6 +340,42 @@ mod tests { Ok(()) } + #[test] + fn test_schema_with_timestamptz_fields() -> Result<()> { + let record = r#"{ + "type": "struct", + "schema-id": 1, + "fields": [ + { + "id": 1, + "name": "ts_tz", + "required": true, + "type": "timestamptz" + }, + { + "id": 2, + "name": "ts_tz_ns", + "required": true, + "type": "timestamptz_ns" + } + ] + }"#; + + let schema = serde_json::from_str::(record)?; + let metadata = create_metadata(schema)?; + + let result = GlueSchemaBuilder::from_iceberg(&metadata)?.build(); + + let expected = vec![ + create_column("ts_tz", "timestamp", "1", false)?, + create_column("ts_tz_ns", "timestamp_ns", "2", false)?, + ]; + + assert_eq!(result, expected); + + Ok(()) + } + #[test] fn test_schema_with_structs() -> Result<()> { let record = r#"{