in crates/iceberg/src/spec/table_metadata.rs [811:912]
fn try_from(value: TableMetadataV2) -> Result<Self, self::Error> {
let current_snapshot_id = if let &Some(-1) = &value.current_snapshot_id {
None
} else {
value.current_snapshot_id
};
let schemas = HashMap::from_iter(
value
.schemas
.into_iter()
.map(|schema| Ok((schema.schema_id, Arc::new(schema.try_into()?))))
.collect::<Result<Vec<_>, Error>>()?,
);
let current_schema: &SchemaRef =
schemas.get(&value.current_schema_id).ok_or_else(|| {
Error::new(
ErrorKind::DataInvalid,
format!(
"No schema exists with the current schema id {}.",
value.current_schema_id
),
)
})?;
let partition_specs = HashMap::from_iter(
value
.partition_specs
.into_iter()
.map(|x| (x.spec_id(), Arc::new(x))),
);
let default_spec_id = value.default_spec_id;
let default_spec: PartitionSpecRef = partition_specs
.get(&value.default_spec_id)
.map(|spec| (**spec).clone())
.or_else(|| {
(DEFAULT_PARTITION_SPEC_ID == default_spec_id)
.then(PartitionSpec::unpartition_spec)
})
.ok_or_else(|| {
Error::new(
ErrorKind::DataInvalid,
format!("Default partition spec {default_spec_id} not found"),
)
})?
.into();
let default_partition_type = default_spec.partition_type(current_schema)?;
let mut metadata = TableMetadata {
format_version: FormatVersion::V2,
table_uuid: value.table_uuid,
location: value.location,
last_sequence_number: value.last_sequence_number,
last_updated_ms: value.last_updated_ms,
last_column_id: value.last_column_id,
current_schema_id: value.current_schema_id,
schemas,
partition_specs,
default_partition_type,
default_spec,
last_partition_id: value.last_partition_id,
properties: value.properties.unwrap_or_default(),
current_snapshot_id,
snapshots: value
.snapshots
.map(|snapshots| {
HashMap::from_iter(
snapshots
.into_iter()
.map(|x| (x.snapshot_id, Arc::new(x.into()))),
)
})
.unwrap_or_default(),
snapshot_log: value.snapshot_log.unwrap_or_default(),
metadata_log: value.metadata_log.unwrap_or_default(),
sort_orders: HashMap::from_iter(
value
.sort_orders
.into_iter()
.map(|x| (x.order_id, Arc::new(x))),
),
default_sort_order_id: value.default_sort_order_id,
refs: value.refs.unwrap_or_else(|| {
if let Some(snapshot_id) = current_snapshot_id {
HashMap::from_iter(vec![(MAIN_BRANCH.to_string(), SnapshotReference {
snapshot_id,
retention: SnapshotRetention::Branch {
min_snapshots_to_keep: None,
max_snapshot_age_ms: None,
max_ref_age_ms: None,
},
})])
} else {
HashMap::new()
}
}),
statistics: index_statistics(value.statistics),
partition_statistics: index_partition_statistics(value.partition_statistics),
};
metadata.borrow_mut().try_normalize()?;
Ok(metadata)
}