This is an automated email from the ASF dual-hosted git repository.

dimas pushed a commit to branch view-drop-no-purge
in repository https://gitbox.apache.org/repos/asf/polaris.git

commit d01287021a76da5fa5d81a115bf09cf2c46658f4
Author: Dmitri Bourlatchkov <dmitri.bourlatch...@gmail.com>
AuthorDate: Sat Aug 16 00:17:40 2025 -0400

    Add feature config to allow dropping views without purging
    
    With tables, the client can decide whether to purge the table
    on drop or not. However, Polaris Servers used to unconditionally
    perform the purge on dropping a view.
    
    After #1619 that behaviour effectively prevents dropping views
    if the admin user does not set `DROP_WITH_PURGE_ENABLED`. The
    latter, though, is not currently advisable per #1617.
    
    This change introduces a new feature configuration
    (`PURGE_VIEWS_ON_DROP`) that allows the admin user to instruct
    Polaris servers to drop views without purging to achieve
    operational parity with tables.
    
    Fixes #2367
---
 .../it/test/PolarisRestCatalogIntegrationBase.java | 26 ++++++++++++++++++++++
 .../polaris/core/config/FeatureConfiguration.java  |  9 ++++++++
 .../service/catalog/iceberg/IcebergCatalog.java    |  8 ++++++-
 3 files changed, 42 insertions(+), 1 deletion(-)

diff --git 
a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationBase.java
 
b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationBase.java
index 469ca37ce..ea08d9bb0 100644
--- 
a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationBase.java
+++ 
b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationBase.java
@@ -1199,6 +1199,32 @@ public abstract class PolarisRestCatalogIntegrationBase 
extends CatalogTests<RES
     }
   }
 
+  @Test
+  public void testDropViewWithPurge() {
+    restCatalog.createNamespace(Namespace.of("ns1"));
+    TableIdentifier id = TableIdentifier.of(Namespace.of("ns1"), "view1");
+    restCatalog
+        .buildView(id)
+        .withSchema(SCHEMA)
+        .withDefaultNamespace(Namespace.of("ns1"))
+        .withQuery("spark", VIEW_QUERY)
+        .create();
+
+    Catalog catalog = managementApi.getCatalog(currentCatalogName);
+    Map<String, String> catalogProps = new 
HashMap<>(catalog.getProperties().toMap());
+    
catalogProps.put(FeatureConfiguration.DROP_WITH_PURGE_ENABLED.catalogConfig(), 
"false");
+    catalogProps.put(FeatureConfiguration.PURGE_VIEWS_ON_DROP.catalogConfig(), 
"true");
+    managementApi.updateCatalog(catalog, catalogProps);
+
+    assertThatThrownBy(() -> 
restCatalog.dropView(id)).isInstanceOf(ForbiddenException.class);
+
+    catalog = managementApi.getCatalog(currentCatalogName);
+    catalogProps.put(FeatureConfiguration.PURGE_VIEWS_ON_DROP.catalogConfig(), 
"false");
+    managementApi.updateCatalog(catalog, catalogProps);
+
+    assertThatCode(() -> restCatalog.dropView(id)).doesNotThrowAnyException();
+  }
+
   @Test
   public void testRenameViewStatus() {
     String tableName = "tbl1";
diff --git 
a/polaris-core/src/main/java/org/apache/polaris/core/config/FeatureConfiguration.java
 
b/polaris-core/src/main/java/org/apache/polaris/core/config/FeatureConfiguration.java
index fe5d6bc6a..58dba287b 100644
--- 
a/polaris-core/src/main/java/org/apache/polaris/core/config/FeatureConfiguration.java
+++ 
b/polaris-core/src/main/java/org/apache/polaris/core/config/FeatureConfiguration.java
@@ -191,6 +191,15 @@ public class FeatureConfiguration<T> extends 
PolarisConfiguration<T> {
           .defaultValue(false)
           .buildFeatureConfiguration();
 
+  public static final FeatureConfiguration<Boolean> PURGE_VIEWS_ON_DROP =
+      PolarisConfiguration.<Boolean>builder()
+          .key("PURGE_VIEWS_ON_DROP")
+          .catalogConfig("polaris.config.purge-views-on-drop")
+          .description(
+              "Indicates whether Polaris should purge view metadata files when 
a view is dropped.")
+          .defaultValue(true)
+          .buildFeatureConfiguration();
+
   public static final FeatureConfiguration<Integer> 
STORAGE_CREDENTIAL_DURATION_SECONDS =
       PolarisConfiguration.<Integer>builder()
           .key("STORAGE_CREDENTIAL_DURATION_SECONDS")
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java
index 9d37dd32d..6283e65c6 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java
@@ -807,7 +807,13 @@ public class IcebergCatalog extends 
BaseMetastoreViewCatalog
 
   @Override
   public boolean dropView(TableIdentifier identifier) {
-    return dropTableLike(PolarisEntitySubType.ICEBERG_VIEW, identifier, 
Map.of(), true).isSuccess();
+    boolean purge =
+        callContext
+            .getRealmConfig()
+            .getConfig(FeatureConfiguration.PURGE_VIEWS_ON_DROP, 
catalogEntity);
+
+    return dropTableLike(PolarisEntitySubType.ICEBERG_VIEW, identifier, 
Map.of(), purge)
+        .isSuccess();
   }
 
   @Override

Reply via email to