jerryshao commented on code in PR #8902:
URL: https://github.com/apache/gravitino/pull/8902#discussion_r2459704700
##########
lance/lance-common/src/main/java/org/apache/gravitino/lance/common/ops/gravitino/GravitinoLanceNamespaceWrapper.java:
##########
@@ -136,39 +148,312 @@ public ListNamespacesResponse listNamespaces(
}
@Override
- public DescribeNamespaceResponse describeNamespace(String id, String
delimiter) {
- throw new UnsupportedOperationException("Not implemented yet");
+ public DescribeNamespaceResponse describeNamespace(String namespaceId,
String delimiter) {
+ ObjectIdentifier nsId = ObjectIdentifier.of(namespaceId, delimiter);
+ Preconditions.checkArgument(
+ nsId.levels() <= 2 && nsId.levels() > 0,
+ "Expected at most 2-level and at least 1-level namespace but got: %s",
+ namespaceId);
+
+ Catalog catalog = loadAndValidateLakehouseCatalog(nsId.levelAtListPos(0));
+ Map<String, String> properties = Maps.newHashMap();
+
+ switch (nsId.levels()) {
+ case 1:
+
Optional.ofNullable(catalog.properties()).ifPresent(properties::putAll);
+ break;
+ case 2:
+ String schemaName = nsId.levelAtListPos(1);
+ Schema schema = catalog.asSchemas().loadSchema(schemaName);
+ Optional.ofNullable(schema.properties()).ifPresent(properties::putAll);
+ break;
+ default:
+ throw new IllegalArgumentException(
+ "Expected at most 2-level and at least 1-level namespace but got:
" + namespaceId);
+ }
+
+ DescribeNamespaceResponse response = new DescribeNamespaceResponse();
+ response.setProperties(properties);
+ return response;
}
@Override
public CreateNamespaceResponse createNamespace(
- String id,
+ String namespaceId,
String delimiter,
CreateNamespaceRequest.ModeEnum mode,
Map<String, String> properties) {
- throw new UnsupportedOperationException("Not implemented yet");
+ ObjectIdentifier nsId = ObjectIdentifier.of(namespaceId, delimiter);
+ Preconditions.checkArgument(
+ nsId.levels() <= 2 && nsId.levels() > 0,
+ "Expected at most 2-level and at least 1-level namespace but got: %s",
+ namespaceId);
+
+ switch (nsId.levels()) {
+ case 1:
+ return createOrUpdateCatalog(nsId.levelAtListPos(0), mode, properties);
+ case 2:
+ return createOrUpdateSchema(
+ nsId.levelAtListPos(0), nsId.levelAtListPos(1), mode, properties);
+ default:
+ throw new IllegalArgumentException(
+ "Expected at most 2-level and at least 1-level namespace but got:
" + namespaceId);
+ }
}
@Override
public DropNamespaceResponse dropNamespace(
- String id,
+ String namespaceId,
String delimiter,
DropNamespaceRequest.ModeEnum mode,
DropNamespaceRequest.BehaviorEnum behavior) {
- throw new UnsupportedOperationException("Not implemented yet");
+ ObjectIdentifier nsId = ObjectIdentifier.of(namespaceId, delimiter);
+ Preconditions.checkArgument(
+ nsId.levels() <= 2 && nsId.levels() > 0,
+ "Expected at most 2-level and at least 1-level namespace but got: %s",
+ namespaceId);
+
+ switch (nsId.levels()) {
+ case 1:
+ return dropCatalog(nsId.levelAtListPos(0), mode, behavior);
+ case 2:
+ return dropSchema(nsId.levelAtListPos(0), nsId.levelAtListPos(1),
mode, behavior);
+ default:
+ throw new IllegalArgumentException(
+ "Expected at most 2-level and at least 1-level namespace but got:
" + namespaceId);
+ }
}
@Override
- public void namespaceExists(String id, String delimiter) throws
LanceNamespaceException {}
+ public void namespaceExists(String namespaceId, String delimiter) throws
LanceNamespaceException {
+ ObjectIdentifier nsId = ObjectIdentifier.of(namespaceId, delimiter);
+ Preconditions.checkArgument(
+ nsId.levels() <= 2 && nsId.levels() > 0,
+ "Expected at most 2-level and at least 1-level namespace but got: %s",
+ namespaceId);
- private boolean isLakehouseCatalog(Catalog catalog) {
- return catalog.type().equals(Catalog.Type.RELATIONAL)
- && "generic-lakehouse".equals(catalog.provider());
+ Catalog catalog = loadAndValidateLakehouseCatalog(nsId.levelAtListPos(0));
+ if (nsId.levels() == 2) {
+ String schemaName = nsId.levelAtListPos(1);
+ if (!catalog.asSchemas().schemaExists(schemaName)) {
+ throw LanceNamespaceException.notFound(
+ "Schema not found: " + schemaName,
+ NoSuchSchemaException.class.getSimpleName(),
+ schemaName,
+ CommonUtil.formatCurrentStackTrace());
+ }
+ }
}
@Override
public ListTablesResponse listTables(
String id, String delimiter, String pageToken, Integer limit) {
throw new UnsupportedOperationException("Not implemented yet");
}
+
+ private boolean isLakehouseCatalog(Catalog catalog) {
+ return catalog.type().equals(Catalog.Type.RELATIONAL)
+ && "generic-lakehouse".equals(catalog.provider());
+ }
+
+ private Catalog loadAndValidateLakehouseCatalog(String catalogName) {
+ Catalog catalog;
+ try {
+ catalog = client.loadCatalog(catalogName);
+ } catch (NoSuchCatalogException e) {
+ throw LanceNamespaceException.notFound(
+ "Catalog not found: " + catalogName,
+ NoSuchCatalogException.class.getSimpleName(),
+ catalogName,
+ CommonUtil.formatCurrentStackTrace());
+ }
+ if (!isLakehouseCatalog(catalog)) {
+ throw LanceNamespaceException.notFound(
+ "Catalog not found: " + catalogName,
+ NoSuchCatalogException.class.getSimpleName(),
+ catalogName,
+ CommonUtil.formatCurrentStackTrace());
+ }
+ return catalog;
+ }
+
+ private CreateNamespaceResponse createOrUpdateCatalog(
+ String catalogName, CreateNamespaceRequest.ModeEnum mode, Map<String,
String> properties) {
+ CreateNamespaceResponse response = new CreateNamespaceResponse();
+
+ Catalog catalog;
+ try {
+ catalog = client.loadCatalog(catalogName);
+ } catch (NoSuchCatalogException e) {
+ // Catalog does not exist, create it
+ Catalog createdCatalog =
+ client.createCatalog(
+ catalogName,
+ Catalog.Type.RELATIONAL,
+ "generic-lakehouse",
+ "created by Lance REST server",
+ properties);
+ response.setProperties(
+ createdCatalog.properties() == null ? Maps.newHashMap() :
createdCatalog.properties());
+ return response;
+ }
+
+ // Catalog exists, handle based on mode
+ switch (mode) {
+ case EXIST_OK:
+ response.setProperties(Maps.newHashMap());
+ return response;
+ case CREATE:
+ throw LanceNamespaceException.conflict(
+ "Catalog already exists: " + catalogName,
+ CatalogAlreadyExistsException.class.getSimpleName(),
+ catalogName,
+ CommonUtil.formatCurrentStackTrace());
+ case OVERWRITE:
+ CatalogChange[] changes =
+ buildChanges(
+ properties,
+ catalog.properties(),
+ CatalogChange::setProperty,
+ CatalogChange::removeProperty,
+ CatalogChange[]::new);
+ Catalog alteredCatalog = client.alterCatalog(catalogName, changes);
+
Optional.ofNullable(alteredCatalog.properties()).ifPresent(response::setProperties);
+ return response;
+ default:
+ throw new IllegalArgumentException("Unknown mode: " + mode);
+ }
+ }
+
+ private CreateNamespaceResponse createOrUpdateSchema(
+ String catalogName,
+ String schemaName,
+ CreateNamespaceRequest.ModeEnum mode,
+ Map<String, String> properties) {
+ CreateNamespaceResponse response = new CreateNamespaceResponse();
+ Catalog loadedCatalog = loadAndValidateLakehouseCatalog(catalogName);
+
+ try {
+ Schema schema = loadedCatalog.asSchemas().loadSchema(schemaName);
+ // Schema exists, handle based on mode
+ switch (mode) {
+ case EXIST_OK:
+ response.setProperties(Maps.newHashMap());
+ return response;
+ case CREATE:
+ throw LanceNamespaceException.conflict(
+ "Schema already exists: " + schemaName,
+ SchemaAlreadyExistsException.class.getSimpleName(),
+ schemaName,
+ CommonUtil.formatCurrentStackTrace());
+ case OVERWRITE:
+ SchemaChange[] changes =
+ buildChanges(
+ properties,
+ schema.properties(),
+ SchemaChange::setProperty,
+ SchemaChange::removeProperty,
+ SchemaChange[]::new);
+ Schema alteredSchema =
loadedCatalog.asSchemas().alterSchema(schemaName, changes);
+
Optional.ofNullable(alteredSchema.properties()).ifPresent(response::setProperties);
+ return response;
+ default:
+ throw new IllegalArgumentException("Unknown mode: " + mode);
+ }
+ } catch (NoSuchSchemaException e) {
Review Comment:
We'd also change the code structure like above for catalog.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]