This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-4.0
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-4.0 by this push:
new 32369a90d71 branch-4.0: [fix](iceberg) fix logic of getting namespaces
#56874 (#57021)
32369a90d71 is described below
commit 32369a90d71f8e8b082de4e401c60e2262c3c413
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Thu Oct 16 18:00:17 2025 +0800
branch-4.0: [fix](iceberg) fix logic of getting namespaces #56874 (#57021)
Cherry-picked from #56874
Co-authored-by: Mingyu Chen (Rayner) <[email protected]>
---
.../datasource/iceberg/IcebergMetadataOps.java | 28 +++++++++----
.../property/metastore/IcebergRestProperties.java | 10 ++---
.../datasource/iceberg/IcebergMetadataOpTest.java | 48 ++++++++++++++++++++++
.../metastore/IcebergRestPropertiesTest.java | 4 +-
4 files changed, 74 insertions(+), 16 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 d722183caf9..39e7d840e4a 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
@@ -43,6 +43,8 @@ import
org.apache.doris.nereids.trees.plans.commands.info.DropBranchInfo;
import org.apache.doris.nereids.trees.plans.commands.info.DropTagInfo;
import org.apache.doris.nereids.trees.plans.commands.info.TagOptions;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Splitter;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.iceberg.ManageSnapshots;
import org.apache.iceberg.PartitionSpec;
@@ -66,6 +68,7 @@ import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -794,7 +797,8 @@ public class IcebergMetadataOps implements
ExternalMetadataOps {
}
try {
ViewCatalog viewCatalog = (ViewCatalog) catalog;
- return executionAuthenticator.execute(() ->
viewCatalog.loadView(TableIdentifier.of(dbName, tblName)));
+ return executionAuthenticator.execute(
+ () ->
viewCatalog.loadView(TableIdentifier.of(getNamespace(dbName), tblName)));
} catch (Exception e) {
throw new RuntimeException("Failed to load view, error message
is:" + e.getMessage(), e);
}
@@ -807,7 +811,7 @@ public class IcebergMetadataOps implements
ExternalMetadataOps {
}
try {
return executionAuthenticator.execute(() ->
- ((ViewCatalog) catalog).listViews(Namespace.of(db))
+ ((ViewCatalog) catalog).listViews(getNamespace(db))
.stream().map(TableIdentifier::name).collect(Collectors.toList()));
} catch (Exception e) {
throw new RuntimeException("Failed to list view names, error
message is:" + e.getMessage(), e);
@@ -815,15 +819,22 @@ public class IcebergMetadataOps implements
ExternalMetadataOps {
}
private TableIdentifier getTableIdentifier(String dbName, String tblName) {
- return externalCatalogName
- .map(s -> TableIdentifier.of(s, dbName, tblName))
- .orElseGet(() -> TableIdentifier.of(dbName, tblName));
+ Namespace ns = getNamespace(dbName);
+ return TableIdentifier.of(ns, tblName);
}
private Namespace getNamespace(String dbName) {
- return externalCatalogName
- .map(s -> Namespace.of(s, dbName))
- .orElseGet(() -> Namespace.of(dbName));
+ return getNamespace(externalCatalogName, dbName);
+ }
+
+ @VisibleForTesting
+ public static Namespace getNamespace(Optional<String> catalogName, String
dbName) {
+ String[] splits =
Splitter.on(".").omitEmptyStrings().trimResults().splitToList(dbName).toArray(new
String[0]);
+ if (catalogName.isPresent()) {
+ splits = Arrays.copyOf(splits, splits.length + 1);
+ splits[splits.length - 1] = catalogName.get();
+ }
+ return Namespace.of(splits);
}
private Namespace getNamespace() {
@@ -843,3 +854,4 @@ public class IcebergMetadataOps implements
ExternalMetadataOps {
}
}
+
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 3110745b91e..b899116a1a8 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
@@ -200,11 +200,7 @@ public class IcebergRestProperties extends
AbstractIcebergProperties {
ParamRules rules = new ParamRules()
// OAuth2 requires either credential or token, but not both
.mutuallyExclusive(icebergRestOauth2Credential,
icebergRestOauth2Token,
- "OAuth2 cannot have both credential and token
configured")
- // If using credential flow, server URI is required
- .requireAllIfPresent(icebergRestOauth2Credential,
- new String[] {icebergRestOauth2ServerUri},
- "OAuth2 credential flow requires server-uri");
+ "OAuth2 cannot have both credential and token
configured");
// Custom validation: OAuth2 scope should not be used with token
if (Strings.isNotBlank(icebergRestOauth2Token) &&
Strings.isNotBlank(icebergRestOauth2Scope)) {
@@ -274,7 +270,9 @@ public class IcebergRestProperties extends
AbstractIcebergProperties {
if (Strings.isNotBlank(icebergRestOauth2Credential)) {
// Client Credentials Flow
icebergRestCatalogProperties.put(OAuth2Properties.CREDENTIAL,
icebergRestOauth2Credential);
-
icebergRestCatalogProperties.put(OAuth2Properties.OAUTH2_SERVER_URI,
icebergRestOauth2ServerUri);
+ if (Strings.isNotBlank(icebergRestOauth2ServerUri)) {
+
icebergRestCatalogProperties.put(OAuth2Properties.OAUTH2_SERVER_URI,
icebergRestOauth2ServerUri);
+ }
if (Strings.isNotBlank(icebergRestOauth2Scope)) {
icebergRestCatalogProperties.put(OAuth2Properties.SCOPE,
icebergRestOauth2Scope);
}
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
new file mode 100644
index 00000000000..3ecdb9ce437
--- /dev/null
+++
b/fe/fe-core/src/test/java/org/apache/doris/datasource/iceberg/IcebergMetadataOpTest.java
@@ -0,0 +1,48 @@
+// 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.doris.datasource.iceberg;
+
+import org.apache.iceberg.catalog.Namespace;
+import org.junit.Assert;
+import org.junit.jupiter.api.Test;
+
+import java.util.Optional;
+
+public class IcebergMetadataOpTest {
+
+ @Test
+ public void testGetNamespaces() {
+ Namespace ns = IcebergMetadataOps.getNamespace(Optional.empty(),
"db1");
+ Assert.assertEquals(1, ns.length());
+
+ ns = IcebergMetadataOps.getNamespace(Optional.empty(), "db1.db2.db3");
+ Assert.assertEquals(3, ns.length());
+
+ ns = IcebergMetadataOps.getNamespace(Optional.empty(), "db1..db2");
+ Assert.assertEquals(2, ns.length());
+
+ ns = IcebergMetadataOps.getNamespace(Optional.of("p1"), "db1");
+ Assert.assertEquals(2, ns.length());
+
+ ns = IcebergMetadataOps.getNamespace(Optional.of("p1"), "");
+ Assert.assertEquals(1, ns.length());
+
+ ns = IcebergMetadataOps.getNamespace(Optional.empty(), "");
+ Assert.assertEquals(0, ns.length());
+ }
+}
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 d1199df2ae6..226f6dd6551 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
@@ -131,14 +131,14 @@ public class IcebergRestPropertiesTest {
IcebergRestProperties restProps2 = new IcebergRestProperties(props2);
Assertions.assertThrows(IllegalArgumentException.class,
restProps2::initNormalizeAndCheckProps);
- // Test: credential flow without server URI
+ // Test: credential flow without server URI is ok
Map<String, String> props3 = new HashMap<>();
props3.put("iceberg.rest.uri", "http://localhost:8080");
props3.put("iceberg.rest.security.type", "oauth2");
props3.put("iceberg.rest.oauth2.credential", "client_credentials");
IcebergRestProperties restProps3 = new IcebergRestProperties(props3);
- Assertions.assertThrows(IllegalArgumentException.class,
restProps3::initNormalizeAndCheckProps);
+ Assertions.assertDoesNotThrow(restProps3::initNormalizeAndCheckProps);
// Test: scope with token (should fail)
Map<String, String> props4 = new HashMap<>();
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]