Skip to content

Commit 94bed60

Browse files
authored
feat(catalog): Implement register_table for glue catalog (#1568)
## Which issue does this PR close? - Closes #1515. ## What changes are included in this PR? * implemented the register_table method in the Glue catalog. * added an integration test to cover table registration via metadata location. ## Are these changes tested? Yes * cargo build * cargo test (including new test case for register_table) I'm new to Rust and to Iceberg, any feedback or suggestions for improvement are very welcome! 😊
1 parent 4aacad7 commit 94bed60

File tree

2 files changed

+91
-6
lines changed

2 files changed

+91
-6
lines changed

crates/catalog/glue/src/catalog.rs

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use std::fmt::Debug;
2020

2121
use anyhow::anyhow;
2222
use async_trait::async_trait;
23+
use aws_sdk_glue::operation::create_table::CreateTableError;
2324
use aws_sdk_glue::operation::update_table::UpdateTableError;
2425
use aws_sdk_glue::types::TableInput;
2526
use iceberg::io::{
@@ -700,15 +701,67 @@ impl Catalog for GlueCatalog {
700701
}
701702
}
702703

704+
/// registers an existing table into the Glue Catalog.
705+
///
706+
/// Converts the provided table identifier and metadata location into a
707+
/// Glue-compatible table representation, and attempts to create the
708+
/// corresponding table in the Glue Catalog.
709+
///
710+
/// # Returns
711+
/// Returns `Ok(Table)` if the table is successfully registered and loaded.
712+
/// If the registration fails due to validation issues, existing table conflicts,
713+
/// metadata problems, or errors during the registration or loading process,
714+
/// an `Err(...)` is returned.
703715
async fn register_table(
704716
&self,
705-
_table_ident: &TableIdent,
706-
_metadata_location: String,
717+
table_ident: &TableIdent,
718+
metadata_location: String,
707719
) -> Result<Table> {
708-
Err(Error::new(
709-
ErrorKind::FeatureUnsupported,
710-
"Registering a table is not supported yet",
711-
))
720+
let db_name = validate_namespace(table_ident.namespace())?;
721+
let table_name = table_ident.name();
722+
let metadata = TableMetadata::read_from(&self.file_io, &metadata_location).await?;
723+
724+
let table_input = convert_to_glue_table(
725+
table_name,
726+
metadata_location.clone(),
727+
&metadata,
728+
metadata.properties(),
729+
None,
730+
)?;
731+
732+
let builder = self
733+
.client
734+
.0
735+
.create_table()
736+
.database_name(&db_name)
737+
.table_input(table_input);
738+
let builder = with_catalog_id!(builder, self.config);
739+
740+
builder.send().await.map_err(|e| {
741+
let error = e.into_service_error();
742+
match error {
743+
CreateTableError::EntityNotFoundException(_) => Error::new(
744+
ErrorKind::NamespaceNotFound,
745+
format!("Database {db_name} does not exist"),
746+
),
747+
CreateTableError::AlreadyExistsException(_) => Error::new(
748+
ErrorKind::TableAlreadyExists,
749+
format!("Table {table_ident} already exists"),
750+
),
751+
_ => Error::new(
752+
ErrorKind::Unexpected,
753+
format!("Failed to register table {table_ident} due to AWS SDK error"),
754+
),
755+
}
756+
.with_source(anyhow!("aws sdk error: {:?}", error))
757+
})?;
758+
759+
Ok(Table::builder()
760+
.identifier(table_ident.clone())
761+
.metadata_location(metadata_location)
762+
.metadata(metadata)
763+
.file_io(self.file_io())
764+
.build()?)
712765
}
713766

714767
async fn update_table(&self, commit: TableCommit) -> Result<Table> {

crates/catalog/glue/tests/glue_catalog_test.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,3 +469,35 @@ async fn test_update_table() -> Result<()> {
469469

470470
Ok(())
471471
}
472+
473+
#[tokio::test]
474+
async fn test_register_table() -> Result<()> {
475+
let catalog = get_catalog().await;
476+
let namespace = NamespaceIdent::new("test_register_table".into());
477+
set_test_namespace(&catalog, &namespace).await?;
478+
479+
let creation = set_table_creation(
480+
Some("s3a://warehouse/hive/test_register_table".into()),
481+
"my_table",
482+
)?;
483+
let table = catalog.create_table(&namespace, creation).await?;
484+
let metadata_location = table
485+
.metadata_location()
486+
.expect("Expected metadata location to be set")
487+
.to_string();
488+
489+
catalog.drop_table(table.identifier()).await?;
490+
let ident = TableIdent::new(namespace.clone(), "my_table".to_string());
491+
492+
let registered = catalog
493+
.register_table(&ident, metadata_location.clone())
494+
.await?;
495+
496+
assert_eq!(registered.identifier(), &ident);
497+
assert_eq!(
498+
registered.metadata_location(),
499+
Some(metadata_location.as_str())
500+
);
501+
502+
Ok(())
503+
}

0 commit comments

Comments
 (0)