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

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


The following commit(s) were added to refs/heads/branch-3.0 by this push:
     new 9b1f290ff7e [fix](catalog) should return error if try using a unknown 
database (#40479) (#41850)
9b1f290ff7e is described below

commit 9b1f290ff7e42267e33b81c63553b2a6f1273cc2
Author: Rayner Chen <[email protected]>
AuthorDate: Wed Oct 16 17:33:02 2024 +0800

    [fix](catalog) should return error if try using a unknown database (#40479) 
(#41850)
    
    bp #40479
---
 .../apache/doris/datasource/ExternalCatalog.java   | 38 +++++++++--
 .../doris/datasource/hive/HMSExternalCatalog.java  |  2 +-
 .../doris/datasource/hive/HiveMetadataOps.java     | 14 +++--
 .../datasource/iceberg/IcebergMetadataOps.java     | 12 +++-
 .../java/org/apache/doris/mysql/MysqlProto.java    |  6 +-
 .../java/org/apache/doris/qe/ConnectProcessor.java |  6 +-
 .../jdbc/test_jdbc_catalog_ddl.out                 | 27 ++++++++
 ...t_hive_insert_overwrite_with_empty_table.groovy | 11 ++--
 .../jdbc/test_jdbc_catalog_ddl.groovy              | 73 ++++++++++++++++++++++
 9 files changed, 168 insertions(+), 21 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalCatalog.java 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalCatalog.java
index 37e44c63569..25329a1a829 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalCatalog.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalCatalog.java
@@ -33,6 +33,7 @@ import org.apache.doris.catalog.TableIf;
 import org.apache.doris.cluster.ClusterNamespace;
 import org.apache.doris.common.Config;
 import org.apache.doris.common.DdlException;
+import org.apache.doris.common.FeConstants;
 import org.apache.doris.common.Pair;
 import org.apache.doris.common.UserException;
 import org.apache.doris.common.Version;
@@ -251,7 +252,7 @@ public abstract class ExternalCatalog
                             Config.max_meta_object_cache_num,
                             ignored -> getFilteredDatabaseNames(),
                             dbName -> Optional.ofNullable(
-                                    buildDbForInit(dbName, 
Util.genIdByName(name, dbName), logType)),
+                                    buildDbForInit(dbName, 
Util.genIdByName(name, dbName), logType, true)),
                             (key, value, cause) -> value.ifPresent(v -> 
v.setUnInitialized(invalidCacheInInit)));
                 }
                 setLastUpdateTime(System.currentTimeMillis());
@@ -371,7 +372,7 @@ public abstract class ExternalCatalog
             } else {
                 dbId = Env.getCurrentEnv().getNextId();
                 tmpDbNameToId.put(dbName, dbId);
-                ExternalDatabase<? extends ExternalTable> db = 
buildDbForInit(dbName, dbId, logType);
+                ExternalDatabase<? extends ExternalTable> db = 
buildDbForInit(dbName, dbId, logType, false);
                 tmpIdToDb.put(dbId, db);
                 initCatalogLog.addCreateDb(dbId, dbName);
             }
@@ -637,7 +638,7 @@ public abstract class ExternalCatalog
         }
         for (int i = 0; i < log.getCreateCount(); i++) {
             ExternalDatabase<? extends ExternalTable> db =
-                    buildDbForInit(log.getCreateDbNames().get(i), 
log.getCreateDbIds().get(i), log.getType());
+                    buildDbForInit(log.getCreateDbNames().get(i), 
log.getCreateDbIds().get(i), log.getType(), false);
             if (db != null) {
                 tmpDbNameToId.put(db.getFullName(), db.getId());
                 tmpIdToDb.put(db.getId(), db);
@@ -660,8 +661,37 @@ public abstract class ExternalCatalog
         }
     }
 
