diff --git a/crates/catalog/glue/src/catalog.rs b/crates/catalog/glue/src/catalog.rs
index fb4bd36b8d..f47d1d54ca 100644
--- a/crates/catalog/glue/src/catalog.rs
+++ b/crates/catalog/glue/src/catalog.rs
@@ -624,15 +624,75 @@ impl Catalog for GlueCatalog {
}
}
+ /// Asynchronously registers an existing table into the Glue Catalog.
+ ///
+ /// Converts the provided table identifier and metadata location into a
+ /// Glue-compatible table representation, and attempts to create the
+ /// corresponding table in the Glue Catalog.
+ ///
+ /// # Returns
+ /// Returns `Ok(Table)` if the table is successfully registered and loaded.
+ /// If the registration fails due to validation issues, existing table conflicts,
+ /// metadata problems, or errors during the registration or loading process,
+ /// an `Err(...)` is returned.
async fn register_table(
&self,
- _table_ident: &TableIdent,
- _metadata_location: String,
+ table: &TableIdent,
+ metadata_location: String,
) -> Result
{
- Err(Error::new(
- ErrorKind::FeatureUnsupported,
- "Registering a table is not supported yet",
- ))
+ let db_name = validate_namespace(table.namespace())?;
+ let table_name = table.name();
+
+ let metadata = TableMetadata::read_from(&self.file_io, &metadata_location).await?;
+
+ let table_input = convert_to_glue_table(
+ table_name,
+ metadata_location.clone(),
+ &metadata,
+ metadata.properties(),
+ None,
+ )?;
+
+ let builder = self
+ .client
+ .0
+ .create_table()
+ .database_name(&db_name)
+ .table_input(table_input);
+ let builder = with_catalog_id!(builder, self.config);
+
+ let result = builder.send().await;
+
+ match result {
+ Ok(_) => {
+ self.load_table(table).await.map_err(|e| {
+ Error::new(
+ ErrorKind::Unexpected,
+ format!(
+ "Table {}.{} created but failed to load: {e}",
+ db_name, table_name
+ ),
+ )
+ })
+ }
+ Err(err) => {
+ let service_err = err.as_service_error();
+
+ if service_err.map(|e| e.is_entity_not_found_exception()) == Some(true) {
+ Err(Error::new(
+ ErrorKind::NamespaceNotFound,
+ format!("Database {} does not exist", db_name),
+ ))
+ } else if service_err.map(|e| e.is_already_exists_exception()) == Some(true) {
+ Err(Error::new(
+ ErrorKind::TableAlreadyExists,
+ format!("Table {}.{} already exists", db_name, table_name),
+ ))
+ } else {
+ Err(from_aws_sdk_error(err))
+ }
+ }
+ }
}
async fn update_table(&self, _commit: TableCommit) -> Result {
diff --git a/crates/catalog/glue/tests/glue_catalog_test.rs b/crates/catalog/glue/tests/glue_catalog_test.rs
index bec9494fe9..60a998d010 100644
--- a/crates/catalog/glue/tests/glue_catalog_test.rs
+++ b/crates/catalog/glue/tests/glue_catalog_test.rs
@@ -367,3 +367,32 @@ async fn test_list_namespace() -> Result<()> {
Ok(())
}
+
+#[tokio::test]
+async fn test_register_table() -> Result<()> {
+ let catalog = get_catalog().await;
+ let namespace = NamespaceIdent::new("test_register_table".into());
+ set_test_namespace(&catalog, &namespace).await?;
+
+ let creation = set_table_creation(Some("s3a://warehouse/hive/test_register_table".into()), "my_table")?;
+ let table = catalog.create_table(&namespace, creation).await?;
+ let metadata_location = table
+ .metadata_location()
+ .expect("Expected metadata location to be set")
+ .to_string();
+
+ catalog.drop_table(table.identifier()).await?;
+ let ident = TableIdent::new(namespace.clone(), "my_table".to_string());
+
+ let registered = catalog
+ .register_table(&ident, metadata_location.clone())
+ .await?;
+
+ assert_eq!(registered.identifier(), &ident);
+ assert_eq!(
+ registered.metadata_location().as_deref(),
+ Some(metadata_location.as_str())
+ );
+
+ Ok(())
+}