diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java index bcebc639add767..7e36996dd1eb1e 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java @@ -138,6 +138,7 @@ import org.apache.doris.datasource.es.EsRepository; import org.apache.doris.datasource.hive.HiveTransactionMgr; import org.apache.doris.datasource.hive.event.MetastoreEventsProcessor; +import org.apache.doris.datasource.iceberg.IcebergExternalTable; import org.apache.doris.deploy.DeployManager; import org.apache.doris.deploy.impl.AmbariDeployManager; import org.apache.doris.deploy.impl.K8sDeployManager; @@ -317,6 +318,7 @@ import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -3917,6 +3919,20 @@ public static void getDdlStmt(DdlStmt ddlStmt, String dbName, TableIf table, Lis sb.append("\"table\" = \"").append(jdbcTable.getJdbcTable()).append("\",\n"); sb.append("\"table_type\" = \"").append(jdbcTable.getJdbcTypeName()).append("\""); sb.append("\n)"); + } else if (table.getType() == TableType.ICEBERG_EXTERNAL_TABLE) { + addTableComment(table, sb); + org.apache.iceberg.Table icebergTable = ((IcebergExternalTable) table).getIcebergTable(); + sb.append("\nLOCATION '").append(icebergTable.location()).append("'"); + sb.append("\nPROPERTIES ("); + Iterator> iterator = icebergTable.properties().entrySet().iterator(); + while (iterator.hasNext()) { + Entry prop = iterator.next(); + sb.append("\n \"").append(prop.getKey()).append("\" = \"").append(prop.getValue()).append("\""); + if (iterator.hasNext()) { + sb.append(","); + } + } + sb.append("\n)"); } createTableStmt.add(sb + ";"); @@ -6366,7 +6382,7 @@ public void compactTable(AdminCompactTableStmt stmt) throws DdlException { AgentTaskExecutor.submit(batchTask); } - private static void addTableComment(Table table, StringBuilder sb) { + private static void addTableComment(TableIf table, StringBuilder sb) { if (StringUtils.isNotBlank(table.getComment())) { sb.append("\nCOMMENT '").append(table.getComment(true)).append("'"); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/TableIf.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/TableIf.java index a052f30ee59ab1..b155e8d314cc3c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/TableIf.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/TableIf.java @@ -428,7 +428,8 @@ default boolean needReadLockWhenPlan() { * Doris table type. */ enum TableType { - MYSQL, ODBC, OLAP, SCHEMA, INLINE_VIEW, VIEW, BROKER, ELASTICSEARCH, HIVE, ICEBERG, @Deprecated HUDI, JDBC, + MYSQL, ODBC, OLAP, SCHEMA, INLINE_VIEW, VIEW, BROKER, ELASTICSEARCH, HIVE, + @Deprecated ICEBERG, @Deprecated HUDI, JDBC, TABLE_VALUED_FUNCTION, HMS_EXTERNAL_TABLE, ES_EXTERNAL_TABLE, MATERIALIZED_VIEW, JDBC_EXTERNAL_TABLE, ICEBERG_EXTERNAL_TABLE, TEST_EXTERNAL_TABLE, PAIMON_EXTERNAL_TABLE, MAX_COMPUTE_EXTERNAL_TABLE, HUDI_EXTERNAL_TABLE, TRINO_CONNECTOR_EXTERNAL_TABLE, LAKESOUl_EXTERNAL_TABLE; diff --git a/fe/fe-core/src/main/java/org/apache/doris/datasource/iceberg/IcebergExternalDatabase.java b/fe/fe-core/src/main/java/org/apache/doris/datasource/iceberg/IcebergExternalDatabase.java index 16ac6b01d4082d..f56183972e36d2 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/datasource/iceberg/IcebergExternalDatabase.java +++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/iceberg/IcebergExternalDatabase.java @@ -21,6 +21,11 @@ import org.apache.doris.datasource.ExternalDatabase; import org.apache.doris.datasource.InitDatabaseLog; +import org.apache.iceberg.catalog.Namespace; +import org.apache.iceberg.catalog.SupportsNamespaces; + +import java.util.Map; + public class IcebergExternalDatabase extends ExternalDatabase { public IcebergExternalDatabase(ExternalCatalog extCatalog, Long id, String name) { @@ -31,4 +36,10 @@ public IcebergExternalDatabase(ExternalCatalog extCatalog, Long id, String name) protected IcebergExternalTable buildTableForInit(String tableName, long tblId, ExternalCatalog catalog) { return new IcebergExternalTable(tblId, tableName, name, (IcebergExternalCatalog) extCatalog); } + + public String getLocation() { + Map props = ((SupportsNamespaces) ((IcebergExternalCatalog) getCatalog()).getCatalog()) + .loadNamespaceMetadata(Namespace.of(name)); + return props.getOrDefault("location", ""); + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java b/fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java index a3d1ca313aef94..56a88bbd6505c7 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java @@ -199,6 +199,8 @@ import org.apache.doris.datasource.hive.HMSExternalCatalog; import org.apache.doris.datasource.hive.HMSExternalTable; import org.apache.doris.datasource.hive.HiveMetaStoreClientHelper; +import org.apache.doris.datasource.iceberg.IcebergExternalCatalog; +import org.apache.doris.datasource.iceberg.IcebergExternalDatabase; import org.apache.doris.datasource.maxcompute.MaxComputeExternalCatalog; import org.apache.doris.job.manager.JobManager; import org.apache.doris.load.DeleteHandler; @@ -1099,6 +1101,12 @@ private void handleShowCreateDb() throws AnalysisException { .append(" LOCATION '") .append(db.getLocationUri()) .append("'"); + } else if (catalog instanceof IcebergExternalCatalog) { + IcebergExternalDatabase db = (IcebergExternalDatabase) catalog.getDbOrAnalysisException(showStmt.getDb()); + sb.append("CREATE DATABASE `").append(showStmt.getDb()).append("`") + .append(" LOCATION '") + .append(db.getLocation()) + .append("'"); } else { DatabaseIf db = catalog.getDbOrAnalysisException(showStmt.getDb()); sb.append("CREATE DATABASE `").append(ClusterNamespace.getNameFromFullName(showStmt.getDb())).append("`"); diff --git a/regression-test/suites/external_table_p0/iceberg/test_iceberg_show_create.groovy b/regression-test/suites/external_table_p0/iceberg/test_iceberg_show_create.groovy new file mode 100644 index 00000000000000..8065998fa71199 --- /dev/null +++ b/regression-test/suites/external_table_p0/iceberg/test_iceberg_show_create.groovy @@ -0,0 +1,73 @@ +// 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. + +suite("test_iceberg_show_create", "p0,external,doris,external_docker,external_docker_doris") { + String enabled = context.config.otherConfigs.get("enableIcebergTest") + if (enabled == null || !enabled.equalsIgnoreCase("true")) { + logger.info("disable iceberg test.") + return + } + + String rest_port = context.config.otherConfigs.get("iceberg_rest_uri_port") + String minio_port = context.config.otherConfigs.get("iceberg_minio_port") + String externalEnvIp = context.config.otherConfigs.get("externalEnvIp") + String catalog_name = "test_iceberg_show_create" + + sql """drop catalog if exists ${catalog_name}""" + sql """ + CREATE CATALOG ${catalog_name} PROPERTIES ( + 'type'='iceberg', + 'iceberg.catalog.type'='rest', + 'uri' = 'http://${externalEnvIp}:${rest_port}', + "s3.access_key" = "admin", + "s3.secret_key" = "password", + "s3.endpoint" = "http://${externalEnvIp}:${minio_port}", + "s3.region" = "us-east-1" + );""" + + sql """ switch ${catalog_name} """ + + String db1 = "test_db1" + String db2 = "test_db2" + String tb1 = "test_tb1" + + sql """ drop table if exists ${db1}.${tb1} """ + sql """ drop database if exists ${db1} """ + sql """ drop database if exists ${db2} """ + + sql """ create database ${db1} properties ('location'='s3a://warehouse/wh/${db1}') """ + sql """ create database ${db2} """ + + String result = "" + result = sql "show create database ${db1}" + logger.info("${result}") + assertTrue(result.toString().containsIgnoreCase("s3a://warehouse/wh/${db1}")) + + result = sql "show create database ${db2}" + logger.info("${result}") + assertTrue(result.toString().containsIgnoreCase("s3a://warehouse/wh/${db2}")) + + sql """ create table ${db1}.${tb1} (id int) """ + result = sql "show create table ${db1}.${tb1}" + logger.info("${result}") + assertTrue(result.toString().containsIgnoreCase("s3a://warehouse/wh/${db1}/${tb1}")) + + sql """ drop table ${db1}.${tb1} """ + sql """ drop database ${db1} """ + sql """ drop database ${db2} """ + +}