+    /**
+     * Build a database instance.
+     * If checkExists is true, it will check if the database exists in the 
remote system.
+     *
+     * @param dbName
+     * @param dbId
+     * @param logType
+     * @param checkExists
+     * @return
+     */
     protected ExternalDatabase<? extends ExternalTable> buildDbForInit(String 
dbName, long dbId,
-            InitCatalogLog.Type logType) {
+            InitCatalogLog.Type logType, boolean checkExists) {
+        // When running ut, disable this check to make ut pass.
+        // Because in ut, the database is not created in remote system.
+        if (checkExists && !FeConstants.runningUnitTest) {
+            try {
+                List<String> dbNames = getDbNames();
+                if (!dbNames.contains(dbName)) {
+                    dbNames = listDatabaseNames();
+                    if (!dbNames.contains(dbName)) {
+                        return null;
+                    }
+                }
+            } catch (Throwable t) {
+                // If connection failed, it will throw exception.
+                // ignore it and treat it as not exist.
+                LOG.warn("Failed to check db {} exist in remote system, ignore 
it.", dbName, t);
+                return null;
+            }
+        }
+
         if (dbName.equals(InfoSchemaDb.DATABASE_NAME)) {
             return new ExternalInfoSchemaDatabase(this, dbId);
         }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HMSExternalCatalog.java
 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HMSExternalCatalog.java
index 5173b414b8a..99fd96f65db 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HMSExternalCatalog.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HMSExternalCatalog.java
@@ -256,7 +256,7 @@ public class HMSExternalCatalog extends ExternalCatalog {
             LOG.debug("create database [{}]", dbName);
         }
 
-        ExternalDatabase<? extends ExternalTable> db = buildDbForInit(dbName, 
dbId, logType);
+        ExternalDatabase<? extends ExternalTable> db = buildDbForInit(dbName, 
dbId, logType, false);
         if (useMetaCache.get()) {
             if (isInitialized()) {
                 metaCache.updateCache(dbName, db, 
Util.genIdByName(getQualifiedName(dbName)));
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HiveMetadataOps.java
 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HiveMetadataOps.java
index 5ec49c380b7..022f646343d 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HiveMetadataOps.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HiveMetadataOps.java
@@ -248,20 +248,26 @@ public class HiveMetadataOps implements 
ExternalMetadataOps {
     @Override
     public void dropTable(DropTableStmt stmt) throws DdlException {
         String dbName = stmt.getDbName();
+        String tblName = stmt.getTableName();
         ExternalDatabase<?> db = catalog.getDbNullable(stmt.getDbName());
         if (db == null) {
-            throw new DdlException("Failed to get database: '" + dbName + "' 
in catalog: " + catalog.getName());
+            if (stmt.isSetIfExists()) {
+                LOG.info("database [{}] does not exist when drop table[{}]", 
dbName, tblName);
+                return;
+            } else {
+                ErrorReport.reportDdlException(ErrorCode.ERR_BAD_DB_ERROR, 
dbName);
+            }
         }
-        if (!tableExist(dbName, stmt.getTableName())) {
+        if (!tableExist(dbName, tblName)) {
             if (stmt.isSetIfExists()) {
                 LOG.info("drop table[{}] which does not exist", dbName);
                 return;
             } else {
-                ErrorReport.reportDdlException(ErrorCode.ERR_UNKNOWN_TABLE, 
stmt.getTableName(), dbName);
+                ErrorReport.reportDdlException(ErrorCode.ERR_UNKNOWN_TABLE, 
tblName, dbName);
             }
         }
         try {
-            client.dropTable(dbName, stmt.getTableName());
+            client.dropTable(dbName, tblName);
             db.setUnInitialized(true);
         } catch (Exception e) {
             throw new DdlException(e.getMessage(), e);
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 66c57e37307..7fa7b5e84e8 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
@@ -167,14 +167,20 @@ public class IcebergMetadataOps implements 
ExternalMetadataOps {
     @Override
     public void dropTable(DropTableStmt stmt) throws DdlException {
         String dbName = stmt.getDbName();
+        String tableName = stmt.getTableName();
         ExternalDatabase<?> db = dorisCatalog.getDbNullable(dbName);
         if (db == null) {
-            throw new DdlException("Failed to get database: '" + dbName + "' 
in catalog: " + dorisCatalog.getName());
+            if (stmt.isSetIfExists()) {
+                LOG.info("database [{}] does not exist when drop table[{}]", 
dbName, tableName);
+                return;
+            } else {
+                ErrorReport.reportDdlException(ErrorCode.ERR_BAD_DB_ERROR, 
dbName);
+            }
         }
-        String tableName = stmt.getTableName();
+
         if (!tableExist(dbName, tableName)) {
             if (stmt.isSetIfExists()) {
-                LOG.info("drop table[{}] which does not exist", dbName);
+                LOG.info("drop table[{}] which does not exist", tableName);
                 return;
             } else {
                 ErrorReport.reportDdlException(ErrorCode.ERR_UNKNOWN_TABLE, 
tableName, dbName);
diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/MysqlProto.java 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/MysqlProto.java
index 09cfcb4ff4f..a672a217a33 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/mysql/MysqlProto.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/MysqlProto.java
@@ -243,11 +243,13 @@ public class MysqlProto {
             if (catalogName != null) {
                 CatalogIf catalogIf = 
context.getEnv().getCatalogMgr().getCatalog(catalogName);
                 if (catalogIf == null) {
-                    context.getState().setError(ErrorCode.ERR_BAD_DB_ERROR, 
"No match catalog in doris: " + db);
+                    context.getState()
+                            .setError(ErrorCode.ERR_BAD_DB_ERROR, 
ErrorCode.ERR_BAD_DB_ERROR.formatErrorMsg(db));
                     return false;
                 }
                 if (catalogIf.getDbNullable(dbFullName) == null) {
-                    context.getState().setError(ErrorCode.ERR_BAD_DB_ERROR, 
"No match database in doris: " + db);
+                    context.getState()
+                            .setError(ErrorCode.ERR_BAD_DB_ERROR, 
ErrorCode.ERR_BAD_DB_ERROR.formatErrorMsg(db));
                     return false;
                 }
             }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/ConnectProcessor.java 
b/fe/fe-core/src/main/java/org/apache/doris/qe/ConnectProcessor.java
index 31be3184fde..6e495217c29 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/qe/ConnectProcessor.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/qe/ConnectProcessor.java
@@ -151,11 +151,13 @@ public abstract class ConnectProcessor {
         if (catalogName != null) {
             CatalogIf catalogIf = 
ctx.getEnv().getCatalogMgr().getCatalog(catalogName);
             if (catalogIf == null) {
-                ctx.getState().setError(ErrorCode.ERR_BAD_DB_ERROR, "No match 
catalog in doris: " + fullDbName);
+                ctx.getState().setError(ErrorCode.ERR_BAD_DB_ERROR,
+                        ErrorCode.ERR_BAD_DB_ERROR.formatErrorMsg(catalogName 
+ "." + dbName));
                 return;
             }
             if (catalogIf.getDbNullable(dbName) == null) {
-                ctx.getState().setError(ErrorCode.ERR_BAD_DB_ERROR, "No match 
database in doris: " + fullDbName);
+                ctx.getState().setError(ErrorCode.ERR_BAD_DB_ERROR,
+                        ErrorCode.ERR_BAD_DB_ERROR.formatErrorMsg(catalogName 
+ "." + dbName));
                 return;
             }
         }
diff --git 
a/regression-test/data/external_table_p0/jdbc/test_jdbc_catalog_ddl.out 
b/regression-test/data/external_table_p0/jdbc/test_jdbc_catalog_ddl.out
new file mode 100644
index 00000000000..9629269ea3c
--- /dev/null
+++ b/regression-test/data/external_table_p0/jdbc/test_jdbc_catalog_ddl.out
@@ -0,0 +1,27 @@
+-- This file is automatically generated. You should know what you did if you 
want to edit this
+-- !show_db --
+DORIS
+Doris
+doris
+doris_test
+information_schema
+init_db
+mysql
+show_test_do_not_modify
+
+-- !sql01 --
+12345
+
+-- !show_db --
+DORIS
+Doris
+doris
+doris_test
+information_schema
+init_db
+mysql
+show_test_do_not_modify
+
+-- !sql01 --
+12345
+
diff --git 
a/regression-test/suites/external_table_p0/hive/write/test_hive_insert_overwrite_with_empty_table.groovy
 
b/regression-test/suites/external_table_p0/hive/write/test_hive_insert_overwrite_with_empty_table.groovy
index eea2e7a4864..9e195d0aff6 100644
--- 
a/regression-test/suites/external_table_p0/hive/write/test_hive_insert_overwrite_with_empty_table.groovy
+++ 
b/regression-test/suites/external_table_p0/hive/write/test_hive_insert_overwrite_with_empty_table.groovy
@@ -43,12 +43,13 @@ suite("test_hive_insert_overwrite_with_empty_table", 
"p0,external,hive,external_
                 'hive.metastore.uris' = 'thrift://${externalEnvIp}:${hms_port}'
             );"""
 
-            sql """ use ${catalog}.${db1} """
-
-            sql """ drop table if exists ${db1}.${tb1} """
-            sql """ drop table if exists ${db1}.${tb2} """
-            sql """ drop database if exists ${db1} """
+            sql """ drop database if exists ${catalog}.${db1} """
+            test {
+                sql """ use ${catalog}.${db1} """
+                exception "Unknown database"
+            }
 
+            sql """ switch ${catalog}"""
             sql """ create database ${db1} """
             sql """ create table ${db1}.${tb1} (id int, val int) partition by 
list (val)() """
             sql """ create table ${db1}.${tb2} (id int, val int) """
diff --git 
a/regression-test/suites/external_table_p0/jdbc/test_jdbc_catalog_ddl.groovy 
b/regression-test/suites/external_table_p0/jdbc/test_jdbc_catalog_ddl.groovy
new file mode 100644
index 00000000000..1b25362edd7
--- /dev/null
+++ b/regression-test/suites/external_table_p0/jdbc/test_jdbc_catalog_ddl.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_jdbc_catalog_ddl", 
"p0,external,mysql,external_docker,external_docker_mysql") {
+
+    String enabled = context.config.otherConfigs.get("enableJdbcTest")
+    String externalEnvIp = context.config.otherConfigs.get("externalEnvIp")
+    String s3_endpoint = getS3Endpoint()
+    String bucket = getS3BucketName()
+    String driver_url = 
"https://${bucket}.${s3_endpoint}/regression/jdbc_driver/mysql-connector-java-5.1.49.jar";
+    String mysql_port = context.config.otherConfigs.get("mysql_57_port");
+    // String driver_url = "mysql-connector-java-5.1.49.jar"
+    if (enabled != null && enabled.equalsIgnoreCase("true")) {
+        String catalog_name = "mysql_jdbc5_catalog";
+
+        for (String useMetaCache : ["true", "false"]) {
+            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&zeroDateTimeBehavior=convertToNull",
+                "driver_url" = "${driver_url}",
+                "driver_class" = "com.mysql.jdbc.Driver",
+                "use_meta_cache" = "${useMetaCache}"
+            );"""
+            order_qt_show_db """ show databases from ${catalog_name}; """
+
+            // test wrong catalog and db
+            test {
+                sql """switch unknown_catalog"""
+                exception "Unknown catalog 'unknown_catalog'"
+            }
+            test {
+                sql """use unknown_catalog.db1"""
+                exception """Unknown catalog 'unknown_catalog'"""
+            }
+            test {
+                sql """use ${catalog_name}.unknown_db"""
+                exception """Unknown database 'unknown_db'"""
+            }
+
+            // create a database in mysql
+            sql """CALL EXECUTE_STMT("${catalog_name}",  "drop database if 
exists temp_database")"""
+            sql """CALL EXECUTE_STMT("${catalog_name}",  "create database 
temp_database")"""
+            sql """CALL EXECUTE_STMT("${catalog_name}",  "drop table if exists 
temp_database.temp_table")"""
+            sql """CALL EXECUTE_STMT("${catalog_name}",  "create table 
temp_database.temp_table (k1 int)")"""
+            sql """CALL EXECUTE_STMT("${catalog_name}",  "insert into 
temp_database.temp_table values(12345)")"""
+
+            if (useMetaCache.equals("false")) {
+                sql """refresh catalog ${catalog_name}"""
+            }
+            sql "use ${catalog_name}.temp_database"
+            qt_sql01 """select * from temp_table"""
+            sql """CALL EXECUTE_STMT("${catalog_name}",  "drop database if 
exists temp_database")"""
+        }
+    }
+}
+


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

Reply via email to