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

yiguolei pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-4.1 by this push:
     new 79d975d1ccd branch-4.1: [fix](iceberg) Allow disabling REST catalog 
view operations (#63320)
79d975d1ccd is described below

commit 79d975d1ccda77745dafbbfe795504809abc7221
Author: Chenjunwei <[email protected]>
AuthorDate: Wed Jun 24 10:55:45 2026 +0800

    branch-4.1: [fix](iceberg) Allow disabling REST catalog view operations 
(#63320)
    
    ### What problem does this PR solve?
    
    Issue Number: None
    
    Related PR: #62986
    
    Problem Summary: Backport #62986 to branch-4.1. This allows Iceberg REST
    catalog users to disable view operations with
    `iceberg.rest.view-enabled=false` when the REST catalog does not support
    view endpoints. The default remains enabled.
    
    ### Release note
    
    Add `iceberg.rest.view-enabled` for Iceberg REST catalog. It defaults to
    true and can be set to false to skip view operations.
    
    ### Check List (For Author)
    
    - Test <!-- At least one of them must be included. -->
        - [ ] Regression test
        - [x] Unit Test
        - [ ] Manual test (add detailed scripts or steps below)
        - [ ] No need to test or manual test. Explain why:
    - [ ] This is a refactor/code format and no logic has been changed.
            - [ ] Previous test can cover this change.
            - [ ] No code files have been changed.
            - [ ] Other reason <!-- Add your reason?  -->
    
    - Behavior changed:
        - [ ] No.
    - [x] Yes. Add an opt-out switch for Iceberg REST catalog view
    operations; default behavior is unchanged.
    
    - Does this need documentation?
        - [x] No.
    - [ ] Yes. <!-- Add document PR link here. eg:
    https://github.com/apache/doris-website/pull/1214 -->
    
    ### Check List (For Reviewer who merge this PR)
    
    - [ ] Confirm the release note
    - [ ] Confirm test cases
    - [ ] Confirm document
    - [ ] Add branch pick label <!-- Add branch pick label that this PR
    should merge into -->
    
    ### Test
    
    - `MAVEN_OPTS='-Xmx4g -XX:MaxMetaspaceSize=1g' FE_UT_PARALLEL=1
    ./run-fe-ut.sh --run
    
org.apache.doris.datasource.iceberg.IcebergMetadataOpTest,org.apache.doris.datasource.property.metastore.IcebergRestPropertiesTest`
---
 .../datasource/iceberg/IcebergMetadataOps.java     | 23 ++++++--
 .../property/metastore/IcebergRestProperties.java  |  9 +++
 .../datasource/iceberg/IcebergMetadataOpTest.java  | 69 ++++++++++++++++++++++
 .../metastore/IcebergRestPropertiesTest.java       | 17 ++++++
 4 files changed, 113 insertions(+), 5 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/iceberg/IcebergMetadataOps.java
 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/iceberg/IcebergMetadataOps.java
index d447bf531e8..c08a822ed0f 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/iceberg/IcebergMetadataOps.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/iceberg/IcebergMetadataOps.java
@@ -193,7 +193,7 @@ public class IcebergMetadataOps implements 
ExternalMetadataOps {
                 // IcebergMetadataOps handles listTableNames and listViewNames 
separately.
                 // listTableNames should only focus on the table type,
                 // but in reality, Iceberg's return includes views. Therefore, 
we added a filter to exclude views.
-                if (catalog instanceof ViewCatalog) {
+                if (isViewCatalogEnabled()) {
                     views = ((ViewCatalog) 
catalog).listViews(getNamespace(dbName))
                             
.stream().map(TableIdentifier::name).collect(Collectors.toList());
                 } else {
@@ -1133,7 +1133,7 @@ public class IcebergMetadataOps implements 
ExternalMetadataOps {
 
     @Override
     public boolean viewExists(String remoteDbName, String remoteViewName) {
-        if (!(catalog instanceof ViewCatalog)) {
+        if (!isViewCatalogEnabled()) {
             return false;
         }
         try {
@@ -1147,7 +1147,7 @@ public class IcebergMetadataOps implements 
ExternalMetadataOps {
 
     @Override
     public View loadView(String dbName, String tblName) {
-        if (!(catalog instanceof ViewCatalog)) {
+        if (!isViewCatalogEnabled()) {
             return null;
         }
         try {
@@ -1161,7 +1161,7 @@ public class IcebergMetadataOps implements 
ExternalMetadataOps {
 
     @Override
     public List<String> listViewNames(String db) {
-        if (!(catalog instanceof ViewCatalog)) {
+        if (!isViewCatalogEnabled()) {
             return Collections.emptyList();
         }
         try {
@@ -1199,12 +1199,25 @@ public class IcebergMetadataOps implements 
ExternalMetadataOps {
         return externalCatalogName.map(Namespace::of).orElseGet(() -> 
Namespace.empty());
     }
 
+    private boolean isViewCatalogEnabled() {
+        if (!(catalog instanceof ViewCatalog)) {
+            return false;
+        }
+        if (dorisCatalog instanceof IcebergRestExternalCatalog) {
+            MetastoreProperties metaProps = 
dorisCatalog.getCatalogProperty().getMetastoreProperties();
+            if (metaProps instanceof IcebergRestProperties) {
+                return ((IcebergRestProperties) 
metaProps).isIcebergRestViewEnabled();
+            }
+        }
+        return true;
+    }
+
     public ThreadPoolExecutor getThreadPoolWithPreAuth() {
         return dorisCatalog.getThreadPoolWithPreAuth();
     }
 
     private void performDropView(String remoteDbName, String remoteViewName) 
throws DdlException {
-        if (!(catalog instanceof ViewCatalog)) {
+        if (!isViewCatalogEnabled()) {
             throw new DdlException("Drop Iceberg view is not supported with 
not view catalog.");
         }
         ViewCatalog viewCatalog = (ViewCatalog) catalog;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/property/metastore/IcebergRestProperties.java
 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/property/metastore/IcebergRestProperties.java
index 407c5c58b3e..f457c90ff40 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/property/metastore/IcebergRestProperties.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/property/metastore/IcebergRestProperties.java
@@ -116,6 +116,11 @@ public class IcebergRestProperties extends 
AbstractIcebergProperties {
             description = "Enable nested namespace for the iceberg rest 
catalog service.")
     private String icebergRestNestedNamespaceEnabled = "false";
 
+    @ConnectorProperty(names = {"iceberg.rest.view-enabled"},
+            required = false,
+            description = "Enable view operations for the iceberg rest catalog 
service.")
+    private String icebergRestViewEnabled = "true";
+
     @ConnectorProperty(names = {"iceberg.rest.case-insensitive-name-matching"},
             required = false,
             supported = false,
@@ -371,6 +376,10 @@ public class IcebergRestProperties extends 
AbstractIcebergProperties {
         return Boolean.parseBoolean(icebergRestNestedNamespaceEnabled);
     }
 
+    public boolean isIcebergRestViewEnabled() {
+        return Boolean.parseBoolean(icebergRestViewEnabled);
+    }
+
     public enum Security {
         NONE,
         OAUTH2,
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/datasource/iceberg/IcebergMetadataOpTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/datasource/iceberg/IcebergMetadataOpTest.java
index 3ecdb9ce437..2bf1ef3deb4 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/datasource/iceberg/IcebergMetadataOpTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/datasource/iceberg/IcebergMetadataOpTest.java
@@ -17,10 +17,23 @@
 
 package org.apache.doris.datasource.iceberg;
 
+import org.apache.doris.common.security.authentication.ExecutionAuthenticator;
+import org.apache.doris.datasource.CatalogProperty;
+
+import org.apache.iceberg.catalog.Catalog;
 import org.apache.iceberg.catalog.Namespace;
+import org.apache.iceberg.catalog.SupportsNamespaces;
+import org.apache.iceberg.catalog.TableIdentifier;
+import org.apache.iceberg.catalog.ViewCatalog;
 import org.junit.Assert;
 import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
 
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 
 public class IcebergMetadataOpTest {
@@ -45,4 +58,60 @@ public class IcebergMetadataOpTest {
         ns = IcebergMetadataOps.getNamespace(Optional.empty(), "");
         Assert.assertEquals(0, ns.length());
     }
+
+    @Test
+    public void testListTableNamesSkipsViewsWhenRestViewDisabled() {
+        IcebergRestExternalCatalog dorisCatalog = 
Mockito.mock(IcebergRestExternalCatalog.class);
+        Catalog icebergCatalog = Mockito.mock(Catalog.class,
+                
Mockito.withSettings().extraInterfaces(SupportsNamespaces.class, 
ViewCatalog.class));
+
+        Map<String, String> props = new HashMap<>();
+        props.put("type", "iceberg");
+        props.put("iceberg.catalog.type", "rest");
+        props.put("iceberg.rest.uri", "http://localhost:8181";);
+        props.put("iceberg.rest.view-enabled", "false");
+
+        Mockito.when(dorisCatalog.getExecutionAuthenticator()).thenReturn(new 
ExecutionAuthenticator() {
+        });
+        
Mockito.when(dorisCatalog.getProperties()).thenReturn(Collections.emptyMap());
+        Mockito.when(dorisCatalog.getCatalogProperty()).thenReturn(new 
CatalogProperty(null, props));
+
+        Namespace namespace = Namespace.of("PUBLIC");
+        TableIdentifier table = TableIdentifier.of(namespace, 
"DORIS_HORIZON_T");
+        
Mockito.when(icebergCatalog.listTables(namespace)).thenReturn(Collections.singletonList(table));
+
+        IcebergMetadataOps ops = new IcebergMetadataOps(dorisCatalog, 
icebergCatalog);
+        List<String> tableNames = ops.listTableNames("PUBLIC");
+
+        Assert.assertEquals(Collections.singletonList("DORIS_HORIZON_T"), 
tableNames);
+        Mockito.verify((ViewCatalog) icebergCatalog, 
Mockito.never()).listViews(Mockito.any());
+    }
+
+    @Test
+    public void testListTableNamesFiltersViewsWhenRestViewEnabled() {
+        IcebergRestExternalCatalog dorisCatalog = 
Mockito.mock(IcebergRestExternalCatalog.class);
+        Catalog icebergCatalog = Mockito.mock(Catalog.class,
+                
Mockito.withSettings().extraInterfaces(SupportsNamespaces.class, 
ViewCatalog.class));
+
+        Map<String, String> props = new HashMap<>();
+        props.put("type", "iceberg");
+        props.put("iceberg.catalog.type", "rest");
+        props.put("iceberg.rest.uri", "http://localhost:8181";);
+
+        Mockito.when(dorisCatalog.getExecutionAuthenticator()).thenReturn(new 
ExecutionAuthenticator() {
+        });
+        
Mockito.when(dorisCatalog.getProperties()).thenReturn(Collections.emptyMap());
+        Mockito.when(dorisCatalog.getCatalogProperty()).thenReturn(new 
CatalogProperty(null, props));
+
+        Namespace namespace = Namespace.of("PUBLIC");
+        TableIdentifier table = TableIdentifier.of(namespace, 
"DORIS_HORIZON_T");
+        TableIdentifier view = TableIdentifier.of(namespace, 
"DORIS_HORIZON_V");
+        
Mockito.when(icebergCatalog.listTables(namespace)).thenReturn(Arrays.asList(table,
 view));
+        Mockito.when(((ViewCatalog) 
icebergCatalog).listViews(namespace)).thenReturn(Collections.singletonList(view));
+
+        IcebergMetadataOps ops = new IcebergMetadataOps(dorisCatalog, 
icebergCatalog);
+        List<String> tableNames = ops.listTableNames("PUBLIC");
+
+        Assert.assertEquals(Collections.singletonList("DORIS_HORIZON_T"), 
tableNames);
+    }
 }
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/datasource/property/metastore/IcebergRestPropertiesTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/datasource/property/metastore/IcebergRestPropertiesTest.java
index 47ce0669a6c..cd9820c2722 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/datasource/property/metastore/IcebergRestPropertiesTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/datasource/property/metastore/IcebergRestPropertiesTest.java
@@ -83,6 +83,23 @@ public class IcebergRestPropertiesTest {
         
Assertions.assertFalse(catalogProps.containsKey("header.X-Iceberg-Access-Delegation"));
     }
 
+    @Test
+    public void testRestViewEnabled() {
+        Map<String, String> props = new HashMap<>();
+        props.put("iceberg.rest.uri", "http://localhost:8080";);
+
+        IcebergRestProperties defaultProps = new IcebergRestProperties(props);
+        defaultProps.initNormalizeAndCheckProps();
+        Assertions.assertTrue(defaultProps.isIcebergRestViewEnabled());
+
+        props.put("iceberg.rest.view-enabled", "false");
+        IcebergRestProperties disabledProps = new IcebergRestProperties(props);
+        disabledProps.initNormalizeAndCheckProps();
+        Assertions.assertFalse(disabledProps.isIcebergRestViewEnabled());
+        Assertions.assertFalse(disabledProps.getIcebergRestCatalogProperties()
+                .containsKey("iceberg.rest.view-enabled"));
+    }
+
     @Test
     public void testOAuth2CredentialFlow() {
         Map<String, String> props = new HashMap<>();


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to