diff --git a/fe/fe-core/src/main/java/org/apache/doris/common/proc/FrontendsProcNode.java b/fe/fe-core/src/main/java/org/apache/doris/common/proc/FrontendsProcNode.java index a4c26b57af6a96..f83a49bf8bfc05 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/common/proc/FrontendsProcNode.java +++ b/fe/fe-core/src/main/java/org/apache/doris/common/proc/FrontendsProcNode.java @@ -93,6 +93,10 @@ public static List> getFrontendWithRpcPort(Env env, boolea } public static void getFrontendsInfo(Env env, List> infos) { + getFrontendsInfo(env, infos, null); + } + + public static void getFrontendsInfo(Env env, List> infos, String currentConnectedFeHost) { InetSocketAddress master = null; try { master = env.getHaProtocol().getLeader(); @@ -109,7 +113,10 @@ public static void getFrontendsInfo(Env env, List> infos) { // Because the `show frontend` stmt maybe forwarded from other FE. // if we only get self node from currrent catalog, the "CurrentConnected" field will always points to Msater FE. String selfNode = Env.getCurrentEnv().getSelfNode().getHost(); - if (ConnectContext.get() != null && !Strings.isNullOrEmpty(ConnectContext.get().getCurrentConnectedFEIp())) { + if (!Strings.isNullOrEmpty(currentConnectedFeHost)) { + selfNode = currentConnectedFeHost; + } else if (ConnectContext.get() != null + && !Strings.isNullOrEmpty(ConnectContext.get().getCurrentConnectedFEIp())) { selfNode = ConnectContext.get().getCurrentConnectedFEIp(); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/tablefunction/FrontendsTableValuedFunction.java b/fe/fe-core/src/main/java/org/apache/doris/tablefunction/FrontendsTableValuedFunction.java index 79b61d33b28555..05b709cd523e3b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/tablefunction/FrontendsTableValuedFunction.java +++ b/fe/fe-core/src/main/java/org/apache/doris/tablefunction/FrontendsTableValuedFunction.java @@ -30,6 +30,7 @@ import org.apache.doris.thrift.TMetaScanRange; import org.apache.doris.thrift.TMetadataType; +import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -105,7 +106,12 @@ public TMetaScanRange getMetaScanRange(List requiredFileds) { TMetaScanRange metaScanRange = new TMetaScanRange(); metaScanRange.setMetadataType(TMetadataType.FRONTENDS); TFrontendsMetadataParams frontendsMetadataParams = new TFrontendsMetadataParams(); - frontendsMetadataParams.setClusterName(""); + String currentConnectedFe = Env.getCurrentEnv().getSelfNode().getHost(); + if (ConnectContext.get() != null + && !Strings.isNullOrEmpty(ConnectContext.get().getCurrentConnectedFEIp())) { + currentConnectedFe = ConnectContext.get().getCurrentConnectedFEIp(); + } + frontendsMetadataParams.setCurrentConnectedFeHost(currentConnectedFe); metaScanRange.setFrontendsParams(frontendsMetadataParams); return metaScanRange; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/tablefunction/MetadataGenerator.java b/fe/fe-core/src/main/java/org/apache/doris/tablefunction/MetadataGenerator.java index fd70373fbdb2fb..b531216dee945b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/tablefunction/MetadataGenerator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/tablefunction/MetadataGenerator.java @@ -92,6 +92,7 @@ import org.apache.doris.thrift.TCell; import org.apache.doris.thrift.TFetchSchemaTableDataRequest; import org.apache.doris.thrift.TFetchSchemaTableDataResult; +import org.apache.doris.thrift.TFrontendsMetadataParams; import org.apache.doris.thrift.THudiMetadataParams; import org.apache.doris.thrift.THudiQueryType; import org.apache.doris.thrift.TJobsMetadataParams; @@ -533,11 +534,12 @@ private static TFetchSchemaTableDataResult frontendsMetadataResult(TMetadataTabl return errorResult("frontends metadata param is not set."); } + TFrontendsMetadataParams frontendsParam = params.getFrontendsMetadataParams(); TFetchSchemaTableDataResult result = new TFetchSchemaTableDataResult(); List dataBatch = Lists.newArrayList(); List> infos = Lists.newArrayList(); - FrontendsProcNode.getFrontendsInfo(Env.getCurrentEnv(), infos); + FrontendsProcNode.getFrontendsInfo(Env.getCurrentEnv(), infos, frontendsParam.getCurrentConnectedFeHost()); for (List info : infos) { TRow trow = new TRow(); for (String item : info) { diff --git a/fe/fe-core/src/test/java/org/apache/doris/tablefunction/FrontendsTableValuedFunctionTest.java b/fe/fe-core/src/test/java/org/apache/doris/tablefunction/FrontendsTableValuedFunctionTest.java new file mode 100644 index 00000000000000..745bec1b302d24 --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/tablefunction/FrontendsTableValuedFunctionTest.java @@ -0,0 +1,93 @@ +// 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.tablefunction; + +import org.apache.doris.catalog.Env; +import org.apache.doris.catalog.InfoSchemaDb; +import org.apache.doris.datasource.InternalCatalog; +import org.apache.doris.mysql.privilege.AccessControllerManager; +import org.apache.doris.mysql.privilege.PrivPredicate; +import org.apache.doris.qe.ConnectContext; +import org.apache.doris.system.SystemInfoService.HostInfo; +import org.apache.doris.thrift.TMetaScanRange; + +import mockit.Expectations; +import mockit.Mocked; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Collections; +import java.util.HashMap; + +public class FrontendsTableValuedFunctionTest { + private static final String INTERNAL_CTL = InternalCatalog.INTERNAL_CATALOG_NAME; + private static final String INFO_DB = InfoSchemaDb.DATABASE_NAME; + + @Mocked + private Env env; + @Mocked + private AccessControllerManager accessControllerManager; + @Mocked + private ConnectContext ctx; + + private void mockContext(String selfHost, String currentConnectedFe) { + new Expectations() { + { + Env.getCurrentEnv(); + minTimes = 0; + result = env; + + env.getAccessManager(); + minTimes = 0; + result = accessControllerManager; + + ConnectContext.get(); + minTimes = 0; + result = ctx; + + accessControllerManager.checkDbPriv(ctx, INTERNAL_CTL, INFO_DB, PrivPredicate.SELECT); + minTimes = 0; + result = true; + + env.getSelfNode(); + minTimes = 0; + result = new HostInfo(selfHost, 9010); + + ctx.getCurrentConnectedFEIp(); + minTimes = 0; + result = currentConnectedFe; + } + }; + } + + @Test + public void testGetMetaScanRangeUseCurrentConnectedFe() throws Exception { + mockContext("self-fe-host", "connected-fe-host"); + FrontendsTableValuedFunction tvf = new FrontendsTableValuedFunction(new HashMap<>()); + TMetaScanRange range = tvf.getMetaScanRange(Collections.emptyList()); + Assert.assertEquals("connected-fe-host", range.getFrontendsParams().getCurrentConnectedFeHost()); + } + + @Test + public void testGetMetaScanRangeFallbackToSelfNode() throws Exception { + mockContext("self-fe-host", ""); + FrontendsTableValuedFunction tvf = new FrontendsTableValuedFunction(new HashMap<>()); + TMetaScanRange range = tvf.getMetaScanRange(Collections.emptyList()); + Assert.assertEquals("self-fe-host", range.getFrontendsParams().getCurrentConnectedFeHost()); + } +} diff --git a/gensrc/thrift/PlanNodes.thrift b/gensrc/thrift/PlanNodes.thrift index 7b281dcf712cb8..03fe657501553e 100644 --- a/gensrc/thrift/PlanNodes.thrift +++ b/gensrc/thrift/PlanNodes.thrift @@ -596,6 +596,7 @@ struct TBackendsMetadataParams { struct TFrontendsMetadataParams { 1: optional string cluster_name + 2: optional string current_connected_fe_host } struct TMaterializedViewsMetadataParams {