Skip to content

Commit fa6caa9

Browse files
Li0kxxchan
authored andcommitted
feat: support remove schemas (#20)
1 parent d6faf63 commit fa6caa9

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

crates/iceberg/src/catalog/mod.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,12 @@ pub enum TableUpdate {
482482
/// Snapshot id to remove partition statistics for.
483483
snapshot_id: i64,
484484
},
485+
/// Remove schemas
486+
#[serde(rename_all = "kebab-case")]
487+
RemoveSchemas {
488+
/// Schema IDs to remove.
489+
schema_ids: Vec<i32>,
490+
},
485491
}
486492

487493
impl TableUpdate {
@@ -525,6 +531,7 @@ impl TableUpdate {
525531
TableUpdate::RemovePartitionStatistics { snapshot_id } => {
526532
Ok(builder.remove_partition_statistics(snapshot_id))
527533
}
534+
TableUpdate::RemoveSchemas { schema_ids } => builder.remove_schemas(&schema_ids),
528535
}
529536
}
530537
}
@@ -2047,4 +2054,19 @@ mod tests {
20472054
},
20482055
)
20492056
}
2057+
2058+
#[test]
2059+
fn test_remove_schema_update() {
2060+
test_serde_json(
2061+
r#"
2062+
{
2063+
"action": "remove-schemas",
2064+
"schema-ids": [1, 2]
2065+
}
2066+
"#,
2067+
TableUpdate::RemoveSchemas {
2068+
schema_ids: vec![1, 2],
2069+
},
2070+
);
2071+
}
20502072
}

crates/iceberg/src/spec/table_metadata_builder.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,35 @@ impl TableMetadataBuilder {
12101210
fn highest_sort_order_id(&self) -> Option<i64> {
12111211
self.metadata.sort_orders.keys().max().copied()
12121212
}
1213+
1214+
/// Remove schemas by their ids from the table metadata.
1215+
/// Does nothing if a schema id is not present. Active schemas should not be removed.
1216+
pub fn remove_schemas(mut self, schema_id_to_remove: &[i32]) -> Result<Self> {
1217+
if schema_id_to_remove.contains(&self.metadata.current_schema_id) {
1218+
return Err(Error::new(
1219+
ErrorKind::DataInvalid,
1220+
"Cannot remove current schema",
1221+
));
1222+
}
1223+
1224+
if !schema_id_to_remove.is_empty() {
1225+
let mut removed_schemas = Vec::with_capacity(schema_id_to_remove.len());
1226+
self.metadata.schemas.retain(|id, _schema| {
1227+
if schema_id_to_remove.contains(id) {
1228+
removed_schemas.push(*id);
1229+
false
1230+
} else {
1231+
true
1232+
}
1233+
});
1234+
1235+
self.changes.push(TableUpdate::RemoveSchemas {
1236+
schema_ids: removed_schemas,
1237+
});
1238+
}
1239+
1240+
Ok(self)
1241+
}
12131242
}
12141243

12151244
impl From<TableMetadataBuildResult> for TableMetadata {
@@ -2412,4 +2441,10 @@ mod tests {
24122441
table.metadata().current_snapshot_id().unwrap()
24132442
);
24142443
}
2444+
2445+
#[test]
2446+
fn test_active_schema_cannot_be_removed() {
2447+
let builder = builder_without_changes(FormatVersion::V2);
2448+
builder.remove_schemas(&[0]).unwrap_err();
2449+
}
24152450
}

0 commit comments

Comments
 (0)