-
Notifications
You must be signed in to change notification settings - Fork 3.4k
AWS: support force register table in GlueCatalog #6742
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
73ecc5d
4ac803c
3509f3a
3c25e64
8e5349b
043b8a6
4bdb165
b38a928
dd9fdc4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,6 +21,7 @@ | |
| import java.io.Closeable; | ||
| import java.io.IOException; | ||
| import java.util.List; | ||
| import java.util.Locale; | ||
| import java.util.Map; | ||
| import java.util.Set; | ||
| import java.util.stream.Collectors; | ||
|
|
@@ -78,6 +79,7 @@ | |
| import software.amazon.awssdk.services.glue.model.Table; | ||
| import software.amazon.awssdk.services.glue.model.TableInput; | ||
| import software.amazon.awssdk.services.glue.model.UpdateDatabaseRequest; | ||
| import software.amazon.awssdk.services.glue.model.UpdateTableRequest; | ||
|
|
||
| public class GlueCatalog extends BaseMetastoreCatalog | ||
| implements Closeable, SupportsNamespaces, Configurable<Configuration> { | ||
|
|
@@ -437,6 +439,44 @@ public void renameTable(TableIdentifier from, TableIdentifier to) { | |
| LOG.info("Successfully renamed table from {} to {}", from, to); | ||
| } | ||
|
|
||
| @Override | ||
| public org.apache.iceberg.Table registerTable(TableIdentifier identifier, String metadataFileLocation) { | ||
| Preconditions.checkArgument(isValidIdentifier(identifier), | ||
| "Table identifier to register is invalid: " + identifier); | ||
| Preconditions.checkArgument(metadataFileLocation != null && !metadataFileLocation.isEmpty(), | ||
| "Cannot register an empty metadata file location as a table"); | ||
|
|
||
| Map<String, String> tableParameters = ImmutableMap.of( | ||
| BaseMetastoreTableOperations.TABLE_TYPE_PROP, | ||
| BaseMetastoreTableOperations.ICEBERG_TABLE_TYPE_VALUE.toLowerCase(Locale.ENGLISH), | ||
| BaseMetastoreTableOperations.METADATA_LOCATION_PROP, | ||
| metadataFileLocation); | ||
|
|
||
| TableInput tableInput = TableInput.builder() | ||
| .name(IcebergToGlueConverter.getTableName(identifier, awsProperties.glueCatalogSkipNameValidation())) | ||
| .tableType(GlueTableOperations.GLUE_EXTERNAL_TABLE_TYPE) | ||
| .parameters(tableParameters) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think here we need to still get the metadata and use the IcebergToGlueConverter to get the merged schema for display. |
||
| .build(); | ||
|
|
||
| try { | ||
| glue.createTable(CreateTableRequest.builder() | ||
| .databaseName(IcebergToGlueConverter.getDatabaseName(identifier, | ||
| awsProperties.glueCatalogSkipNameValidation())) | ||
| .tableInput(tableInput) | ||
| .build()); | ||
| } catch (software.amazon.awssdk.services.glue.model.AlreadyExistsException e) { | ||
| glue.updateTable(UpdateTableRequest.builder() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similarly, I think we should at least make this a feature flag like We could further argue if we should make this an API feature or not, but that is subject to debate. Any thoughts? |
||
| .databaseName(IcebergToGlueConverter.getDatabaseName(identifier, | ||
| awsProperties.glueCatalogSkipNameValidation())) | ||
| .tableInput(tableInput) | ||
| .build()); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should first get the last table version to avoid commit conflict
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think glue catalog already handle this internally? If we call glue.getTable to get the table version first then call glue.updateTable with nextVersionId it will cause concurrentModificationException.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes this is what I mean. It needs to explicitly pass in the version number of the current version to ensure atomic update.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ack, will update |
||
| } catch (EntityNotFoundException e) { | ||
|
Comment on lines
+471
to
+514
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this logic is a combination of a fork of the logic in If the concern is the creation of an extra metadata file, it looks like |
||
| throw new NoSuchNamespaceException(e, "Namespace %s is not found in Glue", identifier.namespace()); | ||
| } | ||
|
|
||
| return loadTable(identifier); | ||
| } | ||
|
|
||
| @Override | ||
| public void createNamespace(Namespace namespace, Map<String, String> metadata) { | ||
| try { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we might want to have a feature flag like
glue.register-table.create-new-metadata(for the lack of a better name) inAwsPropertiesto distinguish 2 behaviors, to either create a new metadata file or not. If the flag is true (by default), it can call the base class method directly.