This is an automated email from the ASF dual-hosted git repository.
starocean999 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 908f0209524 [Enhancement] support table comment for mysql jdbc catalog
(#54088)
908f0209524 is described below
commit 908f020952445f61a94e504532c571180cb9ce94
Author: csding <[email protected]>
AuthorDate: Wed Aug 6 09:41:16 2025 +0800
[Enhancement] support table comment for mysql jdbc catalog (#54088)
support display table comment when use `SHOW CREATE TABLE
jdbc_catalog.db.table`
---
.../docker-compose/mysql/init/03-create-table.sql | 7 ++
.../main/java/org/apache/doris/catalog/Env.java | 4 +
.../doris/datasource/jdbc/JdbcExternalCatalog.java | 4 +
.../doris/datasource/jdbc/JdbcExternalTable.java | 16 +++
.../doris/datasource/jdbc/client/JdbcClient.java | 7 ++
.../datasource/jdbc/client/JdbcMySQLClient.java | 24 ++++
.../test_mysql_jdbc_catalog_table_comment.groovy | 121 +++++++++++++++++++++
7 files changed, 183 insertions(+)
diff --git a/docker/thirdparties/docker-compose/mysql/init/03-create-table.sql
b/docker/thirdparties/docker-compose/mysql/init/03-create-table.sql
index 972e35546d0..21e45e8ebae 100644
--- a/docker/thirdparties/docker-compose/mysql/init/03-create-table.sql
+++ b/docker/thirdparties/docker-compose/mysql/init/03-create-table.sql
@@ -512,3 +512,10 @@ CREATE TABLE doris_test.`test_cast` (
`datetime_c` varchar(100)
);
+CREATE TABLE doris_test.`test_table_comment` (
+ `id` int(11) DEFAULT NULL,
+ `int_c` varchar(100),
+ `date_c` varchar(100),
+ `datetime_c` varchar(100)
+) COMMENT = 'test table comment';
+
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 cee514789b4..9cc3a6488c8 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
@@ -117,6 +117,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.datasource.jdbc.JdbcExternalTable;
import org.apache.doris.datasource.paimon.PaimonExternalTable;
import org.apache.doris.deploy.DeployManager;
import org.apache.doris.deploy.impl.AmbariDeployManager;
@@ -4586,6 +4587,9 @@ public class Env {
sb.append("\"database\" =
\"").append(mysqlTable.getMysqlDatabaseName()).append("\",\n");
sb.append("\"table\" =
\"").append(mysqlTable.getMysqlTableName()).append("\"\n");
sb.append(")");
+ } else if (table.getType() == TableType.JDBC_EXTERNAL_TABLE) {
+ JdbcExternalTable jdbcTable = (JdbcExternalTable) table;
+ addTableComment(jdbcTable, sb);
} else if (table.getType() == TableType.ODBC) {
OdbcTable odbcTable = (OdbcTable) table;
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/JdbcExternalCatalog.java
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/JdbcExternalCatalog.java
index e8e92e60ac1..e5dd7c933fb 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/JdbcExternalCatalog.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/JdbcExternalCatalog.java
@@ -89,6 +89,10 @@ public class JdbcExternalCatalog extends ExternalCatalog {
getMetaNamesMapping());
}
+ public JdbcClient getJdbcClient() {
+ return jdbcClient;
+ }
+
@Override
public void checkProperties() throws DdlException {
super.checkProperties();
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/JdbcExternalTable.java
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/JdbcExternalTable.java
index 2bcd2277251..9c33ec6414d 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/JdbcExternalTable.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/JdbcExternalTable.java
@@ -74,6 +74,7 @@ public class JdbcExternalTable extends ExternalTable {
+ "(\"catalog\"=\"${ctlName}\", \"query\"=\"${sql}\");";
private JdbcTable jdbcTable;
+ private String tableComment;
/**
* Create jdbc external table.
@@ -98,6 +99,21 @@ public class JdbcExternalTable extends ExternalTable {
}
}
+ @Override
+ public String getComment() {
+ return getComment(true);
+ }
+
+ @Override
+ public String getComment(boolean escapeQuota) {
+ if (tableComment != null) {
+ return tableComment;
+ }
+ JdbcExternalCatalog jdbcExternalCatalog = (JdbcExternalCatalog)
catalog;
+ tableComment =
jdbcExternalCatalog.getJdbcClient().getTableComment(db.getRemoteName(),
getRemoteName());
+ return tableComment;
+ }
+
public JdbcTable getJdbcTable() {
makeSureInitialized();
return jdbcTable;
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcClient.java
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcClient.java
index 7d3ecdfe4d9..c7f6463b984 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcClient.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcClient.java
@@ -345,6 +345,13 @@ public abstract class JdbcClient {
return remoteTablesNames;
}
+ /**
+ * get table comment
+ */
+ public String getTableComment(String remoteDbName, String remoteTableName)
{
+ return "";
+ }
+
public boolean isTableExist(String remoteDbName, String remoteTableName) {
final boolean[] isExist = {false};
String[] tableTypes = getTableTypes();
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcMySQLClient.java
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcMySQLClient.java
index a02830f3255..3d8990e4022 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcMySQLClient.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcMySQLClient.java
@@ -23,6 +23,9 @@ import org.apache.doris.catalog.Type;
import org.apache.doris.common.util.Util;
import org.apache.doris.datasource.jdbc.util.JdbcFieldSchema;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
@@ -71,6 +74,27 @@ public class JdbcMySQLClient extends JdbcClient {
this.dbType = dbType;
}
+ @Override
+ public String getTableComment(String remoteDbName, String remoteTableName)
{
+ ImmutableList.Builder<String> tableCommentBuilder =
ImmutableList.builder();
+ String[] tableTypes = getTableTypes();
+ processTable(remoteDbName, remoteTableName, tableTypes, (rs) -> {
+ try {
+ while (rs.next()) {
+
tableCommentBuilder.add(Strings.nullToEmpty(rs.getString("REMARKS")));
+ }
+ } catch (SQLException e) {
+ throw new JdbcClientException(
+ "failed to get table's comment for remote database: `%s`,
remote table: `%s`",
+ e, remoteDbName, remoteTableName);
+ }
+ });
+
+ ImmutableList<String> tableComment = tableCommentBuilder.build();
+ Preconditions.checkArgument(tableComment.size() == 1, "Multiple tables
`%s` are matched", remoteTableName);
+ return tableComment.get(0);
+ }
+
@Override
protected void setJdbcDriverSystemProperties() {
super.setJdbcDriverSystemProperties();
diff --git
a/regression-test/suites/external_table_p0/jdbc/test_mysql_jdbc_catalog_table_comment.groovy
b/regression-test/suites/external_table_p0/jdbc/test_mysql_jdbc_catalog_table_comment.groovy
new file mode 100644
index 00000000000..7a33d718d8b
--- /dev/null
+++
b/regression-test/suites/external_table_p0/jdbc/test_mysql_jdbc_catalog_table_comment.groovy
@@ -0,0 +1,121 @@
+// 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_jdbc_mysql_catalog_table_comment") {
+ String ex_table_name = "test_table_comment";
+ String enabled = context.config.otherConfigs.get("enableJdbcTest")
+ String s3_endpoint = getS3Endpoint()
+ String bucket = getS3BucketName()
+ String externalEnvIp = context.config.otherConfigs.get("externalEnvIp")
+
+ // mysql catalog
+ String driver_url =
"https://${bucket}.${s3_endpoint}/regression/jdbc_driver/mysql-connector-java-8.0.25.jar"
+ if (enabled == null || !enabled.equalsIgnoreCase("true")) {
+ return;
+ }
+
+ for (String driver_class :
["com.mysql.cj.jdbc.Driver","com.mysql.jdbc.Driver" ]) {
+ if (driver_class.equals("com.mysql.jdbc.Driver")) {
+ driver_url =
"https://${bucket}.${s3_endpoint}/regression/jdbc_driver/mysql-connector-java-5.1.49.jar"
+ } else {
+ driver_url =
"https://${bucket}.${s3_endpoint}/regression/jdbc_driver/mysql-connector-java-8.0.25.jar"
+ }
+ String user = "test_jdbc_user";
+ String pwd = '123456';
+ String catalog_name = "mysql_jdbc_catalog";
+ String ex_db_name = "doris_test";
+ String mysql_port = context.config.otherConfigs.get("mysql_57_port");
+
+ sql """drop catalog if exists ${catalog_name} """
+
+ sql """create catalog if not exists ${catalog_name} properties(
+ "type"="jdbc",
+ "user"="root",
+ "password"="123456",
+ "jdbc_url" =
"jdbc:mysql://${externalEnvIp}:${mysql_port}/doris_test?useSSL=false",
+ "driver_url" = "${driver_url}",
+ "driver_class" = "${driver_class}"
+ );"""
+
+ sql """switch ${catalog_name}"""
+ sql """ use ${ex_db_name}"""
+
+ explain {
+ sql "SHOW CREATE TABLE ${ex_table_name}"
+ contains "test table comment"
+ }
+ }
+
+ // doris catalog
+ String jdbcUrl = context.config.jdbcUrl
+ String jdbcUser = "test_doris_catalog"
+ String jdbcPassword = "C123_567p"
+ driver_url =
"https://${bucket}.${s3_endpoint}/regression/jdbc_driver/mysql-connector-j-8.3.0.jar"
+
+ try_sql """drop user ${jdbcUser}"""
+ sql """create user ${jdbcUser} identified by '${jdbcPassword}'"""
+
+ //cloud-mode
+ if (isCloudMode()) {
+ def clusters = sql " SHOW CLUSTERS; "
+ assertTrue(!clusters.isEmpty())
+ def validCluster = clusters[0][0]
+ sql """GRANT USAGE_PRIV ON CLUSTER `${validCluster}` TO ${jdbcUser}""";
+ }
+
+ sql """grant all on *.*.* to ${jdbcUser}"""
+
+ sql """drop database if exists internal.EXTERNAL_DORIS; """
+ sql """create database if not exists internal.EXTERNAL_DORIS;"""
+ sql """create table if not exists internal.EXTERNAL_DORIS.TABLE_TEST
+ (id int, name varchar(20))
+ COMMENT 'test table comment'
+ distributed by hash(id) buckets 10
+ properties('replication_num' = '1');
+ """
+
+ sql """drop catalog if exists test_doris_catalog """
+
+ sql """ CREATE CATALOG `test_doris_catalog` PROPERTIES (
+ "user" = "${jdbcUser}",
+ "type" = "jdbc",
+ "password" = "${jdbcPassword}",
+ "jdbc_url" = "${jdbcUrl}",
+ "driver_url" = "${driver_url}",
+ "driver_class" = "com.mysql.cj.jdbc.Driver",
+ "lower_case_meta_names" = "true",
+ "only_specified_database" = "true",
+ "include_database_list" = "EXTERNAL_DORIS"
+ )"""
+
+ sql """switch test_doris_catalog"""
+ sql """ use external_doris"""
+
+ explain {
+ sql "SHOW CREATE TABLE table_test"
+ contains "test table comment"
+ }
+
+ sql """drop catalog if exists test_doris_catalog """
+ sql """drop database if exists internal.EXTERNAL_DORIS"""
+
+ try_sql """drop user ${jdbcUser}"""
+
+
+}
+
+
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]