From 4f775a633c93c387eebcbf1513e50a2abfa26c32 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Thu, 20 Mar 2025 13:18:34 -0700 Subject: [PATCH 01/19] add missing apis --- .../catalog/generic/GenericTableCatalog.java | 58 ++++++++++++++++++- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java index 86c4f0bbfe..5b3cd690fc 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java @@ -19,21 +19,35 @@ package org.apache.polaris.service.catalog.generic; import jakarta.ws.rs.core.SecurityContext; + +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; + +import org.apache.iceberg.CatalogProperties; +import org.apache.iceberg.TableMetadata; +import org.apache.iceberg.TableOperations; +import org.apache.iceberg.catalog.Namespace; import org.apache.iceberg.catalog.TableIdentifier; import org.apache.iceberg.exceptions.AlreadyExistsException; +import org.apache.iceberg.exceptions.BadRequestException; +import org.apache.iceberg.exceptions.ForbiddenException; import org.apache.iceberg.exceptions.NoSuchTableException; +import org.apache.polaris.core.catalog.PolarisCatalogHelpers; +import org.apache.polaris.core.config.FeatureConfiguration; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.CatalogEntity; import org.apache.polaris.core.entity.GenericTableEntity; import org.apache.polaris.core.entity.PolarisEntity; import org.apache.polaris.core.entity.PolarisEntitySubType; import org.apache.polaris.core.entity.PolarisEntityType; +import org.apache.polaris.core.entity.PolarisTaskConstants; import org.apache.polaris.core.persistence.PolarisEntityManager; import org.apache.polaris.core.persistence.PolarisMetaStoreManager; import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; import org.apache.polaris.core.persistence.dao.entity.BaseResult; +import org.apache.polaris.core.persistence.dao.entity.DropEntityResult; import org.apache.polaris.core.persistence.dao.entity.EntityResult; import org.apache.polaris.core.persistence.resolver.PolarisResolutionManifestCatalogView; import org.apache.polaris.service.catalog.io.FileIOFactory; @@ -97,7 +111,6 @@ public void createGenericTable( List catalogPath = resolvedParent.getRawFullPath(); - // TODO we need to filter by type here? PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( tableIdentifier, PolarisEntityType.GENERIC_TABLE, PolarisEntitySubType.ANY_SUBTYPE); @@ -146,7 +159,6 @@ public void createGenericTable( } public GenericTableEntity loadGenericTable(TableIdentifier tableIdentifier) { - // TODO we need to filter by type here? PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( tableIdentifier, PolarisEntityType.GENERIC_TABLE, PolarisEntitySubType.ANY_SUBTYPE); @@ -159,4 +171,46 @@ public GenericTableEntity loadGenericTable(TableIdentifier tableIdentifier) { return entity; } } + + public boolean dropGenericTable(TableIdentifier tableIdentifier) { + PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( + tableIdentifier, PolarisEntityType.GENERIC_TABLE, PolarisEntitySubType.ANY_SUBTYPE); + + List catalogPath = resolvedEntities.getRawParentPath(); + PolarisEntity leafEntity = resolvedEntities.getRawLeafEntity(); + + DropEntityResult dropEntityResult = this.metaStoreManager + .dropEntityIfExists( + this.callContext.getPolarisCallContext(), + PolarisEntity.toCoreList(catalogPath), + leafEntity, + Map.of(), + false); + + if (!dropEntityResult.isSuccess()) { + if (dropEntityResult.failedBecauseNotEmpty()) { + throw new IllegalStateException("Cannot drop entity because it has children"); + } else { + throw new BadRequestException("Failed to drop " + tableIdentifier.toString()); + } + } + return true; + } + + public List listGenericTables(Namespace namespace) { + PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getResolvedPath(namespace); + + List catalogPath = resolvedEntities.getRawFullPath(); + List entities = + PolarisEntity.toNameAndIdList( + this.metaStoreManager + .listEntities( + this.callContext.getPolarisCallContext(), + PolarisEntity.toCoreList(catalogPath), + PolarisEntityType.GENERIC_TABLE, + PolarisEntitySubType.ANY_SUBTYPE) + .getEntities()); + return PolarisCatalogHelpers.nameAndIdToTableIdentifiers(catalogPath, entities); + + } } From e2fcd5e5eb26f0983ddf99a2f4a966e4f6c1bc1e Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Thu, 20 Mar 2025 20:55:01 -0700 Subject: [PATCH 02/19] more tests, fixes --- .../catalog/GenericTableCatalogTest.java | 200 +++++++++++++++++- .../catalog/generic/GenericTableCatalog.java | 26 +-- 2 files changed, 206 insertions(+), 20 deletions(-) diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java index 57d49226c4..e1161694f8 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java @@ -18,12 +18,15 @@ */ package org.apache.polaris.service.quarkus.catalog; +import static org.apache.iceberg.types.Types.NestedField.required; import static org.mockito.ArgumentMatchers.isA; import static org.mockito.Mockito.when; +import com.google.common.collect.ImmutableMap; import io.quarkus.test.junit.QuarkusMock; import io.quarkus.test.junit.QuarkusTest; import io.quarkus.test.junit.QuarkusTestProfile; +import io.quarkus.test.junit.TestProfile; import jakarta.inject.Inject; import jakarta.ws.rs.core.SecurityContext; import java.io.IOException; @@ -34,8 +37,11 @@ import java.util.Set; import java.util.function.Supplier; import org.apache.commons.lang3.NotImplementedException; +import org.apache.iceberg.CatalogProperties; +import org.apache.iceberg.Schema; import org.apache.iceberg.catalog.Namespace; import org.apache.iceberg.catalog.TableIdentifier; +import org.apache.iceberg.types.Types; import org.apache.polaris.core.PolarisCallContext; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.admin.model.AwsStorageConfigInfo; @@ -52,7 +58,6 @@ import org.apache.polaris.core.entity.PolarisEntitySubType; import org.apache.polaris.core.entity.PolarisEntityType; import org.apache.polaris.core.entity.PrincipalEntity; -import org.apache.polaris.core.persistence.BasePersistence; import org.apache.polaris.core.persistence.MetaStoreManagerFactory; import org.apache.polaris.core.persistence.PolarisEntityManager; import org.apache.polaris.core.persistence.PolarisMetaStoreManager; @@ -60,6 +65,7 @@ import org.apache.polaris.core.persistence.cache.EntityCache; import org.apache.polaris.core.persistence.dao.entity.BaseResult; import org.apache.polaris.core.persistence.dao.entity.PrincipalSecretsResult; +import org.apache.polaris.core.persistence.transactional.TransactionalPersistence; import org.apache.polaris.core.storage.PolarisStorageIntegration; import org.apache.polaris.core.storage.PolarisStorageIntegrationProvider; import org.apache.polaris.core.storage.aws.AwsCredentialsStorageIntegration; @@ -69,7 +75,9 @@ import org.apache.polaris.service.catalog.PolarisPassthroughResolutionView; import org.apache.polaris.service.catalog.generic.GenericTableCatalog; import org.apache.polaris.service.catalog.iceberg.IcebergCatalog; +import org.apache.polaris.service.catalog.io.DefaultFileIOFactory; import org.apache.polaris.service.catalog.io.FileIOFactory; +import org.apache.polaris.service.config.RealmEntityManagerFactory; import org.apache.polaris.service.storage.PolarisStorageIntegrationProviderImpl; import org.apache.polaris.service.task.TaskExecutor; import org.assertj.core.api.Assertions; @@ -85,12 +93,20 @@ import software.amazon.awssdk.services.sts.model.Credentials; @QuarkusTest +@TestProfile(GenericTableCatalogTest.Profile.class) public class GenericTableCatalogTest { + public static class Profile implements QuarkusTestProfile { @Override public Map getConfigOverrides() { - return Map.of(); + return Map.of( + "polaris.features.defaults.\"ALLOW_SPECIFYING_FILE_IO_IMPL\"", + "true", + "polaris.features.defaults.\"INITIALIZE_DEFAULT_CATALOG_FILEIO_FOR_TEST\"", + "true", + "polaris.features.defaults.\"SUPPORTED_CATALOG_STORAGE_TYPES\"", + "[\"FILE\"]"); } } @@ -120,6 +136,11 @@ public Map getConfigOverrides() { private PolarisEntity catalogEntity; private SecurityContext securityContext; + protected static final Schema SCHEMA = + new Schema( + required(3, "id", Types.IntegerType.get(), "unique ID 🤪"), + required(4, "data", Types.StringType.get())); + @BeforeAll public static void setUpMocks() { PolarisStorageIntegrationProviderImpl mock = @@ -199,6 +220,10 @@ public void before(TestInfo testInfo) { new PolarisPassthroughResolutionView( callContext, entityManager, securityContext, CATALOG_NAME); TaskExecutor taskExecutor = Mockito.mock(); + RealmEntityManagerFactory realmEntityManagerFactory = + new RealmEntityManagerFactory(createMockMetaStoreManagerFactory()); + this.fileIOFactory = + new DefaultFileIOFactory(realmEntityManagerFactory, managerFactory, configurationStore); StsClient stsClient = Mockito.mock(StsClient.class); when(stsClient.assumeRole(isA(AssumeRoleRequest.class))) @@ -235,6 +260,10 @@ public void before(TestInfo testInfo) { securityContext, taskExecutor, fileIOFactory); + this.icebergCatalog.initialize( + CATALOG_NAME, + ImmutableMap.of( + CatalogProperties.FILE_IO_IMPL, "org.apache.iceberg.inmemory.InMemoryFileIO")); } @AfterEach @@ -250,8 +279,9 @@ public PolarisMetaStoreManager getOrCreateMetaStoreManager(RealmContext realmCon } @Override - public Supplier getOrCreateSessionSupplier(RealmContext realmContext) { - return () -> polarisContext.getMetaStore(); + public Supplier getOrCreateSessionSupplier( + RealmContext realmContext) { + return () -> ((TransactionalPersistence) polarisContext.getMetaStore()); } @Override @@ -306,4 +336,166 @@ public void testGenericTableRoundTrip() { Assertions.assertThat(resultEntity.getPropertiesAsMap()).isEqualTo(properties); Assertions.assertThat(resultEntity.getName()).isEqualTo(tableName); } + + @Test + public void testLoadNonExistentTable() { + Namespace namespace = Namespace.of("ns"); + icebergCatalog.createNamespace(namespace); + + Assertions.assertThatCode( + () -> genericTableCatalog.loadGenericTable(TableIdentifier.of("ns", "t1"))) + .hasMessageContaining("does not exist: ns.t1"); + } + + @Test + public void testReadIcebergTableAsGeneric() { + Namespace namespace = Namespace.of("ns"); + icebergCatalog.createNamespace(namespace); + + String tableName = "t1"; + + icebergCatalog.createTable(TableIdentifier.of("ns", tableName), SCHEMA); + Assertions.assertThatCode( + () -> genericTableCatalog.loadGenericTable(TableIdentifier.of("ns", tableName))) + .hasMessageContaining("does not exist: ns.t1"); + } + + @Test + public void testReadIcebergViewAsGeneric() { + Namespace namespace = Namespace.of("ns"); + icebergCatalog.createNamespace(namespace); + + String tableName = "t1"; + + icebergCatalog.buildView(TableIdentifier.of("ns", tableName)); + Assertions.assertThatCode( + () -> genericTableCatalog.loadGenericTable(TableIdentifier.of("ns", tableName))) + .hasMessageContaining("does not exist: ns.t1"); + } + + @Test + public void testReadGenericAsIcebergTable() { + Namespace namespace = Namespace.of("ns"); + icebergCatalog.createNamespace(namespace); + + String tableName = "t1"; + + genericTableCatalog.createGenericTable(TableIdentifier.of("ns", tableName), "format", Map.of()); + Assertions.assertThatCode(() -> icebergCatalog.loadTable(TableIdentifier.of("ns", tableName))) + .hasMessageContaining("does not exist: ns.t1"); + } + + @Test + public void testReadGenericAsIcebergView() { + Namespace namespace = Namespace.of("ns"); + icebergCatalog.createNamespace(namespace); + + String tableName = "t1"; + + genericTableCatalog.createGenericTable(TableIdentifier.of("ns", tableName), "format", Map.of()); + Assertions.assertThatCode(() -> icebergCatalog.loadView(TableIdentifier.of("ns", tableName))) + .hasMessageContaining("does not exist: ns.t1"); + } + + @Test + public void testListTables() { + Namespace namespace = Namespace.of("ns"); + icebergCatalog.createNamespace(namespace); + + for (int i = 0; i < 10; i++) { + genericTableCatalog.createGenericTable(TableIdentifier.of("ns", "t" + i), "format", Map.of()); + } + + List listResult = genericTableCatalog.listGenericTables(namespace); + + Assertions.assertThat(listResult.size()).isEqualTo(10); + Assertions.assertThat(listResult.stream().map(TableIdentifier::toString).toList()) + .isEqualTo(listResult.stream().map(TableIdentifier::toString).sorted().toList()); + + Assertions.assertThat(icebergCatalog.listTables(namespace)).isEmpty(); + } + + @Test + public void testListTablesEmpty() { + Namespace namespace = Namespace.of("ns"); + icebergCatalog.createNamespace(namespace); + + for (int i = 0; i < 10; i++) { + icebergCatalog.createTable(TableIdentifier.of("ns", "t" + i), SCHEMA); + } + + Assertions.assertThat(icebergCatalog.listTables(namespace).size()).isEqualTo(10); + Assertions.assertThat(genericTableCatalog.listGenericTables(namespace)).isEmpty(); + } + + @Test + public void testListIcebergTables() { + Namespace namespace = Namespace.of("ns"); + icebergCatalog.createNamespace(namespace); + + for (int i = 0; i < 10; i++) { + icebergCatalog.createTable(TableIdentifier.of("ns", "t" + i), SCHEMA); + } + + List listResult = icebergCatalog.listTables(namespace); + + Assertions.assertThat(listResult.size()).isEqualTo(10); + Assertions.assertThat(listResult.stream().map(TableIdentifier::toString).toList()) + .isEqualTo(listResult.stream().map(TableIdentifier::toString).sorted().toList()); + + Assertions.assertThat(genericTableCatalog.listGenericTables(namespace)).isEmpty(); + } + + @Test + public void testDropNonExistentTable() { + Namespace namespace = Namespace.of("ns"); + icebergCatalog.createNamespace(namespace); + + Assertions.assertThatCode( + () -> genericTableCatalog.dropGenericTable(TableIdentifier.of("ns", "t1"))) + .hasMessageContaining("Table does not exist: ns.t1"); + } + + @Test + public void testDropNonExistentNamespace() { + Namespace namespace = Namespace.of("ns"); + icebergCatalog.createNamespace(namespace); + + Assertions.assertThatCode( + () -> genericTableCatalog.dropGenericTable(TableIdentifier.of("ns2", "t1"))) + .hasMessageContaining("Table does not exist: ns2.t1"); + } + + @Test + public void testDropIcebergTable() { + Namespace namespace = Namespace.of("ns"); + icebergCatalog.createNamespace(namespace); + icebergCatalog.createTable(TableIdentifier.of("ns", "t1"), SCHEMA); + + Assertions.assertThatCode( + () -> genericTableCatalog.dropGenericTable(TableIdentifier.of("ns", "t1"))) + .hasMessageContaining("Table does not exist: ns.t1"); + } + + @Test + public void testDropViaIceberg() { + Namespace namespace = Namespace.of("ns"); + icebergCatalog.createNamespace(namespace); + genericTableCatalog.createGenericTable(TableIdentifier.of("ns", "t1"), "format", Map.of()); + + Assertions.assertThat(icebergCatalog.dropTable(TableIdentifier.of("ns", "t1"))).isFalse(); + Assertions.assertThat(genericTableCatalog.loadGenericTable(TableIdentifier.of("ns", "t1"))) + .isNotNull(); + } + + @Test + public void testDropViaIcebergView() { + Namespace namespace = Namespace.of("ns"); + icebergCatalog.createNamespace(namespace); + genericTableCatalog.createGenericTable(TableIdentifier.of("ns", "t1"), "format", Map.of()); + + Assertions.assertThat(icebergCatalog.dropView(TableIdentifier.of("ns", "t1"))).isFalse(); + Assertions.assertThat(genericTableCatalog.loadGenericTable(TableIdentifier.of("ns", "t1"))) + .isNotNull(); + } } diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java index 5b3cd690fc..bcfef6c0f5 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java @@ -19,30 +19,20 @@ package org.apache.polaris.service.catalog.generic; import jakarta.ws.rs.core.SecurityContext; - -import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; - -import org.apache.iceberg.CatalogProperties; -import org.apache.iceberg.TableMetadata; -import org.apache.iceberg.TableOperations; import org.apache.iceberg.catalog.Namespace; import org.apache.iceberg.catalog.TableIdentifier; import org.apache.iceberg.exceptions.AlreadyExistsException; import org.apache.iceberg.exceptions.BadRequestException; -import org.apache.iceberg.exceptions.ForbiddenException; import org.apache.iceberg.exceptions.NoSuchTableException; import org.apache.polaris.core.catalog.PolarisCatalogHelpers; -import org.apache.polaris.core.config.FeatureConfiguration; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.CatalogEntity; import org.apache.polaris.core.entity.GenericTableEntity; import org.apache.polaris.core.entity.PolarisEntity; import org.apache.polaris.core.entity.PolarisEntitySubType; import org.apache.polaris.core.entity.PolarisEntityType; -import org.apache.polaris.core.entity.PolarisTaskConstants; import org.apache.polaris.core.persistence.PolarisEntityManager; import org.apache.polaris.core.persistence.PolarisMetaStoreManager; import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; @@ -173,14 +163,19 @@ public GenericTableEntity loadGenericTable(TableIdentifier tableIdentifier) { } public boolean dropGenericTable(TableIdentifier tableIdentifier) { - PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntityType.GENERIC_TABLE, PolarisEntitySubType.ANY_SUBTYPE); + PolarisResolvedPathWrapper resolvedEntities = + resolvedEntityView.getPassthroughResolvedPath( + tableIdentifier, PolarisEntityType.GENERIC_TABLE, PolarisEntitySubType.ANY_SUBTYPE); + + if (resolvedEntities == null) { + throw new NoSuchTableException("Table does not exist: %s", tableIdentifier); + } List catalogPath = resolvedEntities.getRawParentPath(); PolarisEntity leafEntity = resolvedEntities.getRawLeafEntity(); - DropEntityResult dropEntityResult = this.metaStoreManager - .dropEntityIfExists( + DropEntityResult dropEntityResult = + this.metaStoreManager.dropEntityIfExists( this.callContext.getPolarisCallContext(), PolarisEntity.toCoreList(catalogPath), leafEntity, @@ -191,7 +186,7 @@ public boolean dropGenericTable(TableIdentifier tableIdentifier) { if (dropEntityResult.failedBecauseNotEmpty()) { throw new IllegalStateException("Cannot drop entity because it has children"); } else { - throw new BadRequestException("Failed to drop " + tableIdentifier.toString()); + throw new BadRequestException("Failed to drop"); } } return true; @@ -211,6 +206,5 @@ public List listGenericTables(Namespace namespace) { PolarisEntitySubType.ANY_SUBTYPE) .getEntities()); return PolarisCatalogHelpers.nameAndIdToTableIdentifiers(catalogPath, entities); - } } From 467ebcb43d87b7402302f6bf9fed1fab4336cf2f Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Fri, 21 Mar 2025 00:36:39 -0700 Subject: [PATCH 03/19] clean up drop --- .../service/catalog/generic/GenericTableCatalog.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java index bcfef6c0f5..378f15350c 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java @@ -162,6 +162,7 @@ public GenericTableEntity loadGenericTable(TableIdentifier tableIdentifier) { } } + @SuppressWarnings("FormatStringAnnotation") public boolean dropGenericTable(TableIdentifier tableIdentifier) { PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( @@ -182,14 +183,7 @@ public boolean dropGenericTable(TableIdentifier tableIdentifier) { Map.of(), false); - if (!dropEntityResult.isSuccess()) { - if (dropEntityResult.failedBecauseNotEmpty()) { - throw new IllegalStateException("Cannot drop entity because it has children"); - } else { - throw new BadRequestException("Failed to drop"); - } - } - return true; + return dropEntityResult.isSuccess(); } public List listGenericTables(Namespace namespace) { From 5f5ca424dd457e0d0f3fcb5c5f3549ee77eab694 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Fri, 21 Mar 2025 00:36:42 -0700 Subject: [PATCH 04/19] autolint --- .../polaris/service/catalog/generic/GenericTableCatalog.java | 1 - 1 file changed, 1 deletion(-) diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java index 378f15350c..8a5ad65f84 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java @@ -24,7 +24,6 @@ import org.apache.iceberg.catalog.Namespace; import org.apache.iceberg.catalog.TableIdentifier; import org.apache.iceberg.exceptions.AlreadyExistsException; -import org.apache.iceberg.exceptions.BadRequestException; import org.apache.iceberg.exceptions.NoSuchTableException; import org.apache.polaris.core.catalog.PolarisCatalogHelpers; import org.apache.polaris.core.context.CallContext; From 34c8e967c1bbc3b0a4ccb6a160442f3998ad2c79 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Mon, 24 Mar 2025 10:13:46 -0700 Subject: [PATCH 05/19] changes per review --- .../quarkus/catalog/GenericTableCatalogTest.java | 14 +++++++++++--- .../catalog/generic/GenericTableCatalog.java | 9 ++++++--- .../service/catalog/iceberg/IcebergCatalog.java | 5 +++-- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java index e1161694f8..62a5a300ff 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java @@ -428,6 +428,14 @@ public void testListTablesEmpty() { Assertions.assertThat(genericTableCatalog.listGenericTables(namespace)).isEmpty(); } + @Test + public void testListTablesNoNamespace() { + Namespace namespace = Namespace.of("ns"); + + Assertions.assertThatCode(() -> genericTableCatalog.listGenericTables(namespace)) + .hasMessageContaining("Namespace"); + } + @Test public void testListIcebergTables() { Namespace namespace = Namespace.of("ns"); @@ -453,7 +461,7 @@ public void testDropNonExistentTable() { Assertions.assertThatCode( () -> genericTableCatalog.dropGenericTable(TableIdentifier.of("ns", "t1"))) - .hasMessageContaining("Table does not exist: ns.t1"); + .hasMessageContaining("Generic table does not exist: ns.t1"); } @Test @@ -463,7 +471,7 @@ public void testDropNonExistentNamespace() { Assertions.assertThatCode( () -> genericTableCatalog.dropGenericTable(TableIdentifier.of("ns2", "t1"))) - .hasMessageContaining("Table does not exist: ns2.t1"); + .hasMessageContaining("Generic table does not exist: ns2.t1"); } @Test @@ -474,7 +482,7 @@ public void testDropIcebergTable() { Assertions.assertThatCode( () -> genericTableCatalog.dropGenericTable(TableIdentifier.of("ns", "t1"))) - .hasMessageContaining("Table does not exist: ns.t1"); + .hasMessageContaining("Generic table does not exist: ns.t1"); } @Test diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java index 8a5ad65f84..d284659080 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java @@ -24,6 +24,7 @@ import org.apache.iceberg.catalog.Namespace; import org.apache.iceberg.catalog.TableIdentifier; import org.apache.iceberg.exceptions.AlreadyExistsException; +import org.apache.iceberg.exceptions.NoSuchNamespaceException; import org.apache.iceberg.exceptions.NoSuchTableException; import org.apache.polaris.core.catalog.PolarisCatalogHelpers; import org.apache.polaris.core.context.CallContext; @@ -155,20 +156,19 @@ public GenericTableEntity loadGenericTable(TableIdentifier tableIdentifier) { GenericTableEntity.of( resolvedEntities == null ? null : resolvedEntities.getRawLeafEntity()); if (null == entity) { - throw new NoSuchTableException("Table does not exist: %s", tableIdentifier); + throw new NoSuchTableException("Generic table does not exist: %s", tableIdentifier); } else { return entity; } } - @SuppressWarnings("FormatStringAnnotation") public boolean dropGenericTable(TableIdentifier tableIdentifier) { PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( tableIdentifier, PolarisEntityType.GENERIC_TABLE, PolarisEntitySubType.ANY_SUBTYPE); if (resolvedEntities == null) { - throw new NoSuchTableException("Table does not exist: %s", tableIdentifier); + throw new NoSuchTableException("Generic table does not exist: %s", tableIdentifier); } List catalogPath = resolvedEntities.getRawParentPath(); @@ -187,6 +187,9 @@ public boolean dropGenericTable(TableIdentifier tableIdentifier) { public List listGenericTables(Namespace namespace) { PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getResolvedPath(namespace); + if (resolvedEntities == null) { + throw new NoSuchNamespaceException("Namespace '%s' does not exist", namespace); + } List catalogPath = resolvedEntities.getRawFullPath(); List entities = diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java index 00469cc491..b71c7c46df 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java @@ -1365,7 +1365,7 @@ public void doCommit(TableMetadata base, TableMetadata metadata) { } if (null == existingLocation) { - throw new NoSuchTableException("Table does not exist: %s", tableName()); + throw new NoSuchTableException("Iceberg table does not exist: %s", tableName()); } throw new CommitFailedException( @@ -1642,7 +1642,8 @@ private void renameTableLike( if (subType == PolarisEntitySubType.VIEW) { throw new NoSuchViewException("Cannot rename %s to %s. View does not exist", from, to); } else { - throw new NoSuchTableException("Cannot rename %s to %s. Table does not exist", from, to); + throw new NoSuchTableException( + "Cannot rename %s to %s. Iceberg table does not exist", from, to); } } List catalogPath = resolvedEntities.getRawParentPath(); From dab727969c0f55a0be0d17e29bed7a856f116dc9 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Mon, 24 Mar 2025 10:19:43 -0700 Subject: [PATCH 06/19] revert iceberg messages to comply with oss tests --- .../service/it/test/PolarisApplicationIntegrationTest.java | 2 +- .../polaris/service/catalog/iceberg/IcebergCatalog.java | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisApplicationIntegrationTest.java b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisApplicationIntegrationTest.java index 0be4312c04..738ac9709c 100644 --- a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisApplicationIntegrationTest.java +++ b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisApplicationIntegrationTest.java @@ -558,7 +558,7 @@ public void testIcebergDropTableInExternalCatalog() throws IOException { sessionCatalog.dropTable(sessionContext, tableIdentifier); assertThatThrownBy(() -> sessionCatalog.loadTable(sessionContext, tableIdentifier)) .isInstanceOf(NoSuchTableException.class) - .hasMessage("Table does not exist: db1.the_table"); + .hasMessage("Iceberg table does not exist: db1.the_table"); } } diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java index b71c7c46df..00469cc491 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java @@ -1365,7 +1365,7 @@ public void doCommit(TableMetadata base, TableMetadata metadata) { } if (null == existingLocation) { - throw new NoSuchTableException("Iceberg table does not exist: %s", tableName()); + throw new NoSuchTableException("Table does not exist: %s", tableName()); } throw new CommitFailedException( @@ -1642,8 +1642,7 @@ private void renameTableLike( if (subType == PolarisEntitySubType.VIEW) { throw new NoSuchViewException("Cannot rename %s to %s. View does not exist", from, to); } else { - throw new NoSuchTableException( - "Cannot rename %s to %s. Iceberg table does not exist", from, to); + throw new NoSuchTableException("Cannot rename %s to %s. Table does not exist", from, to); } } List catalogPath = resolvedEntities.getRawParentPath(); From 54a47a5458ff64b3b4187e03016497e21341fb4f Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Mon, 24 Mar 2025 10:23:02 -0700 Subject: [PATCH 07/19] another revert --- .../service/it/test/PolarisApplicationIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisApplicationIntegrationTest.java b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisApplicationIntegrationTest.java index 738ac9709c..0be4312c04 100644 --- a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisApplicationIntegrationTest.java +++ b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisApplicationIntegrationTest.java @@ -558,7 +558,7 @@ public void testIcebergDropTableInExternalCatalog() throws IOException { sessionCatalog.dropTable(sessionContext, tableIdentifier); assertThatThrownBy(() -> sessionCatalog.loadTable(sessionContext, tableIdentifier)) .isInstanceOf(NoSuchTableException.class) - .hasMessage("Iceberg table does not exist: db1.the_table"); + .hasMessage("Table does not exist: db1.the_table"); } } From 1ffbf078b500e1fcad784e7dbee25868fbdd524c Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Mon, 24 Mar 2025 11:06:40 -0700 Subject: [PATCH 08/19] more iceberg catalog changes --- .../catalog/GenericTableCatalogTest.java | 47 +++++++++++++++++++ .../catalog/generic/GenericTableCatalog.java | 15 ++++-- .../catalog/iceberg/IcebergCatalog.java | 23 ++++++--- 3 files changed, 76 insertions(+), 9 deletions(-) diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java index 62a5a300ff..e626bec14b 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java @@ -318,6 +318,36 @@ public void testCreateGenericTableDoesNotThrow() { .doesNotThrowAnyException(); } + @Test + public void testGenericTableAlreadyExists() { + Namespace namespace = Namespace.of("ns"); + icebergCatalog.createNamespace(namespace); + genericTableCatalog.createGenericTable(TableIdentifier.of("ns", "t1"), "format1", Map.of()); + + Assertions.assertThatCode( + () -> genericTableCatalog.createGenericTable(TableIdentifier.of("ns", "t1"), "format2", Map.of())) + .hasMessageContaining("already exists"); + + Assertions.assertThatCode( + () -> icebergCatalog.createTable(TableIdentifier.of("ns", "t1"), SCHEMA)) + .hasMessageContaining("already exists"); + } + + @Test + public void testIcebergTableAlreadyExists() { + Namespace namespace = Namespace.of("ns"); + icebergCatalog.createNamespace(namespace); + icebergCatalog.createTable(TableIdentifier.of("ns", "t1"), SCHEMA); + + Assertions.assertThatCode( + () -> genericTableCatalog.createGenericTable(TableIdentifier.of("ns", "t1"), "format2", Map.of())) + .hasMessageContaining("already exists"); + + Assertions.assertThatCode( + () -> icebergCatalog.createTable(TableIdentifier.of("ns", "t1"), SCHEMA)) + .hasMessageContaining("already exists"); + } + @Test public void testGenericTableRoundTrip() { Namespace namespace = Namespace.of("ns"); @@ -454,6 +484,23 @@ public void testListIcebergTables() { Assertions.assertThat(genericTableCatalog.listGenericTables(namespace)).isEmpty(); } + @Test + public void testListMixedTables() { + Namespace namespace = Namespace.of("ns"); + icebergCatalog.createNamespace(namespace); + + for (int i = 0; i < 10; i++) { + icebergCatalog.createTable(TableIdentifier.of("ns", "i" + i), SCHEMA); + } + + for (int i = 0; i < 10; i++) { + genericTableCatalog.createGenericTable(TableIdentifier.of("ns", "g" + i), "format", Map.of()); + } + + Assertions.assertThat(genericTableCatalog.listGenericTables(namespace).size()).isEqualTo(10); + Assertions.assertThat(icebergCatalog.listTables(namespace).size()).isEqualTo(10); + } + @Test public void testDropNonExistentTable() { Namespace namespace = Namespace.of("ns"); diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java index d284659080..012b5fc734 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java @@ -88,6 +88,17 @@ public GenericTableCatalog( this.metaStoreManager = metaStoreManager; } + private PolarisResolvedPathWrapper getTablePath(TableIdentifier tableIdentifier) { + PolarisResolvedPathWrapper genericTableResult = resolvedEntityView.getPassthroughResolvedPath( + tableIdentifier, PolarisEntityType.GENERIC_TABLE, PolarisEntitySubType.ANY_SUBTYPE); + if (genericTableResult == null) { + return resolvedEntityView.getPassthroughResolvedPath( + tableIdentifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE); + } else { + return genericTableResult; + } + } + public void createGenericTable( TableIdentifier tableIdentifier, String format, Map properties) { PolarisResolvedPathWrapper resolvedParent = @@ -101,9 +112,7 @@ public void createGenericTable( List catalogPath = resolvedParent.getRawFullPath(); - PolarisResolvedPathWrapper resolvedEntities = - resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntityType.GENERIC_TABLE, PolarisEntitySubType.ANY_SUBTYPE); + PolarisResolvedPathWrapper resolvedEntities = getTablePath(tableIdentifier); GenericTableEntity entity = GenericTableEntity.of( resolvedEntities == null ? null : resolvedEntities.getRawLeafEntity()); diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java index 00469cc491..0c6c28afcf 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java @@ -1189,6 +1189,17 @@ private class BasePolarisTableOperations extends BaseMetastoreTableOperations { this.tableFileIO = defaultFileIO; } + protected PolarisResolvedPathWrapper getTablePath(TableIdentifier tableIdentifier) { + PolarisResolvedPathWrapper icebergTableResult = resolvedEntityView.getPassthroughResolvedPath( + tableIdentifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE); + if (icebergTableResult == null) { + return resolvedEntityView.getPassthroughResolvedPath( + tableIdentifier, PolarisEntityType.GENERIC_TABLE, PolarisEntitySubType.ANY_SUBTYPE); + } else { + return icebergTableResult; + } + } + @Override public void doRefresh() { LOGGER.debug("doRefresh for tableIdentifier {}", tableIdentifier); @@ -1334,9 +1345,7 @@ public void doCommit(TableMetadata base, TableMetadata metadata) { // concurrent // modification between our checking of unchanged metadataLocation here and actual // persistence-layer commit). - PolarisResolvedPathWrapper resolvedEntities = - resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE); + PolarisResolvedPathWrapper resolvedEntities = getTablePath(tableIdentifier); IcebergTableLikeEntity entity = IcebergTableLikeEntity.of( resolvedEntities == null ? null : resolvedEntities.getRawLeafEntity()); @@ -1359,6 +1368,9 @@ public void doCommit(TableMetadata base, TableMetadata metadata) { .setMetadataLocation(newLocation) .build(); } + if (entity.getType() == PolarisEntityType.GENERIC_TABLE) { + throw new AlreadyExistsException("Table already exists: %s", tableName()); + } if (!Objects.equal(existingLocation, oldLocation)) { if (null == base) { throw new AlreadyExistsException("Table already exists: %s", tableName()); @@ -1487,9 +1499,8 @@ public void doCommit(ViewMetadata base, ViewMetadata metadata) { identifier, identifier.namespace()); } - PolarisResolvedPathWrapper resolvedTable = - resolvedEntityView.getPassthroughResolvedPath( - identifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE); + PolarisResolvedPathWrapper resolvedTable = resolvedEntityView.getPassthroughResolvedPath( + identifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE); if (resolvedTable != null) { throw new AlreadyExistsException("Table with same name already exists: %s", identifier); } From 113c9419f750fd753ad24befcc27edb3874e720f Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Mon, 24 Mar 2025 11:08:35 -0700 Subject: [PATCH 09/19] autolint --- .../quarkus/catalog/GenericTableCatalogTest.java | 8 ++++++-- .../service/catalog/generic/GenericTableCatalog.java | 5 +++-- .../service/catalog/iceberg/IcebergCatalog.java | 12 ++++++++---- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java index e626bec14b..9fc59cce24 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java @@ -325,7 +325,9 @@ public void testGenericTableAlreadyExists() { genericTableCatalog.createGenericTable(TableIdentifier.of("ns", "t1"), "format1", Map.of()); Assertions.assertThatCode( - () -> genericTableCatalog.createGenericTable(TableIdentifier.of("ns", "t1"), "format2", Map.of())) + () -> + genericTableCatalog.createGenericTable( + TableIdentifier.of("ns", "t1"), "format2", Map.of())) .hasMessageContaining("already exists"); Assertions.assertThatCode( @@ -340,7 +342,9 @@ public void testIcebergTableAlreadyExists() { icebergCatalog.createTable(TableIdentifier.of("ns", "t1"), SCHEMA); Assertions.assertThatCode( - () -> genericTableCatalog.createGenericTable(TableIdentifier.of("ns", "t1"), "format2", Map.of())) + () -> + genericTableCatalog.createGenericTable( + TableIdentifier.of("ns", "t1"), "format2", Map.of())) .hasMessageContaining("already exists"); Assertions.assertThatCode( diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java index 012b5fc734..322b7cb0db 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java @@ -89,8 +89,9 @@ public GenericTableCatalog( } private PolarisResolvedPathWrapper getTablePath(TableIdentifier tableIdentifier) { - PolarisResolvedPathWrapper genericTableResult = resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntityType.GENERIC_TABLE, PolarisEntitySubType.ANY_SUBTYPE); + PolarisResolvedPathWrapper genericTableResult = + resolvedEntityView.getPassthroughResolvedPath( + tableIdentifier, PolarisEntityType.GENERIC_TABLE, PolarisEntitySubType.ANY_SUBTYPE); if (genericTableResult == null) { return resolvedEntityView.getPassthroughResolvedPath( tableIdentifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE); diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java index 0c6c28afcf..54434a0754 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java @@ -1190,8 +1190,11 @@ private class BasePolarisTableOperations extends BaseMetastoreTableOperations { } protected PolarisResolvedPathWrapper getTablePath(TableIdentifier tableIdentifier) { - PolarisResolvedPathWrapper icebergTableResult = resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE); + PolarisResolvedPathWrapper icebergTableResult = + resolvedEntityView.getPassthroughResolvedPath( + tableIdentifier, + PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntitySubType.ANY_SUBTYPE); if (icebergTableResult == null) { return resolvedEntityView.getPassthroughResolvedPath( tableIdentifier, PolarisEntityType.GENERIC_TABLE, PolarisEntitySubType.ANY_SUBTYPE); @@ -1499,8 +1502,9 @@ public void doCommit(ViewMetadata base, ViewMetadata metadata) { identifier, identifier.namespace()); } - PolarisResolvedPathWrapper resolvedTable = resolvedEntityView.getPassthroughResolvedPath( - identifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE); + PolarisResolvedPathWrapper resolvedTable = + resolvedEntityView.getPassthroughResolvedPath( + identifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE); if (resolvedTable != null) { throw new AlreadyExistsException("Table with same name already exists: %s", identifier); } From 0230ab302554f2c61783f8df4ff626a1d7dcbfa7 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Tue, 25 Mar 2025 13:44:30 -0700 Subject: [PATCH 10/19] wip --- .../core/entity/IcebergTableLikeEntity.java | 2 +- .../core/entity/PolarisEntitySubType.java | 6 +- .../core/entity/PolarisEntityType.java | 8 +- .../polaris/core/entity/PolarisPrivilege.java | 28 ++-- .../polaris/core/entity/TableLikeEntity.java | 22 +++ .../core/persistence/resolver/Resolver.java | 2 +- .../storage/cache/StorageCredentialCache.java | 2 +- .../core/persistence/EntityCacheTest.java | 8 +- .../core/persistence/ResolverTest.java | 16 +-- .../cache/StorageCredentialCacheTest.java | 12 +- .../PolarisTestMetaStoreManager.java | 128 +++++++++--------- .../quarkus/catalog/IcebergCatalogTest.java | 2 +- .../service/admin/PolarisAdminService.java | 24 ++-- .../catalog/generic/GenericTableCatalog.java | 2 +- .../catalog/iceberg/IcebergCatalog.java | 48 +++---- .../iceberg/IcebergCatalogHandlerWrapper.java | 48 +++---- .../service/task/TableCleanupTaskHandler.java | 2 +- 17 files changed, 191 insertions(+), 169 deletions(-) create mode 100644 polaris-core/src/main/java/org/apache/polaris/core/entity/TableLikeEntity.java diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/IcebergTableLikeEntity.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/IcebergTableLikeEntity.java index e7e1810754..b18f093f80 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/entity/IcebergTableLikeEntity.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/IcebergTableLikeEntity.java @@ -82,7 +82,7 @@ public String getBaseLocation() { public static class Builder extends PolarisEntity.BaseBuilder { public Builder(TableIdentifier identifier, String metadataLocation) { super(); - setType(PolarisEntityType.ICEBERG_TABLE_LIKE); + setType(PolarisEntityType.TABLE_LIKE); setTableIdentifier(identifier); setMetadataLocation(metadataLocation); } diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntitySubType.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntitySubType.java index e45f4d910f..870d7c32a7 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntitySubType.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntitySubType.java @@ -30,8 +30,10 @@ public enum PolarisEntitySubType { ANY_SUBTYPE(-1, null), // the NULL value is used when an entity has no subtype, i.e. NOT_APPLICABLE really NULL_SUBTYPE(0, null), - TABLE(2, PolarisEntityType.ICEBERG_TABLE_LIKE), - VIEW(3, PolarisEntityType.ICEBERG_TABLE_LIKE); + ICEBERG_TABLE(2, PolarisEntityType.TABLE_LIKE), + VIEW(3, PolarisEntityType.TABLE_LIKE), + GENERIC_TABLE(4, PolarisEntityType.TABLE_LIKE); + // to efficiently map the code of a subtype to its corresponding subtype enum, use a reverse // array which is initialized below diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntityType.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntityType.java index 90d9aa9e5f..fae2d66eb4 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntityType.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntityType.java @@ -31,12 +31,10 @@ public enum PolarisEntityType { CATALOG(4, ROOT, false, false), CATALOG_ROLE(5, CATALOG, true, false), NAMESPACE(6, CATALOG, false, true), - // generic table is either a view or a real table - ICEBERG_TABLE_LIKE(7, NAMESPACE, false, false), + TABLE_LIKE(7, NAMESPACE, false, false), TASK(8, ROOT, false, false), - FILE(9, ICEBERG_TABLE_LIKE, false, false), - POLICY(10, NAMESPACE, false, false), - GENERIC_TABLE(11, NAMESPACE, false, false); + FILE(9, TABLE_LIKE, false, false), + POLICY(10, NAMESPACE, false, false); // to efficiently map a code to its corresponding entity type, use a reverse array which // is initialized below diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisPrivilege.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisPrivilege.java index 122d39a4ce..782c622d3c 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisPrivilege.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisPrivilege.java @@ -41,22 +41,22 @@ public enum PolarisPrivilege { TABLE_CREATE(6, PolarisEntityType.NAMESPACE), VIEW_CREATE(7, PolarisEntityType.NAMESPACE), NAMESPACE_DROP(8, PolarisEntityType.NAMESPACE), - TABLE_DROP(9, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE), - VIEW_DROP(10, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.VIEW), + TABLE_DROP(9, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE), + VIEW_DROP(10, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW), NAMESPACE_LIST(11, PolarisEntityType.NAMESPACE), TABLE_LIST(12, PolarisEntityType.NAMESPACE), VIEW_LIST(13, PolarisEntityType.NAMESPACE), NAMESPACE_READ_PROPERTIES(14, PolarisEntityType.NAMESPACE), - TABLE_READ_PROPERTIES(15, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE), - VIEW_READ_PROPERTIES(16, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.VIEW), + TABLE_READ_PROPERTIES(15, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE), + VIEW_READ_PROPERTIES(16, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW), NAMESPACE_WRITE_PROPERTIES(17, PolarisEntityType.NAMESPACE), - TABLE_WRITE_PROPERTIES(18, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE), - VIEW_WRITE_PROPERTIES(19, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.VIEW), - TABLE_READ_DATA(20, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE), - TABLE_WRITE_DATA(21, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE), + TABLE_WRITE_PROPERTIES(18, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE), + VIEW_WRITE_PROPERTIES(19, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW), + TABLE_READ_DATA(20, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE), + TABLE_WRITE_DATA(21, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE), NAMESPACE_FULL_METADATA(22, PolarisEntityType.NAMESPACE), - TABLE_FULL_METADATA(23, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE), - VIEW_FULL_METADATA(24, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.VIEW), + TABLE_FULL_METADATA(23, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE), + VIEW_FULL_METADATA(24, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW), CATALOG_CREATE(25, PolarisEntityType.ROOT), CATALOG_DROP(26, PolarisEntityType.CATALOG), CATALOG_LIST(27, PolarisEntityType.ROOT), @@ -70,14 +70,14 @@ public enum PolarisPrivilege { CATALOG_ROLE_LIST_GRANTS(35, PolarisEntityType.PRINCIPAL), CATALOG_LIST_GRANTS(36, PolarisEntityType.CATALOG), NAMESPACE_LIST_GRANTS(37, PolarisEntityType.NAMESPACE), - TABLE_LIST_GRANTS(38, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE), - VIEW_LIST_GRANTS(39, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.VIEW), + TABLE_LIST_GRANTS(38, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE), + VIEW_LIST_GRANTS(39, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW), CATALOG_MANAGE_GRANTS_ON_SECURABLE(40, PolarisEntityType.CATALOG), NAMESPACE_MANAGE_GRANTS_ON_SECURABLE(41, PolarisEntityType.NAMESPACE), TABLE_MANAGE_GRANTS_ON_SECURABLE( - 42, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE), + 42, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE), VIEW_MANAGE_GRANTS_ON_SECURABLE( - 43, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.VIEW), + 43, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW), PRINCIPAL_CREATE(44, PolarisEntityType.ROOT), PRINCIPAL_DROP(45, PolarisEntityType.PRINCIPAL), PRINCIPAL_LIST(46, PolarisEntityType.ROOT), diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/TableLikeEntity.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/TableLikeEntity.java new file mode 100644 index 0000000000..cb13dd1bfc --- /dev/null +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/TableLikeEntity.java @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.polaris.core.entity;public class TableLikeEntity { + +} diff --git a/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/Resolver.java b/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/Resolver.java index 7e152c05f6..5f4fa2c68b 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/Resolver.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/Resolver.java @@ -374,7 +374,7 @@ public ResolverStatus resolveAll() { // validate input diagnostics.check( entityType != PolarisEntityType.NAMESPACE - && entityType != PolarisEntityType.ICEBERG_TABLE_LIKE, + && entityType != PolarisEntityType.TABLE_LIKE, "cannot_be_path"); diagnostics.check( entityType.isTopLevel() || this.referenceCatalogName != null, "reference_catalog_expected"); diff --git a/polaris-core/src/main/java/org/apache/polaris/core/storage/cache/StorageCredentialCache.java b/polaris-core/src/main/java/org/apache/polaris/core/storage/cache/StorageCredentialCache.java index 20a371f4e0..3fe5931950 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/storage/cache/StorageCredentialCache.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/storage/cache/StorageCredentialCache.java @@ -154,7 +154,7 @@ public Map getIfPresent(StorageCredentialCacheKey key) { private boolean isTypeSupported(PolarisEntityType type) { return type == PolarisEntityType.CATALOG || type == PolarisEntityType.NAMESPACE - || type == PolarisEntityType.ICEBERG_TABLE_LIKE + || type == PolarisEntityType.TABLE_LIKE || type == PolarisEntityType.TASK; } diff --git a/polaris-core/src/test/java/org/apache/polaris/core/persistence/EntityCacheTest.java b/polaris-core/src/test/java/org/apache/polaris/core/persistence/EntityCacheTest.java index 389f83deac..463da06c16 100644 --- a/polaris-core/src/test/java/org/apache/polaris/core/persistence/EntityCacheTest.java +++ b/polaris-core/src/test/java/org/apache/polaris/core/persistence/EntityCacheTest.java @@ -298,8 +298,8 @@ void testRefresh() { PolarisBaseEntity T6v1 = this.tm.ensureExistsByName( List.of(catalog, N5, N5_N6), - PolarisEntityType.ICEBERG_TABLE_LIKE, - PolarisEntitySubType.TABLE, + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_TABLE, "T6"); Assertions.assertThat(T6v1).isNotNull(); @@ -436,7 +436,7 @@ void testRenameAndCacheDestinationBeforeLoadingSource() { EntityCacheByNameKey T4_name = new EntityCacheByNameKey( - N1.getCatalogId(), N1.getId(), PolarisEntityType.ICEBERG_TABLE_LIKE, "T4"); + N1.getCatalogId(), N1.getId(), PolarisEntityType.TABLE_LIKE, "T4"); lookup = cache.getOrLoadEntityByName(callCtx, T4_name); Assertions.assertThat(lookup).isNotNull(); ResolvedPolarisEntity cacheEntry_T4 = lookup.getCacheEntry(); @@ -451,7 +451,7 @@ void testRenameAndCacheDestinationBeforeLoadingSource() { // load the renamed entity into cache EntityCacheByNameKey T4_renamed = new EntityCacheByNameKey( - N1.getCatalogId(), N1.getId(), PolarisEntityType.ICEBERG_TABLE_LIKE, "T4_renamed"); + N1.getCatalogId(), N1.getId(), PolarisEntityType.TABLE_LIKE, "T4_renamed"); lookup = cache.getOrLoadEntityByName(callCtx, T4_renamed); Assertions.assertThat(lookup).isNotNull(); ResolvedPolarisEntity cacheEntry_T4_renamed = lookup.getCacheEntry(); diff --git a/polaris-core/src/test/java/org/apache/polaris/core/persistence/ResolverTest.java b/polaris-core/src/test/java/org/apache/polaris/core/persistence/ResolverTest.java index 80bca67af5..d725abca60 100644 --- a/polaris-core/src/test/java/org/apache/polaris/core/persistence/ResolverTest.java +++ b/polaris-core/src/test/java/org/apache/polaris/core/persistence/ResolverTest.java @@ -216,12 +216,12 @@ void testResolvePath(boolean useCache) { // N1/N2/T1 which exists ResolverPath N1_N2_T1 = - new ResolverPath(List.of("N1", "N2", "T1"), PolarisEntityType.ICEBERG_TABLE_LIKE); + new ResolverPath(List.of("N1", "N2", "T1"), PolarisEntityType.TABLE_LIKE); this.resolveDriver(this.cache, "test", N1_N2_T1, null, null); // N1/N2/T1 which exists ResolverPath N1_N2_V1 = - new ResolverPath(List.of("N1", "N2", "V1"), PolarisEntityType.ICEBERG_TABLE_LIKE); + new ResolverPath(List.of("N1", "N2", "V1"), PolarisEntityType.TABLE_LIKE); this.resolveDriver(this.cache, "test", N1_N2_V1, null, null); // N5/N6 which exists @@ -230,7 +230,7 @@ void testResolvePath(boolean useCache) { // N5/N6/T5 which exists ResolverPath N5_N6_T5 = - new ResolverPath(List.of("N5", "N6", "T5"), PolarisEntityType.ICEBERG_TABLE_LIKE); + new ResolverPath(List.of("N5", "N6", "T5"), PolarisEntityType.TABLE_LIKE); this.resolveDriver(this.cache, "test", N5_N6_T5, null, null); // N7/N8 which exists @@ -248,7 +248,7 @@ void testResolvePath(boolean useCache) { // Error scenarios: N5/N6/T8 which does not exists ResolverPath N5_N6_T8 = - new ResolverPath(List.of("N5", "N6", "T8"), PolarisEntityType.ICEBERG_TABLE_LIKE); + new ResolverPath(List.of("N5", "N6", "T8"), PolarisEntityType.TABLE_LIKE); this.resolveDriver( this.cache, "test", @@ -258,7 +258,7 @@ void testResolvePath(boolean useCache) { // Error scenarios: N8/N6/T8 which does not exists ResolverPath N8_N6_T8 = - new ResolverPath(List.of("N8", "N6", "T8"), PolarisEntityType.ICEBERG_TABLE_LIKE); + new ResolverPath(List.of("N8", "N6", "T8"), PolarisEntityType.TABLE_LIKE); this.resolveDriver( this.cache, "test", @@ -278,7 +278,7 @@ void testResolvePath(boolean useCache) { // except if the optional flag is specified N5_N6_T8 = - new ResolverPath(List.of("N5", "N6", "T8"), PolarisEntityType.ICEBERG_TABLE_LIKE, true); + new ResolverPath(List.of("N5", "N6", "T8"), PolarisEntityType.TABLE_LIKE, true); Resolver resolver = this.resolveDriver(this.cache, "test", null, List.of(N1, N5_N6_T8, N5_N6_T5, N1_N2), null); // get all the resolved paths @@ -366,7 +366,7 @@ void testPathConsistency(boolean useCache) { ResolverPath N1_N2_PATH = new ResolverPath(List.of("N1", "N2"), PolarisEntityType.NAMESPACE); this.resolveDriver(this.cache, "test", N1_N2_PATH, null, null); ResolverPath N1_N2_T1_PATH = - new ResolverPath(List.of("N1", "N2", "T1"), PolarisEntityType.ICEBERG_TABLE_LIKE); + new ResolverPath(List.of("N1", "N2", "T1"), PolarisEntityType.TABLE_LIKE); Resolver resolver = this.resolveDriver(this.cache, "test", N1_N2_T1_PATH, null, null); // get the catalog @@ -400,7 +400,7 @@ void testPathConsistency(boolean useCache) { // but we should be able to resolve it under N1/N3 ResolverPath N1_N3_T1_PATH = - new ResolverPath(List.of("N1", "N3", "T1"), PolarisEntityType.ICEBERG_TABLE_LIKE); + new ResolverPath(List.of("N1", "N3", "T1"), PolarisEntityType.TABLE_LIKE); this.resolveDriver(this.cache, "test", N1_N3_T1_PATH, null, null); } diff --git a/polaris-core/src/test/java/org/apache/polaris/core/storage/cache/StorageCredentialCacheTest.java b/polaris-core/src/test/java/org/apache/polaris/core/storage/cache/StorageCredentialCacheTest.java index f3b4fc2f62..aa22c42180 100644 --- a/polaris-core/src/test/java/org/apache/polaris/core/storage/cache/StorageCredentialCacheTest.java +++ b/polaris-core/src/test/java/org/apache/polaris/core/storage/cache/StorageCredentialCacheTest.java @@ -92,7 +92,7 @@ public void testBadResult() { PolarisEntity polarisEntity = new PolarisEntity( new PolarisBaseEntity( - 1, 2, PolarisEntityType.CATALOG, PolarisEntitySubType.TABLE, 0, "name")); + 1, 2, PolarisEntityType.CATALOG, PolarisEntitySubType.ICEBERG_TABLE, 0, "name")); Assertions.assertThatThrownBy( () -> storageCredentialCache.getOrGenerateSubScopeCreds( @@ -125,7 +125,7 @@ public void testCacheHit() { .thenReturn(mockedScopedCreds.get(1)); PolarisBaseEntity baseEntity = new PolarisBaseEntity( - 1, 2, PolarisEntityType.CATALOG, PolarisEntitySubType.TABLE, 0, "name"); + 1, 2, PolarisEntityType.CATALOG, PolarisEntitySubType.ICEBERG_TABLE, 0, "name"); PolarisEntity polarisEntity = new PolarisEntity(baseEntity); // add an item to the cache @@ -168,7 +168,7 @@ public void testCacheEvict() throws InterruptedException { .thenReturn(mockedScopedCreds.get(2)); PolarisBaseEntity baseEntity = new PolarisBaseEntity( - 1, 2, PolarisEntityType.CATALOG, PolarisEntitySubType.TABLE, 0, "name"); + 1, 2, PolarisEntityType.CATALOG, PolarisEntitySubType.ICEBERG_TABLE, 0, "name"); PolarisEntity polarisEntity = new PolarisEntity(baseEntity); StorageCredentialCacheKey cacheKey = new StorageCredentialCacheKey( @@ -426,15 +426,15 @@ private static List getPolarisEntities() { PolarisEntity polarisEntity1 = new PolarisEntity( new PolarisBaseEntity( - 1, 2, PolarisEntityType.CATALOG, PolarisEntitySubType.TABLE, 0, "name")); + 1, 2, PolarisEntityType.CATALOG, PolarisEntitySubType.ICEBERG_TABLE, 0, "name")); PolarisEntity polarisEntity2 = new PolarisEntity( new PolarisBaseEntity( - 2, 2, PolarisEntityType.CATALOG, PolarisEntitySubType.TABLE, 0, "name")); + 2, 2, PolarisEntityType.CATALOG, PolarisEntitySubType.ICEBERG_TABLE, 0, "name")); PolarisEntity polarisEntity3 = new PolarisEntity( new PolarisBaseEntity( - 3, 2, PolarisEntityType.CATALOG, PolarisEntitySubType.TABLE, 0, "name")); + 3, 2, PolarisEntityType.CATALOG, PolarisEntitySubType.ICEBERG_TABLE, 0, "name")); return Arrays.asList(polarisEntity1, polarisEntity2, polarisEntity3); } diff --git a/polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/PolarisTestMetaStoreManager.java b/polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/PolarisTestMetaStoreManager.java index b8470dee94..f965e00548 100644 --- a/polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/PolarisTestMetaStoreManager.java +++ b/polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/PolarisTestMetaStoreManager.java @@ -742,7 +742,7 @@ void dropEntity(List catalogPath, PolarisBaseEntity entityToD .listEntities( this.polarisCallContext, path, - PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE) .getEntities(); Assertions.assertThat(children).isNotNull(); @@ -1003,35 +1003,35 @@ PolarisBaseEntity createTestCatalog(String catalogName) { this.createEntity(List.of(catalog, N1), PolarisEntityType.NAMESPACE, "N2"); this.createEntity( List.of(catalog, N1, N1_N2), - PolarisEntityType.ICEBERG_TABLE_LIKE, - PolarisEntitySubType.TABLE, + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_TABLE, "T1"); this.createEntity( List.of(catalog, N1, N1_N2), - PolarisEntityType.ICEBERG_TABLE_LIKE, - PolarisEntitySubType.TABLE, + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_TABLE, "T2"); this.createEntity( List.of(catalog, N1, N1_N2), - PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW, "V1"); PolarisBaseEntity N1_N3 = this.createEntity(List.of(catalog, N1), PolarisEntityType.NAMESPACE, "N3"); this.createEntity( List.of(catalog, N1, N1_N3), - PolarisEntityType.ICEBERG_TABLE_LIKE, - PolarisEntitySubType.TABLE, + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_TABLE, "T3"); this.createEntity( List.of(catalog, N1, N1_N3), - PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW, "V2"); this.createEntity( List.of(catalog, N1), - PolarisEntityType.ICEBERG_TABLE_LIKE, - PolarisEntitySubType.TABLE, + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_TABLE, "T4"); this.createEntity(List.of(catalog, N1), PolarisEntityType.NAMESPACE, "N4"); PolarisBaseEntity N5 = this.createEntity(List.of(catalog), PolarisEntityType.NAMESPACE, "N5"); @@ -1040,13 +1040,13 @@ PolarisBaseEntity createTestCatalog(String catalogName) { PolarisBaseEntity N5_N6_T5 = this.createEntity( List.of(catalog, N5, N5_N6), - PolarisEntityType.ICEBERG_TABLE_LIKE, - PolarisEntitySubType.TABLE, + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_TABLE, "T5"); this.createEntity( List.of(catalog, N5, N5_N6), - PolarisEntityType.ICEBERG_TABLE_LIKE, - PolarisEntitySubType.TABLE, + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_TABLE, "T6"); PolarisBaseEntity N7 = this.createEntity(List.of(catalog), PolarisEntityType.NAMESPACE, "N7"); @@ -1664,45 +1664,45 @@ void testCreateTestCatalog() { this.ensureExistsByName(List.of(catalog, N1), PolarisEntityType.NAMESPACE, "N2"); this.ensureExistsByName( List.of(catalog, N1, N1_N2), - PolarisEntityType.ICEBERG_TABLE_LIKE, - PolarisEntitySubType.TABLE, + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_TABLE, "T1"); this.ensureExistsByName( List.of(catalog, N1, N1_N2), - PolarisEntityType.ICEBERG_TABLE_LIKE, - PolarisEntitySubType.TABLE, + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_TABLE, "T2"); this.ensureExistsByName( List.of(catalog, N1, N1_N2), - PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE, "T2"); this.ensureExistsByName( List.of(catalog, N1, N1_N2), - PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW, "V1"); this.ensureExistsByName( List.of(catalog, N1, N1_N2), - PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE, "V1"); PolarisBaseEntity N1_N3 = this.ensureExistsByName(List.of(catalog, N1), PolarisEntityType.NAMESPACE, "N3"); this.ensureExistsByName( List.of(catalog, N1, N1_N3), - PolarisEntityType.ICEBERG_TABLE_LIKE, - PolarisEntitySubType.TABLE, + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_TABLE, "T3"); this.ensureExistsByName( List.of(catalog, N1, N1_N3), - PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE, "V2"); this.ensureExistsByName( List.of(catalog, N1), - PolarisEntityType.ICEBERG_TABLE_LIKE, - PolarisEntitySubType.TABLE, + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_TABLE, "T4"); this.ensureExistsByName(List.of(catalog, N1), PolarisEntityType.NAMESPACE, "N4"); PolarisBaseEntity N5 = @@ -1715,19 +1715,19 @@ void testCreateTestCatalog() { "N6"); this.ensureExistsByName( List.of(catalog, N5, N5_N6), - PolarisEntityType.ICEBERG_TABLE_LIKE, - PolarisEntitySubType.TABLE, + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_TABLE, "T5"); PolarisBaseEntity N5_N6_T5 = this.ensureExistsByName( List.of(catalog, N5, N5_N6), - PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE, "T5"); this.ensureExistsByName( List.of(catalog, N5, N5_N6), - PolarisEntityType.ICEBERG_TABLE_LIKE, - PolarisEntitySubType.TABLE, + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_TABLE, "T6"); PolarisBaseEntity N7 = this.ensureExistsByName(List.of(catalog), PolarisEntityType.NAMESPACE, "N7"); @@ -1821,9 +1821,9 @@ void testBrowse() { ImmutablePair.of("N4", PolarisEntitySubType.NULL_SUBTYPE))); this.validateListReturn( List.of(catalog, N1), - PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE, - List.of(ImmutablePair.of("T4", PolarisEntitySubType.TABLE))); + List.of(ImmutablePair.of("T4", PolarisEntitySubType.ICEBERG_TABLE))); PolarisBaseEntity N5 = this.ensureExistsByName(List.of(catalog), PolarisEntityType.NAMESPACE, "N5"); this.validateListReturn( @@ -1837,24 +1837,24 @@ void testBrowse() { // table or view object this.validateListReturn( List.of(catalog, N1, N1_N2), - PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE, List.of( - ImmutablePair.of("T1", PolarisEntitySubType.TABLE), - ImmutablePair.of("T2", PolarisEntitySubType.TABLE), + ImmutablePair.of("T1", PolarisEntitySubType.ICEBERG_TABLE), + ImmutablePair.of("T2", PolarisEntitySubType.ICEBERG_TABLE), ImmutablePair.of("V1", PolarisEntitySubType.VIEW))); // table object only this.validateListReturn( List.of(catalog, N1, N1_N2), - PolarisEntityType.ICEBERG_TABLE_LIKE, - PolarisEntitySubType.TABLE, + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_TABLE, List.of( - ImmutablePair.of("T1", PolarisEntitySubType.TABLE), - ImmutablePair.of("T2", PolarisEntitySubType.TABLE))); + ImmutablePair.of("T1", PolarisEntitySubType.ICEBERG_TABLE), + ImmutablePair.of("T2", PolarisEntitySubType.ICEBERG_TABLE))); // view object only this.validateListReturn( List.of(catalog, N1, N1_N2), - PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW, List.of(ImmutablePair.of("V1", PolarisEntitySubType.VIEW))); // list all principals @@ -1903,8 +1903,8 @@ void testUpdateEntities() { PolarisBaseEntity T6v1 = this.ensureExistsByName( List.of(catalog, N5, N5_N6), - PolarisEntityType.ICEBERG_TABLE_LIKE, - PolarisEntitySubType.TABLE, + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_TABLE, "T6"); Assertions.assertThat(T6v1).isNotNull(); @@ -1940,8 +1940,8 @@ void testUpdateEntities() { PolarisBaseEntity T5v1 = this.ensureExistsByName( List.of(catalog, N5, N5_N6), - PolarisEntityType.ICEBERG_TABLE_LIKE, - PolarisEntitySubType.TABLE, + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_TABLE, "T5"); T5v1.setId(100000L); PolarisBaseEntity notExists = @@ -1981,8 +1981,8 @@ void testDropEntities() { PolarisBaseEntity T6 = this.ensureExistsByName( List.of(catalog, N5, N5_N6), - PolarisEntityType.ICEBERG_TABLE_LIKE, - PolarisEntitySubType.TABLE, + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_TABLE, "T6"); Assertions.assertThat(T6).isNotNull(); @@ -2001,21 +2001,21 @@ void testDropEntities() { PolarisBaseEntity T1 = this.ensureExistsByName( List.of(catalog, N1, N1_N2), - PolarisEntityType.ICEBERG_TABLE_LIKE, - PolarisEntitySubType.TABLE, + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_TABLE, "T1"); this.dropEntity(List.of(catalog, N1, N1_N2), T1); PolarisBaseEntity T2 = this.ensureExistsByName( List.of(catalog, N1, N1_N2), - PolarisEntityType.ICEBERG_TABLE_LIKE, - PolarisEntitySubType.TABLE, + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_TABLE, "T2"); this.dropEntity(List.of(catalog, N1, N1_N2), T2); PolarisBaseEntity V1 = this.ensureExistsByName( List.of(catalog, N1, N1_N2), - PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW, "V1"); this.dropEntity(List.of(catalog, N1, N1_N2), V1); @@ -2026,14 +2026,14 @@ void testDropEntities() { PolarisBaseEntity T3 = this.ensureExistsByName( List.of(catalog, N1, N1_N3), - PolarisEntityType.ICEBERG_TABLE_LIKE, - PolarisEntitySubType.TABLE, + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_TABLE, "T3"); this.dropEntity(List.of(catalog, N1, N1_N3), T3); PolarisBaseEntity V2 = this.ensureExistsByName( List.of(catalog, N1, N1_N3), - PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW, "V2"); this.dropEntity(List.of(catalog, N1, N1_N3), V2); @@ -2042,8 +2042,8 @@ void testDropEntities() { PolarisBaseEntity T4 = this.ensureExistsByName( List.of(catalog, N1), - PolarisEntityType.ICEBERG_TABLE_LIKE, - PolarisEntitySubType.TABLE, + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_TABLE, "T4"); this.dropEntity(List.of(catalog, N1), T4); this.dropEntity(List.of(catalog), N1); @@ -2051,8 +2051,8 @@ void testDropEntities() { PolarisBaseEntity T5 = this.ensureExistsByName( List.of(catalog, N5, N5_N6), - PolarisEntityType.ICEBERG_TABLE_LIKE, - PolarisEntitySubType.TABLE, + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_TABLE, "T5"); this.dropEntity(List.of(catalog, N5, N5_N6), T5); this.dropEntity(List.of(catalog, N5), N5_N6); @@ -2171,7 +2171,7 @@ public void testPrivileges() { PolarisBaseEntity N5_N6_T5 = this.ensureExistsByName( List.of(catalog, N5, N5_N6), - PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE, "T5"); @@ -2341,7 +2341,7 @@ public void testRename() { PolarisBaseEntity N1_N2_T1 = this.ensureExistsByName( List.of(catalog, N1, N1_N2), - PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE, "T1"); // view with the same name exists, should fail @@ -2438,13 +2438,13 @@ public void testEntityCache() { this.loadCacheEntryByName( N1.getCatalogId(), N1.getId(), - PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntityType.TABLE_LIKE, "do_not_exists", false); this.loadCacheEntryById(N1.getCatalogId() + 1000, N1.getId(), N1.getType(), false); // refresh a purged entity this.refreshCacheEntry( - 1, 1, PolarisEntityType.ICEBERG_TABLE_LIKE, N1.getCatalogId() + 1000, N1.getId(), false); + 1, 1, PolarisEntityType.TABLE_LIKE, N1.getCatalogId() + 1000, N1.getId(), false); } } diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/IcebergCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/IcebergCatalogTest.java index 3dafaf109a..8d520b9a9f 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/IcebergCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/IcebergCatalogTest.java @@ -1710,7 +1710,7 @@ public void testConcurrencyConflictCreateTableUpdatedDuringFinalTransaction() { doReturn( new EntityResult( BaseResult.ReturnStatus.ENTITY_ALREADY_EXISTS, - PolarisEntitySubType.TABLE.getCode())) + PolarisEntitySubType.ICEBERG_TABLE.getCode())) .when(spyMetaStore) .createEntityIfNotExists(any(), any(), any()); Assertions.assertThatThrownBy(() -> catalog.createTable(table, SCHEMA)) diff --git a/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java b/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java index bedb10165c..f80df7c819 100644 --- a/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java +++ b/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java @@ -462,7 +462,7 @@ private void authorizeGrantOnTableLikeOperationOrThrow( resolutionManifest.addPath( new ResolverPath( PolarisCatalogHelpers.tableIdentifierToList(identifier), - PolarisEntityType.ICEBERG_TABLE_LIKE), + PolarisEntityType.TABLE_LIKE), identifier); resolutionManifest.addPath( new ResolverPath(List.of(catalogRoleName), PolarisEntityType.CATALOG_ROLE), @@ -473,8 +473,8 @@ private void authorizeGrantOnTableLikeOperationOrThrow( throw new NotFoundException("Catalog not found: %s", catalogName); } else if (status.getStatus() == ResolverStatus.StatusEnum.PATH_COULD_NOT_BE_FULLY_RESOLVED) { if (status.getFailedToResolvePath().getLastEntityType() - == PolarisEntityType.ICEBERG_TABLE_LIKE) { - if (subType == PolarisEntitySubType.TABLE) { + == PolarisEntityType.TABLE_LIKE) { + if (subType == PolarisEntitySubType.ICEBERG_TABLE) { throw new NoSuchTableException("Table does not exist: %s", identifier); } else { throw new NoSuchViewException("View does not exist: %s", identifier); @@ -486,7 +486,7 @@ private void authorizeGrantOnTableLikeOperationOrThrow( PolarisResolvedPathWrapper tableLikeWrapper = resolutionManifest.getResolvedPath( - identifier, PolarisEntityType.ICEBERG_TABLE_LIKE, subType, true); + identifier, PolarisEntityType.TABLE_LIKE, subType, true); PolarisResolvedPathWrapper catalogRoleWrapper = resolutionManifest.getResolvedPath(catalogRoleName, true); @@ -1498,10 +1498,10 @@ public boolean grantPrivilegeOnTableToRole( PolarisAuthorizableOperation op = PolarisAuthorizableOperation.ADD_TABLE_GRANT_TO_CATALOG_ROLE; authorizeGrantOnTableLikeOperationOrThrow( - op, catalogName, PolarisEntitySubType.TABLE, identifier, catalogRoleName); + op, catalogName, PolarisEntitySubType.ICEBERG_TABLE, identifier, catalogRoleName); return grantPrivilegeOnTableLikeToRole( - catalogName, catalogRoleName, identifier, PolarisEntitySubType.TABLE, privilege); + catalogName, catalogRoleName, identifier, PolarisEntitySubType.ICEBERG_TABLE, privilege); } public boolean revokePrivilegeOnTableFromRole( @@ -1513,10 +1513,10 @@ public boolean revokePrivilegeOnTableFromRole( PolarisAuthorizableOperation.REVOKE_TABLE_GRANT_FROM_CATALOG_ROLE; authorizeGrantOnTableLikeOperationOrThrow( - op, catalogName, PolarisEntitySubType.TABLE, identifier, catalogRoleName); + op, catalogName, PolarisEntitySubType.ICEBERG_TABLE, identifier, catalogRoleName); return revokePrivilegeOnTableLikeFromRole( - catalogName, catalogRoleName, identifier, PolarisEntitySubType.TABLE, privilege); + catalogName, catalogRoleName, identifier, PolarisEntitySubType.ICEBERG_TABLE, privilege); } public boolean grantPrivilegeOnViewToRole( @@ -1607,9 +1607,9 @@ public List listGrantsForCatalogRole(String catalogName, String c namespaceGrants.add(grant); break; } - case ICEBERG_TABLE_LIKE: + case TABLE_LIKE: { - if (baseEntity.getSubType() == PolarisEntitySubType.TABLE) { + if (baseEntity.getSubType() == PolarisEntitySubType.ICEBERG_TABLE) { TableIdentifier identifier = IcebergTableLikeEntity.of(baseEntity).getTableIdentifier(); TableGrant grant = @@ -1708,7 +1708,7 @@ private boolean grantPrivilegeOnTableLikeToRole( PolarisResolvedPathWrapper resolvedPathWrapper = resolutionManifest.getResolvedPath( - identifier, PolarisEntityType.ICEBERG_TABLE_LIKE, subType); + identifier, PolarisEntityType.TABLE_LIKE, subType); if (resolvedPathWrapper == null) { if (subType == PolarisEntitySubType.VIEW) { throw new NotFoundException("View %s not found", identifier); @@ -1747,7 +1747,7 @@ private boolean revokePrivilegeOnTableLikeFromRole( PolarisResolvedPathWrapper resolvedPathWrapper = resolutionManifest.getResolvedPath( - identifier, PolarisEntityType.ICEBERG_TABLE_LIKE, subType); + identifier, PolarisEntityType.TABLE_LIKE, subType); if (resolvedPathWrapper == null) { if (subType == PolarisEntitySubType.VIEW) { throw new NotFoundException("View %s not found", identifier); diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java index 322b7cb0db..e565f5f763 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java @@ -94,7 +94,7 @@ private PolarisResolvedPathWrapper getTablePath(TableIdentifier tableIdentifier) tableIdentifier, PolarisEntityType.GENERIC_TABLE, PolarisEntitySubType.ANY_SUBTYPE); if (genericTableResult == null) { return resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE); + tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE); } else { return genericTableResult; } diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java index 54434a0754..a249827cef 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java @@ -440,7 +440,7 @@ public boolean dropTable(TableIdentifier tableIdentifier, boolean purge) { }) .orElse(Map.of()); DropEntityResult dropEntityResult = - dropTableLike(PolarisEntitySubType.TABLE, tableIdentifier, storageProperties, purge); + dropTableLike(PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier, storageProperties, purge); if (!dropEntityResult.isSuccess()) { return false; } @@ -463,7 +463,7 @@ public List listTables(Namespace namespace) { "Cannot list tables for namespace. Namespace does not exist: %s", namespace); } - return listTableLike(PolarisEntitySubType.TABLE, namespace); + return listTableLike(PolarisEntitySubType.ICEBERG_TABLE, namespace); } @Override @@ -472,7 +472,7 @@ public void renameTable(TableIdentifier from, TableIdentifier to) { return; } - renameTableLike(PolarisEntitySubType.TABLE, from, to); + renameTableLike(PolarisEntitySubType.ICEBERG_TABLE, from, to); } @Override @@ -825,7 +825,7 @@ public void renameView(TableIdentifier from, TableIdentifier to) { public boolean sendNotification( TableIdentifier identifier, NotificationRequest notificationRequest) { return sendNotificationForTableLike( - PolarisEntitySubType.TABLE, identifier, notificationRequest); + PolarisEntitySubType.ICEBERG_TABLE, identifier, notificationRequest); } @Override @@ -878,7 +878,7 @@ public String transformTableLikeLocation(String specifiedTableLikeLocation) { private @Nonnull Optional findStorageInfo(TableIdentifier tableIdentifier) { PolarisResolvedPathWrapper resolvedTableEntities = resolvedEntityView.getResolvedPath( - tableIdentifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE); + tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE); PolarisResolvedPathWrapper resolvedStorageEntity = resolvedTableEntities == null @@ -895,7 +895,7 @@ public String transformTableLikeLocation(String specifiedTableLikeLocation) { private void validateLocationForTableLike(TableIdentifier identifier, String location) { PolarisResolvedPathWrapper resolvedStorageEntity = resolvedEntityView.getResolvedPath( - identifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE); + identifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE); if (resolvedStorageEntity == null) { resolvedStorageEntity = resolvedEntityView.getResolvedPath(identifier.namespace()); } @@ -1023,7 +1023,7 @@ private void validateNoLocationOverlap( catalog, FeatureConfiguration.ALLOW_TABLE_LOCATION_OVERLAP)) { LOGGER.debug("Skipping location overlap validation for identifier '{}'", identifier); - } else if (validateViewOverlap || entity.getSubType().equals(PolarisEntitySubType.TABLE)) { + } else if (validateViewOverlap || entity.getSubType().equals(PolarisEntitySubType.ICEBERG_TABLE)) { LOGGER.debug("Validating no overlap with sibling tables or namespaces"); validateNoLocationOverlap(location, resolvedNamespace, identifier.name()); } @@ -1068,7 +1068,7 @@ private void validateNoLocationOverlap( parentPath.stream() .map(PolarisEntity::toCore) .collect(Collectors.toList()), - PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE); if (!siblingTablesResult.isSuccess()) { throw new IllegalStateException( @@ -1104,7 +1104,7 @@ private void validateNoLocationOverlap( resolutionManifest.addPath( new ResolverPath( PolarisCatalogHelpers.tableIdentifierToList(tbl), - PolarisEntityType.ICEBERG_TABLE_LIKE), + PolarisEntityType.TABLE_LIKE), tbl)); siblingNamespaces.forEach( ns -> @@ -1193,7 +1193,7 @@ protected PolarisResolvedPathWrapper getTablePath(TableIdentifier tableIdentifie PolarisResolvedPathWrapper icebergTableResult = resolvedEntityView.getPassthroughResolvedPath( tableIdentifier, - PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE); if (icebergTableResult == null) { return resolvedEntityView.getPassthroughResolvedPath( @@ -1210,7 +1210,7 @@ public void doRefresh() { // table entity instead of the statically-resolved authz resolution set. PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE); + tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE); IcebergTableLikeEntity entity = null; if (resolvedEntities != null) { @@ -1264,7 +1264,7 @@ public void doCommit(TableMetadata base, TableMetadata metadata) { PolarisResolvedPathWrapper resolvedTableEntities = resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE); + tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE); // Fetch credentials for the resolved entity. The entity could be the table itself (if it has // already been stored and credentials have been configured directly) or it could be the @@ -1337,7 +1337,7 @@ public void doCommit(TableMetadata base, TableMetadata metadata) { PolarisResolvedPathWrapper resolvedView = resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.VIEW); + tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW); if (resolvedView != null) { throw new AlreadyExistsException("View with same name already exists: %s", tableIdentifier); } @@ -1358,7 +1358,7 @@ public void doCommit(TableMetadata base, TableMetadata metadata) { entity = new IcebergTableLikeEntity.Builder(tableIdentifier, newLocation) .setCatalogId(getCatalogId()) - .setSubType(PolarisEntitySubType.TABLE) + .setSubType(PolarisEntitySubType.ICEBERG_TABLE) .setBaseLocation(metadata.location()) .setId( getMetaStoreManager().generateNewEntityId(getCurrentPolarisContext()).getId()) @@ -1449,7 +1449,7 @@ private class BasePolarisViewOperations extends BaseViewOperations { public void doRefresh() { PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( - identifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.VIEW); + identifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW); IcebergTableLikeEntity entity = null; if (resolvedEntities != null) { @@ -1504,14 +1504,14 @@ public void doCommit(ViewMetadata base, ViewMetadata metadata) { PolarisResolvedPathWrapper resolvedTable = resolvedEntityView.getPassthroughResolvedPath( - identifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE); + identifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE); if (resolvedTable != null) { throw new AlreadyExistsException("Table with same name already exists: %s", identifier); } PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( - identifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.VIEW); + identifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW); // Fetch credentials for the resolved entity. The entity could be the view itself (if it has // already been stored and credentials have been configured directly) or it could be the @@ -1652,7 +1652,7 @@ private void renameTableLike( PolarisEntitySubType subType, TableIdentifier from, TableIdentifier to) { LOGGER.debug("Renaming tableLike from {} to {}", from, to); PolarisResolvedPathWrapper resolvedEntities = - resolvedEntityView.getResolvedPath(from, PolarisEntityType.ICEBERG_TABLE_LIKE, subType); + resolvedEntityView.getResolvedPath(from, PolarisEntityType.TABLE_LIKE, subType); if (resolvedEntities == null) { if (subType == PolarisEntitySubType.VIEW) { throw new NoSuchViewException("Cannot rename %s to %s. View does not exist", from, to); @@ -1713,7 +1713,7 @@ private void renameTableLike( // this code path is unexpected throw new AlreadyExistsException( "Cannot rename %s to %s. Object already exists", from, to); - } else if (existingEntitySubType == PolarisEntitySubType.TABLE) { + } else if (existingEntitySubType == PolarisEntitySubType.ICEBERG_TABLE) { throw new AlreadyExistsException( "Cannot rename %s to %s. Table already exists", from, to); } else if (existingEntitySubType == PolarisEntitySubType.VIEW) { @@ -1866,7 +1866,7 @@ private void updateTableLike(TableIdentifier identifier, PolarisEntity entity) { boolean purge) { PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getResolvedPath( - identifier, PolarisEntityType.ICEBERG_TABLE_LIKE, subType); + identifier, PolarisEntityType.TABLE_LIKE, subType); if (resolvedEntities == null) { // TODO: Error? return new DropEntityResult(BaseResult.ReturnStatus.ENTITY_NOT_FOUND, null); @@ -1911,14 +1911,14 @@ private boolean sendNotificationForTableLike( "Handling notification request {} for tableIdentifier {}", request, tableIdentifier); PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntityType.ICEBERG_TABLE_LIKE, subType); + tableIdentifier, PolarisEntityType.TABLE_LIKE, subType); NotificationType notificationType = request.getNotificationType(); Preconditions.checkNotNull(notificationType, "Expected a valid notification type."); if (notificationType == NotificationType.DROP) { - return dropTableLike(PolarisEntitySubType.TABLE, tableIdentifier, Map.of(), false /* purge */) + return dropTableLike(PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier, Map.of(), false /* purge */) .isSuccess(); } else if (notificationType == NotificationType.VALIDATE) { // In this mode we don't want to make any mutations, so we won't auto-create non-existing @@ -1984,7 +1984,7 @@ private boolean sendNotificationForTableLike( entity = new IcebergTableLikeEntity.Builder(tableIdentifier, newLocation) .setCatalogId(getCatalogId()) - .setSubType(PolarisEntitySubType.TABLE) + .setSubType(PolarisEntitySubType.ICEBERG_TABLE) .setId( getMetaStoreManager().generateNewEntityId(getCurrentPolarisContext()).getId()) .setLastNotificationTimestamp(request.getPayload().getTimestamp()) @@ -2076,7 +2076,7 @@ private List listTableLike(PolarisEntitySubType subType, Namesp .listEntities( getCurrentPolarisContext(), PolarisEntity.toCoreList(catalogPath), - PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntityType.TABLE_LIKE, subType) .getEntities()); return PolarisCatalogHelpers.nameAndIdToTableIdentifiers(catalogPath, entities); diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java index 543ba907c6..db6e0977bf 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java @@ -217,7 +217,7 @@ private void authorizeBasicNamespaceOperationOrThrow( resolutionManifest.addPassthroughPath( new ResolverPath( PolarisCatalogHelpers.tableIdentifierToList(id), - PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntityType.TABLE_LIKE, true /* optional */), id); } @@ -289,7 +289,7 @@ private void authorizeCreateTableLikeUnderNamespaceOperationOrThrow( resolutionManifest.addPassthroughPath( new ResolverPath( PolarisCatalogHelpers.tableIdentifierToList(identifier), - PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntityType.TABLE_LIKE, true /* optional */), identifier); resolutionManifest.resolveAll(); @@ -316,15 +316,15 @@ private void authorizeBasicTableLikeOperationOrThrow( resolutionManifest.addPassthroughPath( new ResolverPath( PolarisCatalogHelpers.tableIdentifierToList(identifier), - PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntityType.TABLE_LIKE, true /* optional */), identifier); resolutionManifest.resolveAll(); PolarisResolvedPathWrapper target = resolutionManifest.getResolvedPath( - identifier, PolarisEntityType.ICEBERG_TABLE_LIKE, subType, true); + identifier, PolarisEntityType.TABLE_LIKE, subType, true); if (target == null) { - if (subType == PolarisEntitySubType.TABLE) { + if (subType == PolarisEntitySubType.ICEBERG_TABLE) { throw new NoSuchTableException("Table does not exist: %s", identifier); } else { throw new NoSuchViewException("View does not exist: %s", identifier); @@ -351,7 +351,7 @@ private void authorizeCollectionOfTableLikeOperationOrThrow( resolutionManifest.addPassthroughPath( new ResolverPath( PolarisCatalogHelpers.tableIdentifierToList(identifier), - PolarisEntityType.ICEBERG_TABLE_LIKE), + PolarisEntityType.TABLE_LIKE), identifier)); ResolverStatus status = resolutionManifest.resolveAll(); @@ -362,7 +362,7 @@ private void authorizeCollectionOfTableLikeOperationOrThrow( TableIdentifier identifier = PolarisCatalogHelpers.listToTableIdentifier( status.getFailedToResolvePath().getEntityNames()); - if (subType == PolarisEntitySubType.TABLE) { + if (subType == PolarisEntitySubType.ICEBERG_TABLE) { throw new NoSuchTableException("Table does not exist: %s", identifier); } else { throw new NoSuchViewException("View does not exist: %s", identifier); @@ -375,10 +375,10 @@ private void authorizeCollectionOfTableLikeOperationOrThrow( identifier -> Optional.ofNullable( resolutionManifest.getResolvedPath( - identifier, PolarisEntityType.ICEBERG_TABLE_LIKE, subType, true)) + identifier, PolarisEntityType.TABLE_LIKE, subType, true)) .orElseThrow( () -> - subType == PolarisEntitySubType.TABLE + subType == PolarisEntitySubType.ICEBERG_TABLE ? new NoSuchTableException( "Table does not exist: %s", identifier) : new NoSuchViewException( @@ -404,7 +404,7 @@ private void authorizeRenameTableLikeOperationOrThrow( // Add src, dstParent, and dst(optional) resolutionManifest.addPath( new ResolverPath( - PolarisCatalogHelpers.tableIdentifierToList(src), PolarisEntityType.ICEBERG_TABLE_LIKE), + PolarisCatalogHelpers.tableIdentifierToList(src), PolarisEntityType.TABLE_LIKE), src); resolutionManifest.addPath( new ResolverPath(Arrays.asList(dst.namespace().levels()), PolarisEntityType.NAMESPACE), @@ -412,7 +412,7 @@ private void authorizeRenameTableLikeOperationOrThrow( resolutionManifest.addPath( new ResolverPath( PolarisCatalogHelpers.tableIdentifierToList(dst), - PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntityType.TABLE_LIKE, true /* optional */), dst); ResolverStatus status = resolutionManifest.resolveAll(); @@ -420,9 +420,9 @@ private void authorizeRenameTableLikeOperationOrThrow( && status.getFailedToResolvePath().getLastEntityType() == PolarisEntityType.NAMESPACE) { throw new NoSuchNamespaceException("Namespace does not exist: %s", dst.namespace()); } else if (resolutionManifest.getResolvedPath( - src, PolarisEntityType.ICEBERG_TABLE_LIKE, subType) + src, PolarisEntityType.TABLE_LIKE, subType) == null) { - if (subType == PolarisEntitySubType.TABLE) { + if (subType == PolarisEntitySubType.ICEBERG_TABLE) { throw new NoSuchTableException("Table does not exist: %s", src); } else { throw new NoSuchViewException("View does not exist: %s", src); @@ -437,7 +437,7 @@ private void authorizeRenameTableLikeOperationOrThrow( // TODO: Possibly modify the exception thrown depending on whether the caller has privileges // on the parent namespace. PolarisEntitySubType dstLeafSubType = resolutionManifest.getLeafSubType(dst); - if (dstLeafSubType == PolarisEntitySubType.TABLE) { + if (dstLeafSubType == PolarisEntitySubType.ICEBERG_TABLE) { throw new AlreadyExistsException("Cannot rename %s to %s. Table already exists", src, dst); } else if (dstLeafSubType == PolarisEntitySubType.VIEW) { throw new AlreadyExistsException("Cannot rename %s to %s. View already exists", src, dst); @@ -445,7 +445,7 @@ private void authorizeRenameTableLikeOperationOrThrow( PolarisResolvedPathWrapper target = resolutionManifest.getResolvedPath( - src, PolarisEntityType.ICEBERG_TABLE_LIKE, subType, true); + src, PolarisEntityType.TABLE_LIKE, subType, true); PolarisResolvedPathWrapper secondary = resolutionManifest.getResolvedPath(dst.namespace(), true); authorizer.authorizeOrThrow( @@ -773,7 +773,7 @@ public boolean sendNotification(TableIdentifier identifier, NotificationRequest public LoadTableResponse loadTable(TableIdentifier tableIdentifier, String snapshots) { PolarisAuthorizableOperation op = PolarisAuthorizableOperation.LOAD_TABLE; - authorizeBasicTableLikeOperationOrThrow(op, PolarisEntitySubType.TABLE, tableIdentifier); + authorizeBasicTableLikeOperationOrThrow(op, PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier); return CatalogHandlers.loadTable(baseCatalog, tableIdentifier); } @@ -795,10 +795,10 @@ public LoadTableResponse loadTableWithAccessDelegation( try { // TODO: Refactor to have a boolean-return version of the helpers so we can fallthrough // easily. - authorizeBasicTableLikeOperationOrThrow(write, PolarisEntitySubType.TABLE, tableIdentifier); + authorizeBasicTableLikeOperationOrThrow(write, PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier); actionsRequested.add(PolarisStorageActions.WRITE); } catch (ForbiddenException e) { - authorizeBasicTableLikeOperationOrThrow(read, PolarisEntitySubType.TABLE, tableIdentifier); + authorizeBasicTableLikeOperationOrThrow(read, PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier); } PolarisResolvedPathWrapper catalogPath = resolutionManifest.getResolvedReferenceCatalogEntity(); @@ -876,7 +876,7 @@ private UpdateTableRequest applyUpdateFilters(UpdateTableRequest request) { public LoadTableResponse updateTable( TableIdentifier tableIdentifier, UpdateTableRequest request) { PolarisAuthorizableOperation op = PolarisAuthorizableOperation.UPDATE_TABLE; - authorizeBasicTableLikeOperationOrThrow(op, PolarisEntitySubType.TABLE, tableIdentifier); + authorizeBasicTableLikeOperationOrThrow(op, PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier); CatalogEntity catalog = CatalogEntity.of( @@ -909,14 +909,14 @@ public LoadTableResponse updateTableForStagedCreate( public void dropTableWithoutPurge(TableIdentifier tableIdentifier) { PolarisAuthorizableOperation op = PolarisAuthorizableOperation.DROP_TABLE_WITHOUT_PURGE; - authorizeBasicTableLikeOperationOrThrow(op, PolarisEntitySubType.TABLE, tableIdentifier); + authorizeBasicTableLikeOperationOrThrow(op, PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier); CatalogHandlers.dropTable(baseCatalog, tableIdentifier); } public void dropTableWithPurge(TableIdentifier tableIdentifier) { PolarisAuthorizableOperation op = PolarisAuthorizableOperation.DROP_TABLE_WITH_PURGE; - authorizeBasicTableLikeOperationOrThrow(op, PolarisEntitySubType.TABLE, tableIdentifier); + authorizeBasicTableLikeOperationOrThrow(op, PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier); CatalogEntity catalog = CatalogEntity.of( @@ -932,7 +932,7 @@ public void dropTableWithPurge(TableIdentifier tableIdentifier) { public void tableExists(TableIdentifier tableIdentifier) { PolarisAuthorizableOperation op = PolarisAuthorizableOperation.TABLE_EXISTS; - authorizeBasicTableLikeOperationOrThrow(op, PolarisEntitySubType.TABLE, tableIdentifier); + authorizeBasicTableLikeOperationOrThrow(op, PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier); // TODO: Just skip CatalogHandlers for this one maybe CatalogHandlers.loadTable(baseCatalog, tableIdentifier); @@ -941,7 +941,7 @@ public void tableExists(TableIdentifier tableIdentifier) { public void renameTable(RenameTableRequest request) { PolarisAuthorizableOperation op = PolarisAuthorizableOperation.RENAME_TABLE; authorizeRenameTableLikeOperationOrThrow( - op, PolarisEntitySubType.TABLE, request.source(), request.destination()); + op, PolarisEntitySubType.ICEBERG_TABLE, request.source(), request.destination()); CatalogEntity catalog = CatalogEntity.of( @@ -963,7 +963,7 @@ public void commitTransaction(CommitTransactionRequest commitTransactionRequest) // needs TABLE_WRITE_PROPERTIES. authorizeCollectionOfTableLikeOperationOrThrow( op, - PolarisEntitySubType.TABLE, + PolarisEntitySubType.ICEBERG_TABLE, commitTransactionRequest.tableChanges().stream() .map(UpdateTableRequest::identifier) .toList()); diff --git a/service/common/src/main/java/org/apache/polaris/service/task/TableCleanupTaskHandler.java b/service/common/src/main/java/org/apache/polaris/service/task/TableCleanupTaskHandler.java index 35ba9440ec..46a508d05c 100644 --- a/service/common/src/main/java/org/apache/polaris/service/task/TableCleanupTaskHandler.java +++ b/service/common/src/main/java/org/apache/polaris/service/task/TableCleanupTaskHandler.java @@ -71,7 +71,7 @@ public boolean canHandleTask(TaskEntity task) { private boolean taskEntityIsTable(TaskEntity task) { PolarisEntity entity = PolarisEntity.of((task.readData(PolarisBaseEntity.class))); - return entity.getType().equals(PolarisEntityType.ICEBERG_TABLE_LIKE); + return entity.getType().equals(PolarisEntityType.TABLE_LIKE); } @Override From 2e8c3f55f3156d5d3c85532787b19be3625f517b Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Tue, 25 Mar 2025 15:26:35 -0700 Subject: [PATCH 11/19] refactor to subtype --- .../polaris/core/entity/TableLikeEntity.java | 22 ------- .../{ => table}/GenericTableEntity.java | 17 +++-- .../{ => table}/IcebergTableLikeEntity.java | 31 ++++------ .../core/entity/table/TableLikeEntity.java | 62 +++++++++++++++++++ .../PolarisStorageConfigurationInfo.java | 2 +- .../catalog/GenericTableCatalogTest.java | 2 +- .../task/TableCleanupTaskHandlerTest.java | 2 +- .../service/admin/PolarisAdminService.java | 2 +- .../catalog/generic/GenericTableCatalog.java | 25 +++----- .../catalog/iceberg/IcebergCatalog.java | 26 +++----- .../service/task/TableCleanupTaskHandler.java | 2 +- .../service/task/TaskFileIOSupplier.java | 2 +- 12 files changed, 105 insertions(+), 90 deletions(-) delete mode 100644 polaris-core/src/main/java/org/apache/polaris/core/entity/TableLikeEntity.java rename polaris-core/src/main/java/org/apache/polaris/core/entity/{ => table}/GenericTableEntity.java (80%) rename polaris-core/src/main/java/org/apache/polaris/core/entity/{ => table}/IcebergTableLikeEntity.java (87%) create mode 100644 polaris-core/src/main/java/org/apache/polaris/core/entity/table/TableLikeEntity.java diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/TableLikeEntity.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/TableLikeEntity.java deleted file mode 100644 index cb13dd1bfc..0000000000 --- a/polaris-core/src/main/java/org/apache/polaris/core/entity/TableLikeEntity.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.polaris.core.entity;public class TableLikeEntity { - -} diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/GenericTableEntity.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/table/GenericTableEntity.java similarity index 80% rename from polaris-core/src/main/java/org/apache/polaris/core/entity/GenericTableEntity.java rename to polaris-core/src/main/java/org/apache/polaris/core/entity/table/GenericTableEntity.java index 5553b1a46c..5730ebe0e2 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/entity/GenericTableEntity.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/table/GenericTableEntity.java @@ -16,19 +16,23 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.polaris.core.entity; +package org.apache.polaris.core.entity.table; import com.fasterxml.jackson.annotation.JsonIgnore; import org.apache.iceberg.catalog.Namespace; import org.apache.iceberg.catalog.TableIdentifier; import org.apache.iceberg.rest.RESTUtil; +import org.apache.polaris.core.entity.NamespaceEntity; +import org.apache.polaris.core.entity.PolarisBaseEntity; +import org.apache.polaris.core.entity.PolarisEntity; +import org.apache.polaris.core.entity.PolarisEntitySubType; +import org.apache.polaris.core.entity.PolarisEntityType; /** - * A {@link PolarisEntity} implementation for generic tables. These tables are not Iceberg-like in - * that they may not have a schema or base location. Similarly to {@link IcebergTableLikeEntity} - * however, these tables have an identifier and a parent namespace. + * A {@link TableLikeEntity} implementation for generic tables. These tables are not Iceberg-like in + * that they may not have a schema or base location. */ -public class GenericTableEntity extends PolarisEntity { +public class GenericTableEntity extends TableLikeEntity { public static final String FORMAT_KEY = "format"; @@ -52,7 +56,8 @@ public static class Builder extends PolarisEntity.BaseBuilder { public Builder(TableIdentifier tableIdentifier, String format) { super(); - setType(PolarisEntityType.GENERIC_TABLE); + setType(PolarisEntityType.TABLE_LIKE); + setSubType(PolarisEntitySubType.GENERIC_TABLE); setTableIdentifier(tableIdentifier); setFormat(format); } diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/IcebergTableLikeEntity.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/table/IcebergTableLikeEntity.java similarity index 87% rename from polaris-core/src/main/java/org/apache/polaris/core/entity/IcebergTableLikeEntity.java rename to polaris-core/src/main/java/org/apache/polaris/core/entity/table/IcebergTableLikeEntity.java index b18f093f80..d383bc89f1 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/entity/IcebergTableLikeEntity.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/table/IcebergTableLikeEntity.java @@ -16,15 +16,24 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.polaris.core.entity; +package org.apache.polaris.core.entity.table; import com.fasterxml.jackson.annotation.JsonIgnore; import java.util.Optional; import org.apache.iceberg.catalog.Namespace; import org.apache.iceberg.catalog.TableIdentifier; import org.apache.iceberg.rest.RESTUtil; - -public class IcebergTableLikeEntity extends PolarisEntity { +import org.apache.polaris.core.entity.NamespaceEntity; +import org.apache.polaris.core.entity.PolarisBaseEntity; +import org.apache.polaris.core.entity.PolarisEntity; +import org.apache.polaris.core.entity.PolarisEntityConstants; +import org.apache.polaris.core.entity.PolarisEntityType; + +/** + * An entity type for {@link TableLikeEntity} instances that conform to iceberg semantics + * around locations. This includes both Iceberg tables and Iceberg views. + */ +public class IcebergTableLikeEntity extends TableLikeEntity { // For applicable types, this key on the "internalProperties" map will return the location // of the internalProperties JSON file. public static final String METADATA_LOCATION_KEY = "metadata-location"; @@ -46,22 +55,6 @@ public static IcebergTableLikeEntity of(PolarisBaseEntity sourceEntity) { return null; } - @JsonIgnore - public TableIdentifier getTableIdentifier() { - Namespace parent = getParentNamespace(); - return TableIdentifier.of(parent, getName()); - } - - @JsonIgnore - public Namespace getParentNamespace() { - String encodedNamespace = - getInternalPropertiesAsMap().get(NamespaceEntity.PARENT_NAMESPACE_KEY); - if (encodedNamespace == null) { - return Namespace.empty(); - } - return RESTUtil.decodeNamespace(encodedNamespace); - } - @JsonIgnore public String getMetadataLocation() { return getInternalPropertiesAsMap().get(METADATA_LOCATION_KEY); diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/table/TableLikeEntity.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/table/TableLikeEntity.java new file mode 100644 index 0000000000..b4dbc35d9e --- /dev/null +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/table/TableLikeEntity.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.polaris.core.entity.table; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import jakarta.annotation.Nonnull; +import org.apache.iceberg.catalog.Namespace; +import org.apache.iceberg.catalog.TableIdentifier; +import org.apache.iceberg.rest.RESTUtil; +import org.apache.polaris.core.entity.NamespaceEntity; +import org.apache.polaris.core.entity.PolarisBaseEntity; +import org.apache.polaris.core.entity.PolarisEntity; +import org.apache.polaris.core.entity.PolarisEntityConstants; +import org.apache.polaris.core.entity.PolarisEntitySubType; +import org.apache.polaris.core.entity.PolarisEntityType; + +import java.util.Map; +import java.util.Optional; + +/** + * An entity type for all table-like entities including Iceberg tables, Iceberg views, + * and generic tables. This entity maps to {@link PolarisEntityType#TABLE_LIKE} + */ +public abstract class TableLikeEntity extends PolarisEntity { + + public TableLikeEntity(@Nonnull PolarisBaseEntity sourceEntity) { + super(sourceEntity); + } + + @JsonIgnore + public TableIdentifier getTableIdentifier() { + Namespace parent = getParentNamespace(); + return TableIdentifier.of(parent, getName()); + } + + @JsonIgnore + public Namespace getParentNamespace() { + String encodedNamespace = + getInternalPropertiesAsMap().get(NamespaceEntity.PARENT_NAMESPACE_KEY); + if (encodedNamespace == null) { + return Namespace.empty(); + } + return RESTUtil.decodeNamespace(encodedNamespace); + } +} diff --git a/polaris-core/src/main/java/org/apache/polaris/core/storage/PolarisStorageConfigurationInfo.java b/polaris-core/src/main/java/org/apache/polaris/core/storage/PolarisStorageConfigurationInfo.java index 161af2884c..ee10fd209a 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/storage/PolarisStorageConfigurationInfo.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/storage/PolarisStorageConfigurationInfo.java @@ -41,7 +41,7 @@ import org.apache.polaris.core.config.FeatureConfiguration; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.CatalogEntity; -import org.apache.polaris.core.entity.IcebergTableLikeEntity; +import org.apache.polaris.core.entity.table.IcebergTableLikeEntity; import org.apache.polaris.core.entity.PolarisEntity; import org.apache.polaris.core.entity.PolarisEntityConstants; import org.apache.polaris.core.storage.aws.AwsStorageConfigurationInfo; diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java index 9fc59cce24..6af8182254 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java @@ -53,7 +53,7 @@ import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.context.RealmContext; import org.apache.polaris.core.entity.CatalogEntity; -import org.apache.polaris.core.entity.GenericTableEntity; +import org.apache.polaris.core.entity.table.GenericTableEntity; import org.apache.polaris.core.entity.PolarisEntity; import org.apache.polaris.core.entity.PolarisEntitySubType; import org.apache.polaris.core.entity.PolarisEntityType; diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/task/TableCleanupTaskHandlerTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/task/TableCleanupTaskHandlerTest.java index d723f6caf0..0bf2326945 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/task/TableCleanupTaskHandlerTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/task/TableCleanupTaskHandlerTest.java @@ -43,7 +43,7 @@ import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.context.RealmContext; import org.apache.polaris.core.entity.AsyncTaskType; -import org.apache.polaris.core.entity.IcebergTableLikeEntity; +import org.apache.polaris.core.entity.table.IcebergTableLikeEntity; import org.apache.polaris.core.entity.PolarisBaseEntity; import org.apache.polaris.core.entity.PolarisEntityType; import org.apache.polaris.core.entity.PolarisTaskConstants; diff --git a/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java b/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java index f80df7c819..e75b512d21 100644 --- a/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java +++ b/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java @@ -69,7 +69,7 @@ import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.CatalogEntity; import org.apache.polaris.core.entity.CatalogRoleEntity; -import org.apache.polaris.core.entity.IcebergTableLikeEntity; +import org.apache.polaris.core.entity.table.IcebergTableLikeEntity; import org.apache.polaris.core.entity.NamespaceEntity; import org.apache.polaris.core.entity.PolarisBaseEntity; import org.apache.polaris.core.entity.PolarisEntity; diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java index e565f5f763..9fd4d50dad 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java @@ -29,7 +29,7 @@ import org.apache.polaris.core.catalog.PolarisCatalogHelpers; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.CatalogEntity; -import org.apache.polaris.core.entity.GenericTableEntity; +import org.apache.polaris.core.entity.table.GenericTableEntity; import org.apache.polaris.core.entity.PolarisEntity; import org.apache.polaris.core.entity.PolarisEntitySubType; import org.apache.polaris.core.entity.PolarisEntityType; @@ -88,18 +88,6 @@ public GenericTableCatalog( this.metaStoreManager = metaStoreManager; } - private PolarisResolvedPathWrapper getTablePath(TableIdentifier tableIdentifier) { - PolarisResolvedPathWrapper genericTableResult = - resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntityType.GENERIC_TABLE, PolarisEntitySubType.ANY_SUBTYPE); - if (genericTableResult == null) { - return resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE); - } else { - return genericTableResult; - } - } - public void createGenericTable( TableIdentifier tableIdentifier, String format, Map properties) { PolarisResolvedPathWrapper resolvedParent = @@ -113,7 +101,8 @@ public void createGenericTable( List catalogPath = resolvedParent.getRawFullPath(); - PolarisResolvedPathWrapper resolvedEntities = getTablePath(tableIdentifier); + PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( + tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE); GenericTableEntity entity = GenericTableEntity.of( resolvedEntities == null ? null : resolvedEntities.getRawLeafEntity()); @@ -161,7 +150,7 @@ public void createGenericTable( public GenericTableEntity loadGenericTable(TableIdentifier tableIdentifier) { PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntityType.GENERIC_TABLE, PolarisEntitySubType.ANY_SUBTYPE); + tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.GENERIC_TABLE); GenericTableEntity entity = GenericTableEntity.of( resolvedEntities == null ? null : resolvedEntities.getRawLeafEntity()); @@ -175,7 +164,7 @@ public GenericTableEntity loadGenericTable(TableIdentifier tableIdentifier) { public boolean dropGenericTable(TableIdentifier tableIdentifier) { PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntityType.GENERIC_TABLE, PolarisEntitySubType.ANY_SUBTYPE); + tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.GENERIC_TABLE); if (resolvedEntities == null) { throw new NoSuchTableException("Generic table does not exist: %s", tableIdentifier); @@ -208,8 +197,8 @@ public List listGenericTables(Namespace namespace) { .listEntities( this.callContext.getPolarisCallContext(), PolarisEntity.toCoreList(catalogPath), - PolarisEntityType.GENERIC_TABLE, - PolarisEntitySubType.ANY_SUBTYPE) + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.GENERIC_TABLE) .getEntities()); return PolarisCatalogHelpers.nameAndIdToTableIdentifiers(catalogPath, entities); } diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java index a249827cef..45f1b30515 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java @@ -83,7 +83,7 @@ import org.apache.polaris.core.config.FeatureConfiguration; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.CatalogEntity; -import org.apache.polaris.core.entity.IcebergTableLikeEntity; +import org.apache.polaris.core.entity.table.IcebergTableLikeEntity; import org.apache.polaris.core.entity.NamespaceEntity; import org.apache.polaris.core.entity.PolarisEntity; import org.apache.polaris.core.entity.PolarisEntityConstants; @@ -1189,20 +1189,6 @@ private class BasePolarisTableOperations extends BaseMetastoreTableOperations { this.tableFileIO = defaultFileIO; } - protected PolarisResolvedPathWrapper getTablePath(TableIdentifier tableIdentifier) { - PolarisResolvedPathWrapper icebergTableResult = - resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, - PolarisEntityType.TABLE_LIKE, - PolarisEntitySubType.ANY_SUBTYPE); - if (icebergTableResult == null) { - return resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntityType.GENERIC_TABLE, PolarisEntitySubType.ANY_SUBTYPE); - } else { - return icebergTableResult; - } - } - @Override public void doRefresh() { LOGGER.debug("doRefresh for tableIdentifier {}", tableIdentifier); @@ -1348,7 +1334,10 @@ public void doCommit(TableMetadata base, TableMetadata metadata) { // concurrent // modification between our checking of unchanged metadataLocation here and actual // persistence-layer commit). - PolarisResolvedPathWrapper resolvedEntities = getTablePath(tableIdentifier); + PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( + tableIdentifier, + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ANY_SUBTYPE); IcebergTableLikeEntity entity = IcebergTableLikeEntity.of( resolvedEntities == null ? null : resolvedEntities.getRawLeafEntity()); @@ -1371,10 +1360,9 @@ public void doCommit(TableMetadata base, TableMetadata metadata) { .setMetadataLocation(newLocation) .build(); } - if (entity.getType() == PolarisEntityType.GENERIC_TABLE) { + if (entity.getSubType() == PolarisEntitySubType.GENERIC_TABLE) { throw new AlreadyExistsException("Table already exists: %s", tableName()); - } - if (!Objects.equal(existingLocation, oldLocation)) { + } else if (!Objects.equal(existingLocation, oldLocation)) { if (null == base) { throw new AlreadyExistsException("Table already exists: %s", tableName()); } diff --git a/service/common/src/main/java/org/apache/polaris/service/task/TableCleanupTaskHandler.java b/service/common/src/main/java/org/apache/polaris/service/task/TableCleanupTaskHandler.java index 46a508d05c..1c6180342d 100644 --- a/service/common/src/main/java/org/apache/polaris/service/task/TableCleanupTaskHandler.java +++ b/service/common/src/main/java/org/apache/polaris/service/task/TableCleanupTaskHandler.java @@ -33,7 +33,7 @@ import org.apache.polaris.core.PolarisCallContext; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.AsyncTaskType; -import org.apache.polaris.core.entity.IcebergTableLikeEntity; +import org.apache.polaris.core.entity.table.IcebergTableLikeEntity; import org.apache.polaris.core.entity.PolarisBaseEntity; import org.apache.polaris.core.entity.PolarisEntity; import org.apache.polaris.core.entity.PolarisEntityType; diff --git a/service/common/src/main/java/org/apache/polaris/service/task/TaskFileIOSupplier.java b/service/common/src/main/java/org/apache/polaris/service/task/TaskFileIOSupplier.java index b87c062718..87dc50c6af 100644 --- a/service/common/src/main/java/org/apache/polaris/service/task/TaskFileIOSupplier.java +++ b/service/common/src/main/java/org/apache/polaris/service/task/TaskFileIOSupplier.java @@ -29,7 +29,7 @@ import org.apache.iceberg.catalog.TableIdentifier; import org.apache.iceberg.io.FileIO; import org.apache.polaris.core.context.CallContext; -import org.apache.polaris.core.entity.IcebergTableLikeEntity; +import org.apache.polaris.core.entity.table.IcebergTableLikeEntity; import org.apache.polaris.core.entity.PolarisTaskConstants; import org.apache.polaris.core.entity.TaskEntity; import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; From 3cfd53f0fb6951d7f1473fe80ca562a5e2221b9f Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Tue, 25 Mar 2025 15:26:39 -0700 Subject: [PATCH 12/19] autolint --- .../core/entity/PolarisEntitySubType.java | 1 - .../polaris/core/entity/PolarisPrivilege.java | 3 +- .../entity/table/IcebergTableLikeEntity.java | 4 +- .../core/entity/table/TableLikeEntity.java | 42 ++++++++----------- .../core/persistence/resolver/Resolver.java | 3 +- .../PolarisStorageConfigurationInfo.java | 2 +- .../core/persistence/EntityCacheTest.java | 3 +- .../core/persistence/ResolverTest.java | 3 +- .../PolarisTestMetaStoreManager.java | 21 ++-------- .../catalog/GenericTableCatalogTest.java | 2 +- .../task/TableCleanupTaskHandlerTest.java | 2 +- .../service/admin/PolarisAdminService.java | 17 +++----- .../catalog/generic/GenericTableCatalog.java | 7 ++-- .../catalog/iceberg/IcebergCatalog.java | 24 +++++------ .../iceberg/IcebergCatalogHandlerWrapper.java | 30 +++++++------ .../service/task/TableCleanupTaskHandler.java | 2 +- .../service/task/TaskFileIOSupplier.java | 2 +- 17 files changed, 72 insertions(+), 96 deletions(-) diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntitySubType.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntitySubType.java index 870d7c32a7..660120a949 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntitySubType.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntitySubType.java @@ -34,7 +34,6 @@ public enum PolarisEntitySubType { VIEW(3, PolarisEntityType.TABLE_LIKE), GENERIC_TABLE(4, PolarisEntityType.TABLE_LIKE); - // to efficiently map the code of a subtype to its corresponding subtype enum, use a reverse // array which is initialized below private static final PolarisEntitySubType[] REVERSE_MAPPING_ARRAY; diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisPrivilege.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisPrivilege.java index 782c622d3c..5a98d53341 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisPrivilege.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisPrivilege.java @@ -76,8 +76,7 @@ public enum PolarisPrivilege { NAMESPACE_MANAGE_GRANTS_ON_SECURABLE(41, PolarisEntityType.NAMESPACE), TABLE_MANAGE_GRANTS_ON_SECURABLE( 42, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE), - VIEW_MANAGE_GRANTS_ON_SECURABLE( - 43, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW), + VIEW_MANAGE_GRANTS_ON_SECURABLE(43, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW), PRINCIPAL_CREATE(44, PolarisEntityType.ROOT), PRINCIPAL_DROP(45, PolarisEntityType.PRINCIPAL), PRINCIPAL_LIST(46, PolarisEntityType.ROOT), diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/table/IcebergTableLikeEntity.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/table/IcebergTableLikeEntity.java index d383bc89f1..026a569b34 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/entity/table/IcebergTableLikeEntity.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/table/IcebergTableLikeEntity.java @@ -30,8 +30,8 @@ import org.apache.polaris.core.entity.PolarisEntityType; /** - * An entity type for {@link TableLikeEntity} instances that conform to iceberg semantics - * around locations. This includes both Iceberg tables and Iceberg views. + * An entity type for {@link TableLikeEntity} instances that conform to iceberg semantics around + * locations. This includes both Iceberg tables and Iceberg views. */ public class IcebergTableLikeEntity extends TableLikeEntity { // For applicable types, this key on the "internalProperties" map will return the location diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/table/TableLikeEntity.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/table/TableLikeEntity.java index b4dbc35d9e..22808d1a7b 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/entity/table/TableLikeEntity.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/table/TableLikeEntity.java @@ -16,7 +16,6 @@ * specific language governing permissions and limitations * under the License. */ - package org.apache.polaris.core.entity.table; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -27,36 +26,31 @@ import org.apache.polaris.core.entity.NamespaceEntity; import org.apache.polaris.core.entity.PolarisBaseEntity; import org.apache.polaris.core.entity.PolarisEntity; -import org.apache.polaris.core.entity.PolarisEntityConstants; -import org.apache.polaris.core.entity.PolarisEntitySubType; import org.apache.polaris.core.entity.PolarisEntityType; -import java.util.Map; -import java.util.Optional; - /** - * An entity type for all table-like entities including Iceberg tables, Iceberg views, - * and generic tables. This entity maps to {@link PolarisEntityType#TABLE_LIKE} + * An entity type for all table-like entities including Iceberg tables, Iceberg views, and generic + * tables. This entity maps to {@link PolarisEntityType#TABLE_LIKE} */ public abstract class TableLikeEntity extends PolarisEntity { - public TableLikeEntity(@Nonnull PolarisBaseEntity sourceEntity) { - super(sourceEntity); - } + public TableLikeEntity(@Nonnull PolarisBaseEntity sourceEntity) { + super(sourceEntity); + } - @JsonIgnore - public TableIdentifier getTableIdentifier() { - Namespace parent = getParentNamespace(); - return TableIdentifier.of(parent, getName()); - } + @JsonIgnore + public TableIdentifier getTableIdentifier() { + Namespace parent = getParentNamespace(); + return TableIdentifier.of(parent, getName()); + } - @JsonIgnore - public Namespace getParentNamespace() { - String encodedNamespace = - getInternalPropertiesAsMap().get(NamespaceEntity.PARENT_NAMESPACE_KEY); - if (encodedNamespace == null) { - return Namespace.empty(); - } - return RESTUtil.decodeNamespace(encodedNamespace); + @JsonIgnore + public Namespace getParentNamespace() { + String encodedNamespace = + getInternalPropertiesAsMap().get(NamespaceEntity.PARENT_NAMESPACE_KEY); + if (encodedNamespace == null) { + return Namespace.empty(); } + return RESTUtil.decodeNamespace(encodedNamespace); + } } diff --git a/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/Resolver.java b/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/Resolver.java index 5f4fa2c68b..b1c7fc1697 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/Resolver.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/Resolver.java @@ -373,8 +373,7 @@ public ResolverStatus resolveAll() { // validate input diagnostics.check( - entityType != PolarisEntityType.NAMESPACE - && entityType != PolarisEntityType.TABLE_LIKE, + entityType != PolarisEntityType.NAMESPACE && entityType != PolarisEntityType.TABLE_LIKE, "cannot_be_path"); diagnostics.check( entityType.isTopLevel() || this.referenceCatalogName != null, "reference_catalog_expected"); diff --git a/polaris-core/src/main/java/org/apache/polaris/core/storage/PolarisStorageConfigurationInfo.java b/polaris-core/src/main/java/org/apache/polaris/core/storage/PolarisStorageConfigurationInfo.java index ee10fd209a..e1ec45bdb8 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/storage/PolarisStorageConfigurationInfo.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/storage/PolarisStorageConfigurationInfo.java @@ -41,9 +41,9 @@ import org.apache.polaris.core.config.FeatureConfiguration; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.CatalogEntity; -import org.apache.polaris.core.entity.table.IcebergTableLikeEntity; import org.apache.polaris.core.entity.PolarisEntity; import org.apache.polaris.core.entity.PolarisEntityConstants; +import org.apache.polaris.core.entity.table.IcebergTableLikeEntity; import org.apache.polaris.core.storage.aws.AwsStorageConfigurationInfo; import org.apache.polaris.core.storage.azure.AzureStorageConfigurationInfo; import org.apache.polaris.core.storage.gcp.GcpStorageConfigurationInfo; diff --git a/polaris-core/src/test/java/org/apache/polaris/core/persistence/EntityCacheTest.java b/polaris-core/src/test/java/org/apache/polaris/core/persistence/EntityCacheTest.java index 463da06c16..6e2f458dcb 100644 --- a/polaris-core/src/test/java/org/apache/polaris/core/persistence/EntityCacheTest.java +++ b/polaris-core/src/test/java/org/apache/polaris/core/persistence/EntityCacheTest.java @@ -435,8 +435,7 @@ void testRenameAndCacheDestinationBeforeLoadingSource() { Assertions.assertThat(lookup).isNotNull(); EntityCacheByNameKey T4_name = - new EntityCacheByNameKey( - N1.getCatalogId(), N1.getId(), PolarisEntityType.TABLE_LIKE, "T4"); + new EntityCacheByNameKey(N1.getCatalogId(), N1.getId(), PolarisEntityType.TABLE_LIKE, "T4"); lookup = cache.getOrLoadEntityByName(callCtx, T4_name); Assertions.assertThat(lookup).isNotNull(); ResolvedPolarisEntity cacheEntry_T4 = lookup.getCacheEntry(); diff --git a/polaris-core/src/test/java/org/apache/polaris/core/persistence/ResolverTest.java b/polaris-core/src/test/java/org/apache/polaris/core/persistence/ResolverTest.java index d725abca60..51ec06a05d 100644 --- a/polaris-core/src/test/java/org/apache/polaris/core/persistence/ResolverTest.java +++ b/polaris-core/src/test/java/org/apache/polaris/core/persistence/ResolverTest.java @@ -277,8 +277,7 @@ void testResolvePath(boolean useCache) { ResolverStatus.StatusEnum.PATH_COULD_NOT_BE_FULLY_RESOLVED); // except if the optional flag is specified - N5_N6_T8 = - new ResolverPath(List.of("N5", "N6", "T8"), PolarisEntityType.TABLE_LIKE, true); + N5_N6_T8 = new ResolverPath(List.of("N5", "N6", "T8"), PolarisEntityType.TABLE_LIKE, true); Resolver resolver = this.resolveDriver(this.cache, "test", null, List.of(N1, N5_N6_T8, N5_N6_T5, N1_N2), null); // get all the resolved paths diff --git a/polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/PolarisTestMetaStoreManager.java b/polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/PolarisTestMetaStoreManager.java index f965e00548..51087df398 100644 --- a/polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/PolarisTestMetaStoreManager.java +++ b/polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/PolarisTestMetaStoreManager.java @@ -1012,10 +1012,7 @@ PolarisBaseEntity createTestCatalog(String catalogName) { PolarisEntitySubType.ICEBERG_TABLE, "T2"); this.createEntity( - List.of(catalog, N1, N1_N2), - PolarisEntityType.TABLE_LIKE, - PolarisEntitySubType.VIEW, - "V1"); + List.of(catalog, N1, N1_N2), PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW, "V1"); PolarisBaseEntity N1_N3 = this.createEntity(List.of(catalog, N1), PolarisEntityType.NAMESPACE, "N3"); this.createEntity( @@ -1024,10 +1021,7 @@ PolarisBaseEntity createTestCatalog(String catalogName) { PolarisEntitySubType.ICEBERG_TABLE, "T3"); this.createEntity( - List.of(catalog, N1, N1_N3), - PolarisEntityType.TABLE_LIKE, - PolarisEntitySubType.VIEW, - "V2"); + List.of(catalog, N1, N1_N3), PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW, "V2"); this.createEntity( List.of(catalog, N1), PolarisEntityType.TABLE_LIKE, @@ -1678,10 +1672,7 @@ void testCreateTestCatalog() { PolarisEntitySubType.ANY_SUBTYPE, "T2"); this.ensureExistsByName( - List.of(catalog, N1, N1_N2), - PolarisEntityType.TABLE_LIKE, - PolarisEntitySubType.VIEW, - "V1"); + List.of(catalog, N1, N1_N2), PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW, "V1"); this.ensureExistsByName( List.of(catalog, N1, N1_N2), PolarisEntityType.TABLE_LIKE, @@ -2436,11 +2427,7 @@ public void testEntityCache() { // now validate that load something which does not exist, will also work this.loadCacheEntryByName( - N1.getCatalogId(), - N1.getId(), - PolarisEntityType.TABLE_LIKE, - "do_not_exists", - false); + N1.getCatalogId(), N1.getId(), PolarisEntityType.TABLE_LIKE, "do_not_exists", false); this.loadCacheEntryById(N1.getCatalogId() + 1000, N1.getId(), N1.getType(), false); // refresh a purged entity diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java index 6af8182254..77a6c00612 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java @@ -53,11 +53,11 @@ import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.context.RealmContext; import org.apache.polaris.core.entity.CatalogEntity; -import org.apache.polaris.core.entity.table.GenericTableEntity; import org.apache.polaris.core.entity.PolarisEntity; import org.apache.polaris.core.entity.PolarisEntitySubType; import org.apache.polaris.core.entity.PolarisEntityType; import org.apache.polaris.core.entity.PrincipalEntity; +import org.apache.polaris.core.entity.table.GenericTableEntity; import org.apache.polaris.core.persistence.MetaStoreManagerFactory; import org.apache.polaris.core.persistence.PolarisEntityManager; import org.apache.polaris.core.persistence.PolarisMetaStoreManager; diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/task/TableCleanupTaskHandlerTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/task/TableCleanupTaskHandlerTest.java index 0bf2326945..33e96e2a16 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/task/TableCleanupTaskHandlerTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/task/TableCleanupTaskHandlerTest.java @@ -43,11 +43,11 @@ import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.context.RealmContext; import org.apache.polaris.core.entity.AsyncTaskType; -import org.apache.polaris.core.entity.table.IcebergTableLikeEntity; import org.apache.polaris.core.entity.PolarisBaseEntity; import org.apache.polaris.core.entity.PolarisEntityType; import org.apache.polaris.core.entity.PolarisTaskConstants; import org.apache.polaris.core.entity.TaskEntity; +import org.apache.polaris.core.entity.table.IcebergTableLikeEntity; import org.apache.polaris.core.persistence.BasePersistence; import org.apache.polaris.core.persistence.MetaStoreManagerFactory; import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; diff --git a/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java b/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java index e75b512d21..00551cec5c 100644 --- a/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java +++ b/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java @@ -69,7 +69,6 @@ import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.CatalogEntity; import org.apache.polaris.core.entity.CatalogRoleEntity; -import org.apache.polaris.core.entity.table.IcebergTableLikeEntity; import org.apache.polaris.core.entity.NamespaceEntity; import org.apache.polaris.core.entity.PolarisBaseEntity; import org.apache.polaris.core.entity.PolarisEntity; @@ -80,6 +79,7 @@ import org.apache.polaris.core.entity.PolarisPrivilege; import org.apache.polaris.core.entity.PrincipalEntity; import org.apache.polaris.core.entity.PrincipalRoleEntity; +import org.apache.polaris.core.entity.table.IcebergTableLikeEntity; import org.apache.polaris.core.persistence.PolarisEntityManager; import org.apache.polaris.core.persistence.PolarisMetaStoreManager; import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; @@ -461,8 +461,7 @@ private void authorizeGrantOnTableLikeOperationOrThrow( entityManager.prepareResolutionManifest(callContext, securityContext, catalogName); resolutionManifest.addPath( new ResolverPath( - PolarisCatalogHelpers.tableIdentifierToList(identifier), - PolarisEntityType.TABLE_LIKE), + PolarisCatalogHelpers.tableIdentifierToList(identifier), PolarisEntityType.TABLE_LIKE), identifier); resolutionManifest.addPath( new ResolverPath(List.of(catalogRoleName), PolarisEntityType.CATALOG_ROLE), @@ -472,8 +471,7 @@ private void authorizeGrantOnTableLikeOperationOrThrow( if (status.getStatus() == ResolverStatus.StatusEnum.ENTITY_COULD_NOT_BE_RESOLVED) { throw new NotFoundException("Catalog not found: %s", catalogName); } else if (status.getStatus() == ResolverStatus.StatusEnum.PATH_COULD_NOT_BE_FULLY_RESOLVED) { - if (status.getFailedToResolvePath().getLastEntityType() - == PolarisEntityType.TABLE_LIKE) { + if (status.getFailedToResolvePath().getLastEntityType() == PolarisEntityType.TABLE_LIKE) { if (subType == PolarisEntitySubType.ICEBERG_TABLE) { throw new NoSuchTableException("Table does not exist: %s", identifier); } else { @@ -485,8 +483,7 @@ private void authorizeGrantOnTableLikeOperationOrThrow( } PolarisResolvedPathWrapper tableLikeWrapper = - resolutionManifest.getResolvedPath( - identifier, PolarisEntityType.TABLE_LIKE, subType, true); + resolutionManifest.getResolvedPath(identifier, PolarisEntityType.TABLE_LIKE, subType, true); PolarisResolvedPathWrapper catalogRoleWrapper = resolutionManifest.getResolvedPath(catalogRoleName, true); @@ -1707,8 +1704,7 @@ private boolean grantPrivilegeOnTableLikeToRole( .orElseThrow(() -> new NotFoundException("CatalogRole %s not found", catalogRoleName)); PolarisResolvedPathWrapper resolvedPathWrapper = - resolutionManifest.getResolvedPath( - identifier, PolarisEntityType.TABLE_LIKE, subType); + resolutionManifest.getResolvedPath(identifier, PolarisEntityType.TABLE_LIKE, subType); if (resolvedPathWrapper == null) { if (subType == PolarisEntitySubType.VIEW) { throw new NotFoundException("View %s not found", identifier); @@ -1746,8 +1742,7 @@ private boolean revokePrivilegeOnTableLikeFromRole( .orElseThrow(() -> new NotFoundException("CatalogRole %s not found", catalogRoleName)); PolarisResolvedPathWrapper resolvedPathWrapper = - resolutionManifest.getResolvedPath( - identifier, PolarisEntityType.TABLE_LIKE, subType); + resolutionManifest.getResolvedPath(identifier, PolarisEntityType.TABLE_LIKE, subType); if (resolvedPathWrapper == null) { if (subType == PolarisEntitySubType.VIEW) { throw new NotFoundException("View %s not found", identifier); diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java index 9fd4d50dad..f686f08e9c 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java @@ -29,10 +29,10 @@ import org.apache.polaris.core.catalog.PolarisCatalogHelpers; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.CatalogEntity; -import org.apache.polaris.core.entity.table.GenericTableEntity; import org.apache.polaris.core.entity.PolarisEntity; import org.apache.polaris.core.entity.PolarisEntitySubType; import org.apache.polaris.core.entity.PolarisEntityType; +import org.apache.polaris.core.entity.table.GenericTableEntity; import org.apache.polaris.core.persistence.PolarisEntityManager; import org.apache.polaris.core.persistence.PolarisMetaStoreManager; import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; @@ -101,8 +101,9 @@ public void createGenericTable( List catalogPath = resolvedParent.getRawFullPath(); - PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE); + PolarisResolvedPathWrapper resolvedEntities = + resolvedEntityView.getPassthroughResolvedPath( + tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE); GenericTableEntity entity = GenericTableEntity.of( resolvedEntities == null ? null : resolvedEntities.getRawLeafEntity()); diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java index 45f1b30515..1240ba11e5 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java @@ -83,13 +83,13 @@ import org.apache.polaris.core.config.FeatureConfiguration; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.CatalogEntity; -import org.apache.polaris.core.entity.table.IcebergTableLikeEntity; import org.apache.polaris.core.entity.NamespaceEntity; import org.apache.polaris.core.entity.PolarisEntity; import org.apache.polaris.core.entity.PolarisEntityConstants; import org.apache.polaris.core.entity.PolarisEntitySubType; import org.apache.polaris.core.entity.PolarisEntityType; import org.apache.polaris.core.entity.PolarisTaskConstants; +import org.apache.polaris.core.entity.table.IcebergTableLikeEntity; import org.apache.polaris.core.persistence.PolarisEntityManager; import org.apache.polaris.core.persistence.PolarisMetaStoreManager; import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; @@ -440,7 +440,8 @@ public boolean dropTable(TableIdentifier tableIdentifier, boolean purge) { }) .orElse(Map.of()); DropEntityResult dropEntityResult = - dropTableLike(PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier, storageProperties, purge); + dropTableLike( + PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier, storageProperties, purge); if (!dropEntityResult.isSuccess()) { return false; } @@ -1023,7 +1024,8 @@ private void validateNoLocationOverlap( catalog, FeatureConfiguration.ALLOW_TABLE_LOCATION_OVERLAP)) { LOGGER.debug("Skipping location overlap validation for identifier '{}'", identifier); - } else if (validateViewOverlap || entity.getSubType().equals(PolarisEntitySubType.ICEBERG_TABLE)) { + } else if (validateViewOverlap + || entity.getSubType().equals(PolarisEntitySubType.ICEBERG_TABLE)) { LOGGER.debug("Validating no overlap with sibling tables or namespaces"); validateNoLocationOverlap(location, resolvedNamespace, identifier.name()); } @@ -1103,8 +1105,7 @@ private void validateNoLocationOverlap( tbl -> resolutionManifest.addPath( new ResolverPath( - PolarisCatalogHelpers.tableIdentifierToList(tbl), - PolarisEntityType.TABLE_LIKE), + PolarisCatalogHelpers.tableIdentifierToList(tbl), PolarisEntityType.TABLE_LIKE), tbl)); siblingNamespaces.forEach( ns -> @@ -1334,10 +1335,9 @@ public void doCommit(TableMetadata base, TableMetadata metadata) { // concurrent // modification between our checking of unchanged metadataLocation here and actual // persistence-layer commit). - PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, - PolarisEntityType.TABLE_LIKE, - PolarisEntitySubType.ANY_SUBTYPE); + PolarisResolvedPathWrapper resolvedEntities = + resolvedEntityView.getPassthroughResolvedPath( + tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE); IcebergTableLikeEntity entity = IcebergTableLikeEntity.of( resolvedEntities == null ? null : resolvedEntities.getRawLeafEntity()); @@ -1853,8 +1853,7 @@ private void updateTableLike(TableIdentifier identifier, PolarisEntity entity) { Map storageProperties, boolean purge) { PolarisResolvedPathWrapper resolvedEntities = - resolvedEntityView.getResolvedPath( - identifier, PolarisEntityType.TABLE_LIKE, subType); + resolvedEntityView.getResolvedPath(identifier, PolarisEntityType.TABLE_LIKE, subType); if (resolvedEntities == null) { // TODO: Error? return new DropEntityResult(BaseResult.ReturnStatus.ENTITY_NOT_FOUND, null); @@ -1906,7 +1905,8 @@ private boolean sendNotificationForTableLike( Preconditions.checkNotNull(notificationType, "Expected a valid notification type."); if (notificationType == NotificationType.DROP) { - return dropTableLike(PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier, Map.of(), false /* purge */) + return dropTableLike( + PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier, Map.of(), false /* purge */) .isSuccess(); } else if (notificationType == NotificationType.VALIDATE) { // In this mode we don't want to make any mutations, so we won't auto-create non-existing diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java index db6e0977bf..1e888a7c71 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java @@ -321,8 +321,7 @@ private void authorizeBasicTableLikeOperationOrThrow( identifier); resolutionManifest.resolveAll(); PolarisResolvedPathWrapper target = - resolutionManifest.getResolvedPath( - identifier, PolarisEntityType.TABLE_LIKE, subType, true); + resolutionManifest.getResolvedPath(identifier, PolarisEntityType.TABLE_LIKE, subType, true); if (target == null) { if (subType == PolarisEntitySubType.ICEBERG_TABLE) { throw new NoSuchTableException("Table does not exist: %s", identifier); @@ -419,8 +418,7 @@ private void authorizeRenameTableLikeOperationOrThrow( if (status.getStatus() == ResolverStatus.StatusEnum.PATH_COULD_NOT_BE_FULLY_RESOLVED && status.getFailedToResolvePath().getLastEntityType() == PolarisEntityType.NAMESPACE) { throw new NoSuchNamespaceException("Namespace does not exist: %s", dst.namespace()); - } else if (resolutionManifest.getResolvedPath( - src, PolarisEntityType.TABLE_LIKE, subType) + } else if (resolutionManifest.getResolvedPath(src, PolarisEntityType.TABLE_LIKE, subType) == null) { if (subType == PolarisEntitySubType.ICEBERG_TABLE) { throw new NoSuchTableException("Table does not exist: %s", src); @@ -444,8 +442,7 @@ private void authorizeRenameTableLikeOperationOrThrow( } PolarisResolvedPathWrapper target = - resolutionManifest.getResolvedPath( - src, PolarisEntityType.TABLE_LIKE, subType, true); + resolutionManifest.getResolvedPath(src, PolarisEntityType.TABLE_LIKE, subType, true); PolarisResolvedPathWrapper secondary = resolutionManifest.getResolvedPath(dst.namespace(), true); authorizer.authorizeOrThrow( @@ -773,7 +770,8 @@ public boolean sendNotification(TableIdentifier identifier, NotificationRequest public LoadTableResponse loadTable(TableIdentifier tableIdentifier, String snapshots) { PolarisAuthorizableOperation op = PolarisAuthorizableOperation.LOAD_TABLE; - authorizeBasicTableLikeOperationOrThrow(op, PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier); + authorizeBasicTableLikeOperationOrThrow( + op, PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier); return CatalogHandlers.loadTable(baseCatalog, tableIdentifier); } @@ -795,10 +793,12 @@ public LoadTableResponse loadTableWithAccessDelegation( try { // TODO: Refactor to have a boolean-return version of the helpers so we can fallthrough // easily. - authorizeBasicTableLikeOperationOrThrow(write, PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier); + authorizeBasicTableLikeOperationOrThrow( + write, PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier); actionsRequested.add(PolarisStorageActions.WRITE); } catch (ForbiddenException e) { - authorizeBasicTableLikeOperationOrThrow(read, PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier); + authorizeBasicTableLikeOperationOrThrow( + read, PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier); } PolarisResolvedPathWrapper catalogPath = resolutionManifest.getResolvedReferenceCatalogEntity(); @@ -876,7 +876,8 @@ private UpdateTableRequest applyUpdateFilters(UpdateTableRequest request) { public LoadTableResponse updateTable( TableIdentifier tableIdentifier, UpdateTableRequest request) { PolarisAuthorizableOperation op = PolarisAuthorizableOperation.UPDATE_TABLE; - authorizeBasicTableLikeOperationOrThrow(op, PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier); + authorizeBasicTableLikeOperationOrThrow( + op, PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier); CatalogEntity catalog = CatalogEntity.of( @@ -909,14 +910,16 @@ public LoadTableResponse updateTableForStagedCreate( public void dropTableWithoutPurge(TableIdentifier tableIdentifier) { PolarisAuthorizableOperation op = PolarisAuthorizableOperation.DROP_TABLE_WITHOUT_PURGE; - authorizeBasicTableLikeOperationOrThrow(op, PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier); + authorizeBasicTableLikeOperationOrThrow( + op, PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier); CatalogHandlers.dropTable(baseCatalog, tableIdentifier); } public void dropTableWithPurge(TableIdentifier tableIdentifier) { PolarisAuthorizableOperation op = PolarisAuthorizableOperation.DROP_TABLE_WITH_PURGE; - authorizeBasicTableLikeOperationOrThrow(op, PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier); + authorizeBasicTableLikeOperationOrThrow( + op, PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier); CatalogEntity catalog = CatalogEntity.of( @@ -932,7 +935,8 @@ public void dropTableWithPurge(TableIdentifier tableIdentifier) { public void tableExists(TableIdentifier tableIdentifier) { PolarisAuthorizableOperation op = PolarisAuthorizableOperation.TABLE_EXISTS; - authorizeBasicTableLikeOperationOrThrow(op, PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier); + authorizeBasicTableLikeOperationOrThrow( + op, PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier); // TODO: Just skip CatalogHandlers for this one maybe CatalogHandlers.loadTable(baseCatalog, tableIdentifier); diff --git a/service/common/src/main/java/org/apache/polaris/service/task/TableCleanupTaskHandler.java b/service/common/src/main/java/org/apache/polaris/service/task/TableCleanupTaskHandler.java index 1c6180342d..f9f1c2f35f 100644 --- a/service/common/src/main/java/org/apache/polaris/service/task/TableCleanupTaskHandler.java +++ b/service/common/src/main/java/org/apache/polaris/service/task/TableCleanupTaskHandler.java @@ -33,11 +33,11 @@ import org.apache.polaris.core.PolarisCallContext; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.AsyncTaskType; -import org.apache.polaris.core.entity.table.IcebergTableLikeEntity; import org.apache.polaris.core.entity.PolarisBaseEntity; import org.apache.polaris.core.entity.PolarisEntity; import org.apache.polaris.core.entity.PolarisEntityType; import org.apache.polaris.core.entity.TaskEntity; +import org.apache.polaris.core.entity.table.IcebergTableLikeEntity; import org.apache.polaris.core.persistence.MetaStoreManagerFactory; import org.apache.polaris.core.persistence.PolarisMetaStoreManager; import org.slf4j.Logger; diff --git a/service/common/src/main/java/org/apache/polaris/service/task/TaskFileIOSupplier.java b/service/common/src/main/java/org/apache/polaris/service/task/TaskFileIOSupplier.java index 87dc50c6af..e3a1ddd48f 100644 --- a/service/common/src/main/java/org/apache/polaris/service/task/TaskFileIOSupplier.java +++ b/service/common/src/main/java/org/apache/polaris/service/task/TaskFileIOSupplier.java @@ -29,9 +29,9 @@ import org.apache.iceberg.catalog.TableIdentifier; import org.apache.iceberg.io.FileIO; import org.apache.polaris.core.context.CallContext; -import org.apache.polaris.core.entity.table.IcebergTableLikeEntity; import org.apache.polaris.core.entity.PolarisTaskConstants; import org.apache.polaris.core.entity.TaskEntity; +import org.apache.polaris.core.entity.table.IcebergTableLikeEntity; import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; import org.apache.polaris.core.persistence.ResolvedPolarisEntity; import org.apache.polaris.core.storage.PolarisStorageActions; From 5f6fe0eb9248133da8d224ec651b129b508a0fcb Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Tue, 25 Mar 2025 15:51:02 -0700 Subject: [PATCH 13/19] rebase --- .../datacompaction/DataCompactionPolicyValidator.java | 6 +++--- .../validator/DataCompactionPolicyValidatorTest.java | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/polaris-core/src/main/java/org/apache/polaris/core/policy/validator/datacompaction/DataCompactionPolicyValidator.java b/polaris-core/src/main/java/org/apache/polaris/core/policy/validator/datacompaction/DataCompactionPolicyValidator.java index 8ef8b4dcff..344c72d909 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/policy/validator/datacompaction/DataCompactionPolicyValidator.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/policy/validator/datacompaction/DataCompactionPolicyValidator.java @@ -19,8 +19,8 @@ package org.apache.polaris.core.policy.validator.datacompaction; import static org.apache.polaris.core.entity.PolarisEntityType.CATALOG; -import static org.apache.polaris.core.entity.PolarisEntityType.ICEBERG_TABLE_LIKE; import static org.apache.polaris.core.entity.PolarisEntityType.NAMESPACE; +import static org.apache.polaris.core.entity.PolarisEntityType.TABLE_LIKE; import java.util.Set; import org.apache.polaris.core.entity.PolarisEntitySubType; @@ -32,7 +32,7 @@ public class DataCompactionPolicyValidator implements PolicyValidator { public static final DataCompactionPolicyValidator INSTANCE = new DataCompactionPolicyValidator(); private static final Set ATTACHABLE_ENTITY_TYPES = - Set.of(CATALOG, NAMESPACE, ICEBERG_TABLE_LIKE); + Set.of(CATALOG, NAMESPACE, TABLE_LIKE); @Override public void validate(String content) throws InvalidPolicyException { @@ -49,7 +49,7 @@ public boolean canAttach(PolarisEntityType entityType, PolarisEntitySubType enti return false; } - if (entityType == ICEBERG_TABLE_LIKE && entitySubType != PolarisEntitySubType.TABLE) { + if (entityType == TABLE_LIKE && entitySubType != PolarisEntitySubType.ICEBERG_TABLE) { return false; } diff --git a/polaris-core/src/test/java/org/apache/polaris/core/policy/validator/DataCompactionPolicyValidatorTest.java b/polaris-core/src/test/java/org/apache/polaris/core/policy/validator/DataCompactionPolicyValidatorTest.java index e833015d67..e0b6811093 100644 --- a/polaris-core/src/test/java/org/apache/polaris/core/policy/validator/DataCompactionPolicyValidatorTest.java +++ b/polaris-core/src/test/java/org/apache/polaris/core/policy/validator/DataCompactionPolicyValidatorTest.java @@ -19,15 +19,15 @@ package org.apache.polaris.core.policy.validator; import static org.apache.polaris.core.entity.PolarisEntitySubType.ANY_SUBTYPE; -import static org.apache.polaris.core.entity.PolarisEntitySubType.TABLE; +import static org.apache.polaris.core.entity.PolarisEntitySubType.ICEBERG_TABLE; import static org.apache.polaris.core.entity.PolarisEntitySubType.VIEW; import static org.apache.polaris.core.entity.PolarisEntityType.CATALOG; -import static org.apache.polaris.core.entity.PolarisEntityType.ICEBERG_TABLE_LIKE; import static org.apache.polaris.core.entity.PolarisEntityType.NAMESPACE; import static org.apache.polaris.core.entity.PolarisEntityType.PRINCIPAL; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import org.apache.polaris.core.entity.PolarisEntityType; import org.apache.polaris.core.policy.validator.datacompaction.DataCompactionPolicyValidator; import org.junit.jupiter.api.Test; @@ -59,7 +59,7 @@ public void testCanAttachReturnsTrueForNamespaceType() { @Test public void testCanAttachReturnsTrueForIcebergTableLikeWithTableSubtype() { - var result = validator.canAttach(ICEBERG_TABLE_LIKE, TABLE); + var result = validator.canAttach(PolarisEntityType.TABLE_LIKE, ICEBERG_TABLE); assertThat(result) .isTrue() .as("Expected canAttach() to return true for ICEBERG_TABLE_LIKE with TABLE subtype"); @@ -68,7 +68,7 @@ public void testCanAttachReturnsTrueForIcebergTableLikeWithTableSubtype() { @Test public void testCanAttachReturnsFalseForIcebergTableLikeWithNonTableSubtype() { // For ICEBERG_TABLE_LIKE, any subtype other than TABLE should return false. - boolean result = validator.canAttach(ICEBERG_TABLE_LIKE, VIEW); + boolean result = validator.canAttach(PolarisEntityType.TABLE_LIKE, VIEW); assertThat(result) .isFalse() .as("Expected canAttach() to return false for ICEBERG_TABLE_LIKE with non-TABLE subtype"); From b7ac95343aa0d4c9daebdd75f872663bbbcf6d96 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Tue, 25 Mar 2025 16:15:11 -0700 Subject: [PATCH 14/19] add another assert --- .../service/quarkus/catalog/GenericTableCatalogTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java index 77a6c00612..8299b4128a 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java @@ -534,6 +534,10 @@ public void testDropIcebergTable() { Assertions.assertThatCode( () -> genericTableCatalog.dropGenericTable(TableIdentifier.of("ns", "t1"))) .hasMessageContaining("Generic table does not exist: ns.t1"); + + Assertions.assertThatCode( + () -> icebergCatalog.dropTable(TableIdentifier.of("ns", "t1"))). + doesNotThrowAnyException(); } @Test From f4ab8919b1de8cfe048115a493ba70ba598b09a3 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Tue, 25 Mar 2025 16:15:13 -0700 Subject: [PATCH 15/19] autolint --- .../service/quarkus/catalog/GenericTableCatalogTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java index 8299b4128a..9fcdabc24e 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java @@ -535,9 +535,8 @@ public void testDropIcebergTable() { () -> genericTableCatalog.dropGenericTable(TableIdentifier.of("ns", "t1"))) .hasMessageContaining("Generic table does not exist: ns.t1"); - Assertions.assertThatCode( - () -> icebergCatalog.dropTable(TableIdentifier.of("ns", "t1"))). - doesNotThrowAnyException(); + Assertions.assertThatCode(() -> icebergCatalog.dropTable(TableIdentifier.of("ns", "t1"))) + .doesNotThrowAnyException(); } @Test From e6f81708f39bfedcb0c1d89d3530ac93797cec48 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Tue, 25 Mar 2025 19:17:01 -0700 Subject: [PATCH 16/19] add another best effort check --- .../core/entity/PolarisEntitySubType.java | 2 +- .../polaris/core/entity/PolarisPrivilege.java | 12 +++---- .../DataCompactionPolicyValidatorTest.java | 4 +-- .../PolarisTestMetaStoreManager.java | 16 +++++----- .../service/admin/PolarisAdminService.java | 12 +++---- .../catalog/iceberg/IcebergCatalog.java | 31 +++++++++++-------- .../iceberg/IcebergCatalogHandlerWrapper.java | 12 +++---- 7 files changed, 47 insertions(+), 42 deletions(-) diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntitySubType.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntitySubType.java index 660120a949..2d2c666cb0 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntitySubType.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntitySubType.java @@ -31,7 +31,7 @@ public enum PolarisEntitySubType { // the NULL value is used when an entity has no subtype, i.e. NOT_APPLICABLE really NULL_SUBTYPE(0, null), ICEBERG_TABLE(2, PolarisEntityType.TABLE_LIKE), - VIEW(3, PolarisEntityType.TABLE_LIKE), + ICEBERG_VIEW(3, PolarisEntityType.TABLE_LIKE), GENERIC_TABLE(4, PolarisEntityType.TABLE_LIKE); // to efficiently map the code of a subtype to its corresponding subtype enum, use a reverse diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisPrivilege.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisPrivilege.java index 5a98d53341..6ce4a9de71 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisPrivilege.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisPrivilege.java @@ -42,21 +42,21 @@ public enum PolarisPrivilege { VIEW_CREATE(7, PolarisEntityType.NAMESPACE), NAMESPACE_DROP(8, PolarisEntityType.NAMESPACE), TABLE_DROP(9, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE), - VIEW_DROP(10, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW), + VIEW_DROP(10, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_VIEW), NAMESPACE_LIST(11, PolarisEntityType.NAMESPACE), TABLE_LIST(12, PolarisEntityType.NAMESPACE), VIEW_LIST(13, PolarisEntityType.NAMESPACE), NAMESPACE_READ_PROPERTIES(14, PolarisEntityType.NAMESPACE), TABLE_READ_PROPERTIES(15, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE), - VIEW_READ_PROPERTIES(16, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW), + VIEW_READ_PROPERTIES(16, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_VIEW), NAMESPACE_WRITE_PROPERTIES(17, PolarisEntityType.NAMESPACE), TABLE_WRITE_PROPERTIES(18, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE), - VIEW_WRITE_PROPERTIES(19, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW), + VIEW_WRITE_PROPERTIES(19, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_VIEW), TABLE_READ_DATA(20, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE), TABLE_WRITE_DATA(21, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE), NAMESPACE_FULL_METADATA(22, PolarisEntityType.NAMESPACE), TABLE_FULL_METADATA(23, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE), - VIEW_FULL_METADATA(24, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW), + VIEW_FULL_METADATA(24, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_VIEW), CATALOG_CREATE(25, PolarisEntityType.ROOT), CATALOG_DROP(26, PolarisEntityType.CATALOG), CATALOG_LIST(27, PolarisEntityType.ROOT), @@ -71,12 +71,12 @@ public enum PolarisPrivilege { CATALOG_LIST_GRANTS(36, PolarisEntityType.CATALOG), NAMESPACE_LIST_GRANTS(37, PolarisEntityType.NAMESPACE), TABLE_LIST_GRANTS(38, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE), - VIEW_LIST_GRANTS(39, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW), + VIEW_LIST_GRANTS(39, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_VIEW), CATALOG_MANAGE_GRANTS_ON_SECURABLE(40, PolarisEntityType.CATALOG), NAMESPACE_MANAGE_GRANTS_ON_SECURABLE(41, PolarisEntityType.NAMESPACE), TABLE_MANAGE_GRANTS_ON_SECURABLE( 42, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE), - VIEW_MANAGE_GRANTS_ON_SECURABLE(43, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW), + VIEW_MANAGE_GRANTS_ON_SECURABLE(43, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_VIEW), PRINCIPAL_CREATE(44, PolarisEntityType.ROOT), PRINCIPAL_DROP(45, PolarisEntityType.PRINCIPAL), PRINCIPAL_LIST(46, PolarisEntityType.ROOT), diff --git a/polaris-core/src/test/java/org/apache/polaris/core/policy/validator/DataCompactionPolicyValidatorTest.java b/polaris-core/src/test/java/org/apache/polaris/core/policy/validator/DataCompactionPolicyValidatorTest.java index e0b6811093..18205763fa 100644 --- a/polaris-core/src/test/java/org/apache/polaris/core/policy/validator/DataCompactionPolicyValidatorTest.java +++ b/polaris-core/src/test/java/org/apache/polaris/core/policy/validator/DataCompactionPolicyValidatorTest.java @@ -20,7 +20,7 @@ import static org.apache.polaris.core.entity.PolarisEntitySubType.ANY_SUBTYPE; import static org.apache.polaris.core.entity.PolarisEntitySubType.ICEBERG_TABLE; -import static org.apache.polaris.core.entity.PolarisEntitySubType.VIEW; +import static org.apache.polaris.core.entity.PolarisEntitySubType.ICEBERG_VIEW; import static org.apache.polaris.core.entity.PolarisEntityType.CATALOG; import static org.apache.polaris.core.entity.PolarisEntityType.NAMESPACE; import static org.apache.polaris.core.entity.PolarisEntityType.PRINCIPAL; @@ -68,7 +68,7 @@ public void testCanAttachReturnsTrueForIcebergTableLikeWithTableSubtype() { @Test public void testCanAttachReturnsFalseForIcebergTableLikeWithNonTableSubtype() { // For ICEBERG_TABLE_LIKE, any subtype other than TABLE should return false. - boolean result = validator.canAttach(PolarisEntityType.TABLE_LIKE, VIEW); + boolean result = validator.canAttach(PolarisEntityType.TABLE_LIKE, ICEBERG_VIEW); assertThat(result) .isFalse() .as("Expected canAttach() to return false for ICEBERG_TABLE_LIKE with non-TABLE subtype"); diff --git a/polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/PolarisTestMetaStoreManager.java b/polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/PolarisTestMetaStoreManager.java index 51087df398..0904f48079 100644 --- a/polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/PolarisTestMetaStoreManager.java +++ b/polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/PolarisTestMetaStoreManager.java @@ -1012,7 +1012,7 @@ PolarisBaseEntity createTestCatalog(String catalogName) { PolarisEntitySubType.ICEBERG_TABLE, "T2"); this.createEntity( - List.of(catalog, N1, N1_N2), PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW, "V1"); + List.of(catalog, N1, N1_N2), PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_VIEW, "V1"); PolarisBaseEntity N1_N3 = this.createEntity(List.of(catalog, N1), PolarisEntityType.NAMESPACE, "N3"); this.createEntity( @@ -1021,7 +1021,7 @@ PolarisBaseEntity createTestCatalog(String catalogName) { PolarisEntitySubType.ICEBERG_TABLE, "T3"); this.createEntity( - List.of(catalog, N1, N1_N3), PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW, "V2"); + List.of(catalog, N1, N1_N3), PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_VIEW, "V2"); this.createEntity( List.of(catalog, N1), PolarisEntityType.TABLE_LIKE, @@ -1672,7 +1672,7 @@ void testCreateTestCatalog() { PolarisEntitySubType.ANY_SUBTYPE, "T2"); this.ensureExistsByName( - List.of(catalog, N1, N1_N2), PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW, "V1"); + List.of(catalog, N1, N1_N2), PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_VIEW, "V1"); this.ensureExistsByName( List.of(catalog, N1, N1_N2), PolarisEntityType.TABLE_LIKE, @@ -1833,7 +1833,7 @@ void testBrowse() { List.of( ImmutablePair.of("T1", PolarisEntitySubType.ICEBERG_TABLE), ImmutablePair.of("T2", PolarisEntitySubType.ICEBERG_TABLE), - ImmutablePair.of("V1", PolarisEntitySubType.VIEW))); + ImmutablePair.of("V1", PolarisEntitySubType.ICEBERG_VIEW))); // table object only this.validateListReturn( List.of(catalog, N1, N1_N2), @@ -1846,8 +1846,8 @@ void testBrowse() { this.validateListReturn( List.of(catalog, N1, N1_N2), PolarisEntityType.TABLE_LIKE, - PolarisEntitySubType.VIEW, - List.of(ImmutablePair.of("V1", PolarisEntitySubType.VIEW))); + PolarisEntitySubType.ICEBERG_VIEW, + List.of(ImmutablePair.of("V1", PolarisEntitySubType.ICEBERG_VIEW))); // list all principals this.validateListReturn( null, @@ -2007,7 +2007,7 @@ void testDropEntities() { this.ensureExistsByName( List.of(catalog, N1, N1_N2), PolarisEntityType.TABLE_LIKE, - PolarisEntitySubType.VIEW, + PolarisEntitySubType.ICEBERG_VIEW, "V1"); this.dropEntity(List.of(catalog, N1, N1_N2), V1); this.dropEntity(List.of(catalog, N1), N1_N2); @@ -2025,7 +2025,7 @@ void testDropEntities() { this.ensureExistsByName( List.of(catalog, N1, N1_N3), PolarisEntityType.TABLE_LIKE, - PolarisEntitySubType.VIEW, + PolarisEntitySubType.ICEBERG_VIEW, "V2"); this.dropEntity(List.of(catalog, N1, N1_N3), V2); this.dropEntity(List.of(catalog, N1), N1_N3); diff --git a/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java b/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java index 00551cec5c..effcededd4 100644 --- a/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java +++ b/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java @@ -1524,10 +1524,10 @@ public boolean grantPrivilegeOnViewToRole( PolarisAuthorizableOperation op = PolarisAuthorizableOperation.ADD_VIEW_GRANT_TO_CATALOG_ROLE; authorizeGrantOnTableLikeOperationOrThrow( - op, catalogName, PolarisEntitySubType.VIEW, identifier, catalogRoleName); + op, catalogName, PolarisEntitySubType.ICEBERG_VIEW, identifier, catalogRoleName); return grantPrivilegeOnTableLikeToRole( - catalogName, catalogRoleName, identifier, PolarisEntitySubType.VIEW, privilege); + catalogName, catalogRoleName, identifier, PolarisEntitySubType.ICEBERG_VIEW, privilege); } public boolean revokePrivilegeOnViewFromRole( @@ -1539,10 +1539,10 @@ public boolean revokePrivilegeOnViewFromRole( PolarisAuthorizableOperation.REVOKE_VIEW_GRANT_FROM_CATALOG_ROLE; authorizeGrantOnTableLikeOperationOrThrow( - op, catalogName, PolarisEntitySubType.VIEW, identifier, catalogRoleName); + op, catalogName, PolarisEntitySubType.ICEBERG_VIEW, identifier, catalogRoleName); return revokePrivilegeOnTableLikeFromRole( - catalogName, catalogRoleName, identifier, PolarisEntitySubType.VIEW, privilege); + catalogName, catalogRoleName, identifier, PolarisEntitySubType.ICEBERG_VIEW, privilege); } public List listAssigneePrincipalRolesForCatalogRole( @@ -1706,7 +1706,7 @@ private boolean grantPrivilegeOnTableLikeToRole( PolarisResolvedPathWrapper resolvedPathWrapper = resolutionManifest.getResolvedPath(identifier, PolarisEntityType.TABLE_LIKE, subType); if (resolvedPathWrapper == null) { - if (subType == PolarisEntitySubType.VIEW) { + if (subType == PolarisEntitySubType.ICEBERG_VIEW) { throw new NotFoundException("View %s not found", identifier); } else { throw new NotFoundException("Table %s not found", identifier); @@ -1744,7 +1744,7 @@ private boolean revokePrivilegeOnTableLikeFromRole( PolarisResolvedPathWrapper resolvedPathWrapper = resolutionManifest.getResolvedPath(identifier, PolarisEntityType.TABLE_LIKE, subType); if (resolvedPathWrapper == null) { - if (subType == PolarisEntitySubType.VIEW) { + if (subType == PolarisEntitySubType.ICEBERG_VIEW) { throw new NotFoundException("View %s not found", identifier); } else { throw new NotFoundException("Table %s not found", identifier); diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java index 1240ba11e5..a579655beb 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java @@ -800,7 +800,7 @@ public List listViews(Namespace namespace) { "Cannot list views for namespace. Namespace does not exist: %s", namespace); } - return listTableLike(PolarisEntitySubType.VIEW, namespace); + return listTableLike(PolarisEntitySubType.ICEBERG_VIEW, namespace); } @Override @@ -810,7 +810,7 @@ protected ViewOperations newViewOps(TableIdentifier identifier) { @Override public boolean dropView(TableIdentifier identifier) { - return dropTableLike(PolarisEntitySubType.VIEW, identifier, Map.of(), true).isSuccess(); + return dropTableLike(PolarisEntitySubType.ICEBERG_VIEW, identifier, Map.of(), true).isSuccess(); } @Override @@ -819,7 +819,7 @@ public void renameView(TableIdentifier from, TableIdentifier to) { return; } - renameTableLike(PolarisEntitySubType.VIEW, from, to); + renameTableLike(PolarisEntitySubType.ICEBERG_VIEW, from, to); } @Override @@ -1324,11 +1324,18 @@ public void doCommit(TableMetadata base, TableMetadata metadata) { PolarisResolvedPathWrapper resolvedView = resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW); + tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_VIEW); if (resolvedView != null) { throw new AlreadyExistsException("View with same name already exists: %s", tableIdentifier); } + PolarisResolvedPathWrapper resolvedGenericTable = + resolvedEntityView.getPassthroughResolvedPath( + tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.GENERIC_TABLE); + if (resolvedGenericTable != null) { + throw new AlreadyExistsException("Generic table with same name already exists: %s", tableIdentifier); + } + // TODO: Consider using the entity from doRefresh() directly to do the conflict detection // instead of a two-layer CAS (checking metadataLocation to detect concurrent modification // between doRefresh() and doCommit(), and then updateEntityPropertiesIfNotChanged to detect @@ -1337,7 +1344,7 @@ public void doCommit(TableMetadata base, TableMetadata metadata) { // persistence-layer commit). PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE); + tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE); IcebergTableLikeEntity entity = IcebergTableLikeEntity.of( resolvedEntities == null ? null : resolvedEntities.getRawLeafEntity()); @@ -1360,9 +1367,7 @@ public void doCommit(TableMetadata base, TableMetadata metadata) { .setMetadataLocation(newLocation) .build(); } - if (entity.getSubType() == PolarisEntitySubType.GENERIC_TABLE) { - throw new AlreadyExistsException("Table already exists: %s", tableName()); - } else if (!Objects.equal(existingLocation, oldLocation)) { + if (!Objects.equal(existingLocation, oldLocation)) { if (null == base) { throw new AlreadyExistsException("Table already exists: %s", tableName()); } @@ -1437,7 +1442,7 @@ private class BasePolarisViewOperations extends BaseViewOperations { public void doRefresh() { PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( - identifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW); + identifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_VIEW); IcebergTableLikeEntity entity = null; if (resolvedEntities != null) { @@ -1499,7 +1504,7 @@ public void doCommit(ViewMetadata base, ViewMetadata metadata) { PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( - identifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW); + identifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_VIEW); // Fetch credentials for the resolved entity. The entity could be the view itself (if it has // already been stored and credentials have been configured directly) or it could be the @@ -1547,7 +1552,7 @@ public void doCommit(ViewMetadata base, ViewMetadata metadata) { entity = new IcebergTableLikeEntity.Builder(identifier, newLocation) .setCatalogId(getCatalogId()) - .setSubType(PolarisEntitySubType.VIEW) + .setSubType(PolarisEntitySubType.ICEBERG_VIEW) .setId( getMetaStoreManager().generateNewEntityId(getCurrentPolarisContext()).getId()) .build(); @@ -1642,7 +1647,7 @@ private void renameTableLike( PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getResolvedPath(from, PolarisEntityType.TABLE_LIKE, subType); if (resolvedEntities == null) { - if (subType == PolarisEntitySubType.VIEW) { + if (subType == PolarisEntitySubType.ICEBERG_VIEW) { throw new NoSuchViewException("Cannot rename %s to %s. View does not exist", from, to); } else { throw new NoSuchTableException("Cannot rename %s to %s. Table does not exist", from, to); @@ -1704,7 +1709,7 @@ private void renameTableLike( } else if (existingEntitySubType == PolarisEntitySubType.ICEBERG_TABLE) { throw new AlreadyExistsException( "Cannot rename %s to %s. Table already exists", from, to); - } else if (existingEntitySubType == PolarisEntitySubType.VIEW) { + } else if (existingEntitySubType == PolarisEntitySubType.ICEBERG_VIEW) { throw new AlreadyExistsException( "Cannot rename %s to %s. View already exists", from, to); } diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java index 1e888a7c71..fab2453e7b 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java @@ -437,7 +437,7 @@ private void authorizeRenameTableLikeOperationOrThrow( PolarisEntitySubType dstLeafSubType = resolutionManifest.getLeafSubType(dst); if (dstLeafSubType == PolarisEntitySubType.ICEBERG_TABLE) { throw new AlreadyExistsException("Cannot rename %s to %s. Table already exists", src, dst); - } else if (dstLeafSubType == PolarisEntitySubType.VIEW) { + } else if (dstLeafSubType == PolarisEntitySubType.ICEBERG_VIEW) { throw new AlreadyExistsException("Cannot rename %s to %s. View already exists", src, dst); } @@ -1091,14 +1091,14 @@ public LoadViewResponse createView(Namespace namespace, CreateViewRequest reques public LoadViewResponse loadView(TableIdentifier viewIdentifier) { PolarisAuthorizableOperation op = PolarisAuthorizableOperation.LOAD_VIEW; - authorizeBasicTableLikeOperationOrThrow(op, PolarisEntitySubType.VIEW, viewIdentifier); + authorizeBasicTableLikeOperationOrThrow(op, PolarisEntitySubType.ICEBERG_VIEW, viewIdentifier); return CatalogHandlers.loadView(viewCatalog, viewIdentifier); } public LoadViewResponse replaceView(TableIdentifier viewIdentifier, UpdateTableRequest request) { PolarisAuthorizableOperation op = PolarisAuthorizableOperation.REPLACE_VIEW; - authorizeBasicTableLikeOperationOrThrow(op, PolarisEntitySubType.VIEW, viewIdentifier); + authorizeBasicTableLikeOperationOrThrow(op, PolarisEntitySubType.ICEBERG_VIEW, viewIdentifier); CatalogEntity catalog = CatalogEntity.of( @@ -1114,14 +1114,14 @@ public LoadViewResponse replaceView(TableIdentifier viewIdentifier, UpdateTableR public void dropView(TableIdentifier viewIdentifier) { PolarisAuthorizableOperation op = PolarisAuthorizableOperation.DROP_VIEW; - authorizeBasicTableLikeOperationOrThrow(op, PolarisEntitySubType.VIEW, viewIdentifier); + authorizeBasicTableLikeOperationOrThrow(op, PolarisEntitySubType.ICEBERG_VIEW, viewIdentifier); CatalogHandlers.dropView(viewCatalog, viewIdentifier); } public void viewExists(TableIdentifier viewIdentifier) { PolarisAuthorizableOperation op = PolarisAuthorizableOperation.VIEW_EXISTS; - authorizeBasicTableLikeOperationOrThrow(op, PolarisEntitySubType.VIEW, viewIdentifier); + authorizeBasicTableLikeOperationOrThrow(op, PolarisEntitySubType.ICEBERG_VIEW, viewIdentifier); // TODO: Just skip CatalogHandlers for this one maybe CatalogHandlers.loadView(viewCatalog, viewIdentifier); @@ -1130,7 +1130,7 @@ public void viewExists(TableIdentifier viewIdentifier) { public void renameView(RenameTableRequest request) { PolarisAuthorizableOperation op = PolarisAuthorizableOperation.RENAME_VIEW; authorizeRenameTableLikeOperationOrThrow( - op, PolarisEntitySubType.VIEW, request.source(), request.destination()); + op, PolarisEntitySubType.ICEBERG_VIEW, request.source(), request.destination()); CatalogEntity catalog = CatalogEntity.of( From b67706741235cd1bd91fca96953fc62e67ee9419 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Tue, 25 Mar 2025 19:17:04 -0700 Subject: [PATCH 17/19] autolint --- .../polaris/core/entity/PolarisPrivilege.java | 3 ++- .../persistence/PolarisTestMetaStoreManager.java | 15 ++++++++++++--- .../service/catalog/iceberg/IcebergCatalog.java | 3 ++- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisPrivilege.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisPrivilege.java index 6ce4a9de71..8fb0990e21 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisPrivilege.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisPrivilege.java @@ -76,7 +76,8 @@ public enum PolarisPrivilege { NAMESPACE_MANAGE_GRANTS_ON_SECURABLE(41, PolarisEntityType.NAMESPACE), TABLE_MANAGE_GRANTS_ON_SECURABLE( 42, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE), - VIEW_MANAGE_GRANTS_ON_SECURABLE(43, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_VIEW), + VIEW_MANAGE_GRANTS_ON_SECURABLE( + 43, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_VIEW), PRINCIPAL_CREATE(44, PolarisEntityType.ROOT), PRINCIPAL_DROP(45, PolarisEntityType.PRINCIPAL), PRINCIPAL_LIST(46, PolarisEntityType.ROOT), diff --git a/polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/PolarisTestMetaStoreManager.java b/polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/PolarisTestMetaStoreManager.java index 0904f48079..591c657d13 100644 --- a/polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/PolarisTestMetaStoreManager.java +++ b/polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/PolarisTestMetaStoreManager.java @@ -1012,7 +1012,10 @@ PolarisBaseEntity createTestCatalog(String catalogName) { PolarisEntitySubType.ICEBERG_TABLE, "T2"); this.createEntity( - List.of(catalog, N1, N1_N2), PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_VIEW, "V1"); + List.of(catalog, N1, N1_N2), + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_VIEW, + "V1"); PolarisBaseEntity N1_N3 = this.createEntity(List.of(catalog, N1), PolarisEntityType.NAMESPACE, "N3"); this.createEntity( @@ -1021,7 +1024,10 @@ PolarisBaseEntity createTestCatalog(String catalogName) { PolarisEntitySubType.ICEBERG_TABLE, "T3"); this.createEntity( - List.of(catalog, N1, N1_N3), PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_VIEW, "V2"); + List.of(catalog, N1, N1_N3), + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_VIEW, + "V2"); this.createEntity( List.of(catalog, N1), PolarisEntityType.TABLE_LIKE, @@ -1672,7 +1678,10 @@ void testCreateTestCatalog() { PolarisEntitySubType.ANY_SUBTYPE, "T2"); this.ensureExistsByName( - List.of(catalog, N1, N1_N2), PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_VIEW, "V1"); + List.of(catalog, N1, N1_N2), + PolarisEntityType.TABLE_LIKE, + PolarisEntitySubType.ICEBERG_VIEW, + "V1"); this.ensureExistsByName( List.of(catalog, N1, N1_N2), PolarisEntityType.TABLE_LIKE, diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java index a579655beb..df56b57601 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java @@ -1333,7 +1333,8 @@ public void doCommit(TableMetadata base, TableMetadata metadata) { resolvedEntityView.getPassthroughResolvedPath( tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.GENERIC_TABLE); if (resolvedGenericTable != null) { - throw new AlreadyExistsException("Generic table with same name already exists: %s", tableIdentifier); + throw new AlreadyExistsException( + "Generic table with same name already exists: %s", tableIdentifier); } // TODO: Consider using the entity from doRefresh() directly to do the conflict detection From 10cb09056e2daa86b6353204d5e1fd65f1c3d5d7 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Tue, 25 Mar 2025 19:28:19 -0700 Subject: [PATCH 18/19] reduce metastore trips --- .../catalog/iceberg/IcebergCatalog.java | 28 +++++++------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java index df56b57601..d9d6ca0c75 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java @@ -1322,33 +1322,25 @@ public void doCommit(TableMetadata base, TableMetadata metadata) { String newLocation = writeNewMetadataIfRequired(base == null, metadata); String oldLocation = base == null ? null : base.metadataFileLocation(); - PolarisResolvedPathWrapper resolvedView = - resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_VIEW); - if (resolvedView != null) { - throw new AlreadyExistsException("View with same name already exists: %s", tableIdentifier); - } - - PolarisResolvedPathWrapper resolvedGenericTable = - resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.GENERIC_TABLE); - if (resolvedGenericTable != null) { - throw new AlreadyExistsException( - "Generic table with same name already exists: %s", tableIdentifier); - } - // TODO: Consider using the entity from doRefresh() directly to do the conflict detection // instead of a two-layer CAS (checking metadataLocation to detect concurrent modification // between doRefresh() and doCommit(), and then updateEntityPropertiesIfNotChanged to detect // concurrent // modification between our checking of unchanged metadataLocation here and actual // persistence-layer commit). - PolarisResolvedPathWrapper resolvedEntities = + PolarisResolvedPathWrapper resolvedPath = resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE); + tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE); + if (resolvedPath != null && resolvedPath.getRawLeafEntity() != null) { + if (resolvedPath.getRawLeafEntity().getSubType() == PolarisEntitySubType.ICEBERG_VIEW) { + throw new AlreadyExistsException("View with same name already exists: %s", tableIdentifier); + } else if (resolvedPath.getRawLeafEntity().getSubType() == PolarisEntitySubType.GENERIC_TABLE) { + throw new AlreadyExistsException("Generic table with same name already exists: %s", tableIdentifier); + } + } IcebergTableLikeEntity entity = IcebergTableLikeEntity.of( - resolvedEntities == null ? null : resolvedEntities.getRawLeafEntity()); + resolvedPath == null ? null : resolvedPath.getRawLeafEntity()); String existingLocation; if (null == entity) { existingLocation = null; From 73cf7be551a860c4faea77ef7db161e7f5db221a Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Tue, 25 Mar 2025 19:28:21 -0700 Subject: [PATCH 19/19] autolint --- .../service/catalog/iceberg/IcebergCatalog.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java index d9d6ca0c75..ef6c99212a 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java @@ -1333,14 +1333,16 @@ public void doCommit(TableMetadata base, TableMetadata metadata) { tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE); if (resolvedPath != null && resolvedPath.getRawLeafEntity() != null) { if (resolvedPath.getRawLeafEntity().getSubType() == PolarisEntitySubType.ICEBERG_VIEW) { - throw new AlreadyExistsException("View with same name already exists: %s", tableIdentifier); - } else if (resolvedPath.getRawLeafEntity().getSubType() == PolarisEntitySubType.GENERIC_TABLE) { - throw new AlreadyExistsException("Generic table with same name already exists: %s", tableIdentifier); + throw new AlreadyExistsException( + "View with same name already exists: %s", tableIdentifier); + } else if (resolvedPath.getRawLeafEntity().getSubType() + == PolarisEntitySubType.GENERIC_TABLE) { + throw new AlreadyExistsException( + "Generic table with same name already exists: %s", tableIdentifier); } } IcebergTableLikeEntity entity = - IcebergTableLikeEntity.of( - resolvedPath == null ? null : resolvedPath.getRawLeafEntity()); + IcebergTableLikeEntity.of(resolvedPath == null ? null : resolvedPath.getRawLeafEntity()); String existingLocation; if (null == entity) { existingLocation = null;