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

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


The following commit(s) were added to refs/heads/branch-2.1 by this push:
     new ede1253666b [fix](catalog) fix filtered database when 
use_meta_cache=true #41939 (#42114)
ede1253666b is described below

commit ede1253666b434a98878d137109ddcb65eb8ae96
Author: Rayner Chen <morning...@163.com>
AuthorDate: Sat Oct 19 08:33:35 2024 +0800

    [fix](catalog) fix filtered database when use_meta_cache=true #41939 
(#42114)
    
    cherry pick from #41939
---
 .../apache/doris/datasource/ExternalCatalog.java   |  40 +++--
 .../doris/datasource/ExternalCatalogTest.java      | 196 +++++++++++++++++++++
 2 files changed, 218 insertions(+), 18 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 fb99c4193ca..50edcbbf31f 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
@@ -51,6 +51,7 @@ import org.apache.doris.datasource.metacache.MetaCache;
 import org.apache.doris.datasource.operations.ExternalMetadataOps;
 import org.apache.doris.datasource.paimon.PaimonExternalDatabase;
 import org.apache.doris.datasource.property.PropertyConverter;
+import org.apache.doris.datasource.test.TestExternalCatalog;
 import org.apache.doris.datasource.test.TestExternalDatabase;
 import org.apache.doris.fs.remote.dfs.DFSFileSystem;
 import org.apache.doris.persist.gson.GsonPostProcessable;
@@ -343,19 +344,8 @@ public abstract class ExternalCatalog
         InitCatalogLog initCatalogLog = new InitCatalogLog();
         initCatalogLog.setCatalogId(id);
         initCatalogLog.setType(logType);
-        List<String> allDatabases = getFilteredDatabaseNames();
-        Map<String, Boolean> includeDatabaseMap = getIncludeDatabaseMap();
-        Map<String, Boolean> excludeDatabaseMap = getExcludeDatabaseMap();
-        for (String dbName : allDatabases) {
-            if (!dbName.equals(InfoSchemaDb.DATABASE_NAME) && 
!dbName.equals(MysqlDb.DATABASE_NAME)) {
-                // Exclude database map take effect with higher priority over 
include database map
-                if (!excludeDatabaseMap.isEmpty() && 
excludeDatabaseMap.containsKey(dbName)) {
-                    continue;
-                }
-                if (!includeDatabaseMap.isEmpty() && 
!includeDatabaseMap.containsKey(dbName)) {
-                    continue;
-                }
-            }
+        List<String> filteredDatabases = getFilteredDatabaseNames();
+        for (String dbName : filteredDatabases) {
             long dbId;
             if (dbNameToId != null && dbNameToId.containsKey(dbName)) {
                 dbId = dbNameToId.get(dbName);
@@ -386,6 +376,20 @@ public abstract class ExternalCatalog
         allDatabases.add(InfoSchemaDb.DATABASE_NAME);
         allDatabases.remove(MysqlDb.DATABASE_NAME);
         allDatabases.add(MysqlDb.DATABASE_NAME);
+        Map<String, Boolean> includeDatabaseMap = getIncludeDatabaseMap();
+        Map<String, Boolean> excludeDatabaseMap = getExcludeDatabaseMap();
+        allDatabases = allDatabases.stream().filter(dbName -> {
+            if (!dbName.equals(InfoSchemaDb.DATABASE_NAME) && 
!dbName.equals(MysqlDb.DATABASE_NAME)) {
+                // Exclude database map take effect with higher priority over 
include database map
+                if (!excludeDatabaseMap.isEmpty() && 
excludeDatabaseMap.containsKey(dbName)) {
+                    return false;
+                }
+                if (!includeDatabaseMap.isEmpty() && 
!includeDatabaseMap.containsKey(dbName)) {
+                    return false;
+                }
+            }
+            return true;
+        }).collect(Collectors.toList());
         return allDatabases;
     }
 
@@ -669,11 +673,11 @@ public abstract class ExternalCatalog
             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) {
+        if (checkExists && (!FeConstants.runningUnitTest || this instanceof 
TestExternalCatalog)) {
             try {
                 List<String> dbNames = getDbNames();
                 if (!dbNames.contains(dbName)) {
-                    dbNames = listDatabaseNames();
+                    dbNames = getFilteredDatabaseNames();
                     if (!dbNames.contains(dbName)) {
                         return null;
                     }
@@ -822,15 +826,15 @@ public abstract class ExternalCatalog
         throw new NotImplementedException("registerDatabase not implemented");
     }
 
-    public Map<String, Boolean> getIncludeDatabaseMap() {
+    protected Map<String, Boolean> getIncludeDatabaseMap() {
         return getSpecifiedDatabaseMap(Resource.INCLUDE_DATABASE_LIST);
     }
 
-    public Map<String, Boolean> getExcludeDatabaseMap() {
+    protected Map<String, Boolean> getExcludeDatabaseMap() {
         return getSpecifiedDatabaseMap(Resource.EXCLUDE_DATABASE_LIST);
     }
 
-    public Map<String, Boolean> getSpecifiedDatabaseMap(String 
catalogPropertyKey) {
+    private Map<String, Boolean> getSpecifiedDatabaseMap(String 
catalogPropertyKey) {
         String specifiedDatabaseList = 
catalogProperty.getOrDefault(catalogPropertyKey, "");
         Map<String, Boolean> specifiedDatabaseMap = Maps.newHashMap();
         specifiedDatabaseList = specifiedDatabaseList.trim();
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/datasource/ExternalCatalogTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/datasource/ExternalCatalogTest.java
index f527da2725e..43348ca8a0e 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/datasource/ExternalCatalogTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/datasource/ExternalCatalogTest.java
@@ -17,16 +17,108 @@
 
 package org.apache.doris.datasource;
 
+import org.apache.doris.analysis.CreateCatalogStmt;
+import org.apache.doris.catalog.Column;
+import org.apache.doris.catalog.Env;
+import org.apache.doris.catalog.PrimitiveType;
+import org.apache.doris.common.FeConstants;
 import org.apache.doris.datasource.hive.HMSExternalCatalog;
+import org.apache.doris.datasource.test.TestExternalCatalog;
+import org.apache.doris.mysql.privilege.Auth;
+import org.apache.doris.qe.ConnectContext;
+import org.apache.doris.qe.QueryState.MysqlStateType;
+import org.apache.doris.qe.StmtExecutor;
 import org.apache.doris.utframe.TestWithFeService;
 
+import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
 import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 public class ExternalCatalogTest extends TestWithFeService {
+    private static Auth auth;
+    private static Env env;
+    private CatalogMgr mgr;
+    private ConnectContext rootCtx;
+
+    @Override
+    protected void runBeforeAll() throws Exception {
+        FeConstants.runningUnitTest = true;
+        mgr = Env.getCurrentEnv().getCatalogMgr();
+        rootCtx = createDefaultCtx();
+        env = Env.getCurrentEnv();
+        auth = env.getAuth();
+        // 1. create test catalog
+        CreateCatalogStmt testCatalog = (CreateCatalogStmt) 
parseAndAnalyzeStmt(
+                "create catalog test1 properties(\n"
+                        + "    \"type\" = \"test\",\n"
+                        + "    \"catalog_provider.class\" "
+                        + "= 
\"org.apache.doris.datasource.RefreshCatalogTest$RefreshCatalogProvider\",\n"
+                        + "    \"include_database_list\" = \"db1\"\n"
+                        + ");",
+                rootCtx);
+        env.getCatalogMgr().createCatalog(testCatalog);
+
+        testCatalog = (CreateCatalogStmt) parseAndAnalyzeStmt(
+                "create catalog test2 properties(\n"
+                        + "    \"type\" = \"test\",\n"
+                        + "    \"catalog_provider.class\" "
+                        + "= 
\"org.apache.doris.datasource.RefreshCatalogTest$RefreshCatalogProvider\",\n"
+                        + "    \"exclude_database_list\" = \"db1\"\n"
+                        + ");",
+                rootCtx);
+        env.getCatalogMgr().createCatalog(testCatalog);
+
+        testCatalog = (CreateCatalogStmt) parseAndAnalyzeStmt(
+                "create catalog test3 properties(\n"
+                        + "    \"type\" = \"test\",\n"
+                        + "    \"catalog_provider.class\" "
+                        + "= 
\"org.apache.doris.datasource.RefreshCatalogTest$RefreshCatalogProvider\",\n"
+                        + "    \"include_database_list\" = \"db1\",\n"
+                        + "    \"exclude_database_list\" = \"db1\"\n"
+                        + ");",
+                rootCtx);
+        env.getCatalogMgr().createCatalog(testCatalog);
+
+        // use_meta_cache=false
+        testCatalog = (CreateCatalogStmt) parseAndAnalyzeStmt(
+                "create catalog test4 properties(\n"
+                        + "    \"type\" = \"test\",\n"
+                        + "    \"use_meta_cache\" = \"false\",\n"
+                        + "    \"catalog_provider.class\" "
+                        + "= 
\"org.apache.doris.datasource.RefreshCatalogTest$RefreshCatalogProvider\",\n"
+                        + "    \"include_database_list\" = \"db1\"\n"
+                        + ");",
+                rootCtx);
+        env.getCatalogMgr().createCatalog(testCatalog);
+
+        testCatalog = (CreateCatalogStmt) parseAndAnalyzeStmt(
+                "create catalog test5 properties(\n"
+                        + "    \"type\" = \"test\",\n"
+                        + "    \"use_meta_cache\" = \"false\",\n"
+                        + "    \"catalog_provider.class\" "
+                        + "= 
\"org.apache.doris.datasource.RefreshCatalogTest$RefreshCatalogProvider\",\n"
+                        + "    \"exclude_database_list\" = \"db1\"\n"
+                        + ");",
+                rootCtx);
+        env.getCatalogMgr().createCatalog(testCatalog);
+
+        testCatalog = (CreateCatalogStmt) parseAndAnalyzeStmt(
+                "create catalog test6 properties(\n"
+                        + "    \"type\" = \"test\",\n"
+                        + "    \"use_meta_cache\" = \"false\",\n"
+                        + "    \"catalog_provider.class\" "
+                        + "= 
\"org.apache.doris.datasource.RefreshCatalogTest$RefreshCatalogProvider\",\n"
+                        + "    \"include_database_list\" = \"db1\",\n"
+                        + "    \"exclude_database_list\" = \"db1\"\n"
+                        + ");",
+                rootCtx);
+        env.getCatalogMgr().createCatalog(testCatalog);
+    }
 
     @Test
     public void testExternalCatalogAutoAnalyze() throws Exception {
@@ -48,4 +140,108 @@ public class ExternalCatalogTest extends TestWithFeService 
{
         catalog.modifyCatalogProps(prop);
         Assertions.assertTrue(catalog.enableAutoAnalyze());
     }
+
+    @Test
+    public void testExternalCatalogFilteredDatabase() throws Exception {
+        // 1. use_meta_cache=true
+        TestExternalCatalog ctl = (TestExternalCatalog) 
mgr.getCatalog("test1");
+        List<String> dbNames = ctl.getDbNames();
+        System.out.println(dbNames);
+        Assertions.assertEquals(3, dbNames.size());
+        Assertions.assertTrue(!dbNames.contains("db2"));
+
+        ctl = (TestExternalCatalog) mgr.getCatalog("test2");
+        // before get dbnames
+        String useDb = "use test2.db3";
+        StmtExecutor stmtExecutor = new StmtExecutor(rootCtx, useDb);
+        stmtExecutor.execute();
+        
Assertions.assertTrue(rootCtx.getState().getErrorMessage().contains("Unknown 
database 'db3'"));
+
+        dbNames = ctl.getDbNames();
+        System.out.println(dbNames);
+        Assertions.assertEquals(3, dbNames.size());
+        Assertions.assertTrue(!dbNames.contains("db1"));
+
+        ctl = (TestExternalCatalog) mgr.getCatalog("test3");
+        dbNames = ctl.getDbNames();
+        System.out.println(dbNames);
+        Assertions.assertEquals(2, dbNames.size());
+        Assertions.assertTrue(!dbNames.contains("db1"));
+        Assertions.assertTrue(!dbNames.contains("db2"));
+
+        // use non exist db
+        useDb = "use test2.db3";
+        stmtExecutor = new StmtExecutor(rootCtx, useDb);
+        stmtExecutor.execute();
+        
Assertions.assertTrue(rootCtx.getState().getErrorMessage().contains("Unknown 
database 'db3'"));
+
+        // use exist db
+        useDb = "use test2.db2";
+        stmtExecutor = new StmtExecutor(rootCtx, useDb);
+        stmtExecutor.execute();
+        Assertions.assertEquals(MysqlStateType.OK, 
rootCtx.getState().getStateType());
+
+        // 2. use_meta_cache=false
+        ctl = (TestExternalCatalog) mgr.getCatalog("test4");
+        dbNames = ctl.getDbNames();
+        System.out.println(dbNames);
+        Assertions.assertEquals(3, dbNames.size());
+        Assertions.assertTrue(!dbNames.contains("db2"));
+
+        ctl = (TestExternalCatalog) mgr.getCatalog("test5");
+        dbNames = ctl.getDbNames();
+        System.out.println(dbNames);
+        Assertions.assertEquals(3, dbNames.size());
+        Assertions.assertTrue(!dbNames.contains("db1"));
+
+        ctl = (TestExternalCatalog) mgr.getCatalog("test6");
+        dbNames = ctl.getDbNames();
+        System.out.println(dbNames);
+        Assertions.assertEquals(2, dbNames.size());
+        Assertions.assertTrue(!dbNames.contains("db1"));
+        Assertions.assertTrue(!dbNames.contains("db2"));
+
+        // use non exist db
+        useDb = "use test5.db3";
+        stmtExecutor = new StmtExecutor(rootCtx, useDb);
+        stmtExecutor.execute();
+        
Assertions.assertTrue(rootCtx.getState().getErrorMessage().contains("Unknown 
database 'db3'"));
+
+        // use exist db
+        useDb = "use test5.db2";
+        stmtExecutor = new StmtExecutor(rootCtx, useDb);
+        stmtExecutor.execute();
+        Assertions.assertEquals(MysqlStateType.OK, 
rootCtx.getState().getStateType());
+    }
+
+    public static class RefreshCatalogProvider implements 
TestExternalCatalog.TestCatalogProvider {
+        public static final Map<String, Map<String, List<Column>>> MOCKED_META;
+
+        static {
+            MOCKED_META = Maps.newHashMap();
+            Map<String, List<Column>> tblSchemaMap1 = Maps.newHashMap();
+            // db1
+            tblSchemaMap1.put("tbl11", Lists.newArrayList(
+                    new Column("a11", PrimitiveType.BIGINT),
+                    new Column("a12", PrimitiveType.STRING),
+                    new Column("a13", PrimitiveType.FLOAT)));
+            tblSchemaMap1.put("tbl12", Lists.newArrayList(
+                    new Column("b21", PrimitiveType.BIGINT),
+                    new Column("b22", PrimitiveType.STRING),
+                    new Column("b23", PrimitiveType.FLOAT)));
+            MOCKED_META.put("db1", tblSchemaMap1);
+            // db2
+            Map<String, List<Column>> tblSchemaMap2 = Maps.newHashMap();
+            tblSchemaMap2.put("tbl21", Lists.newArrayList(
+                    new Column("c11", PrimitiveType.BIGINT),
+                    new Column("c12", PrimitiveType.STRING),
+                    new Column("c13", PrimitiveType.FLOAT)));
+            MOCKED_META.put("db2", tblSchemaMap2);
+        }
+
+        @Override
+        public Map<String, Map<String, List<Column>>> getMetadata() {
+            return MOCKED_META;
+        }
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to