diff --git a/core/src/main/java/org/apache/iceberg/rest/RESTSessionCatalog.java b/core/src/main/java/org/apache/iceberg/rest/RESTSessionCatalog.java index 13baec98fd8b..6a53bb984ad7 100644 --- a/core/src/main/java/org/apache/iceberg/rest/RESTSessionCatalog.java +++ b/core/src/main/java/org/apache/iceberg/rest/RESTSessionCatalog.java @@ -176,6 +176,8 @@ public void setConf(Configuration newConf) { @Override public List listTables(SessionContext context, Namespace ns) { + checkNamespaceIsValid(ns); + ListTablesResponse response = client.get( paths.tables(ns), ListTablesResponse.class, headers(context), ErrorHandlers.namespaceErrorHandler()); return response.identifiers(); @@ -183,6 +185,8 @@ public List listTables(SessionContext context, Namespace ns) { @Override public boolean dropTable(SessionContext context, TableIdentifier identifier) { + checkIdentifierIsValid(identifier); + try { client.delete(paths.table(identifier), null, headers(context), ErrorHandlers.tableErrorHandler()); return true; @@ -198,6 +202,9 @@ public boolean purgeTable(SessionContext context, TableIdentifier ident) { @Override public void renameTable(SessionContext context, TableIdentifier from, TableIdentifier to) { + checkIdentifierIsValid(from); + checkIdentifierIsValid(to); + RenameTableRequest request = RenameTableRequest.builder() .withSource(from) .withDestination(to) @@ -214,6 +221,8 @@ private LoadTableResponse loadInternal(SessionContext context, TableIdentifier i @Override public Table loadTable(SessionContext context, TableIdentifier identifier) { + checkIdentifierIsValid(identifier); + MetadataTableType metadataType; LoadTableResponse response; try { @@ -295,6 +304,8 @@ public List listNamespaces(SessionContext context, Namespace namespac @Override public Map loadNamespaceMetadata(SessionContext context, Namespace ns) { + checkNamespaceIsValid(ns); + // TODO: rename to LoadNamespaceResponse? GetNamespaceResponse response = client .get(paths.namespace(ns), GetNamespaceResponse.class, headers(context), ErrorHandlers.namespaceErrorHandler()); @@ -303,6 +314,8 @@ public Map loadNamespaceMetadata(SessionContext context, Namespa @Override public boolean dropNamespace(SessionContext context, Namespace ns) { + checkNamespaceIsValid(ns); + try { client.delete(paths.namespace(ns), null, headers(context), ErrorHandlers.namespaceErrorHandler()); return true; @@ -314,6 +327,8 @@ public boolean dropNamespace(SessionContext context, Namespace ns) { @Override public boolean updateNamespaceMetadata(SessionContext context, Namespace ns, Map updates, Set removals) { + checkNamespaceIsValid(ns); + UpdateNamespacePropertiesRequest request = UpdateNamespacePropertiesRequest.builder() .updateAll(updates) .removeAll(removals) @@ -404,6 +419,8 @@ private class Builder implements Catalog.TableBuilder { private String location = null; private Builder(TableIdentifier ident, Schema schema, SessionContext context) { + checkIdentifierIsValid(ident); + this.ident = ident; this.schema = schema; this.context = context; @@ -678,6 +695,18 @@ private Long expiresInMs(Map properties) { } } + private void checkIdentifierIsValid(TableIdentifier tableIdentifier) { + if (tableIdentifier.namespace().isEmpty()) { + throw new NoSuchTableException("Invalid table identifier: %s", tableIdentifier); + } + } + + private void checkNamespaceIsValid(Namespace namespace) { + if (namespace.isEmpty()) { + throw new NoSuchNamespaceException("Invalid namespace: %s", namespace); + } + } + private static Map configHeaders(Map properties) { return RESTUtil.extractPrefixMap(properties, "header."); }