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

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


The following commit(s) were added to refs/heads/branch-4.0 by this push:
     new 076332bb590 branch-4.0: [Fix](udf) fix frontends udf return rows 
incompatible with show frontends command #60211 (#60602)
076332bb590 is described below

commit 076332bb590d6ee0f85e14ab1d91396e0fbc0956
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Fri Feb 13 15:45:03 2026 +0800

    branch-4.0: [Fix](udf) fix frontends udf return rows incompatible with show 
frontends command #60211 (#60602)
    
    Cherry-picked from #60211
    
    Co-authored-by: heguanhui <[email protected]>
---
 .../doris/common/proc/FrontendsProcNode.java       | 16 +-----
 .../trees/plans/commands/ShowFrontendsCommand.java |  6 ++-
 .../FrontendsDisksTableValuedFunction.java         | 11 ++++
 .../FrontendsTableValuedFunction.java              | 16 +++++-
 .../plans/commands/ShowFrontendsCommandTest.java   | 62 +++++++++++++++++++++-
 .../tvf/test_frontends_disks_tvf.groovy            | 13 +++++
 .../tvf/test_frontends_tvf.groovy                  | 26 ++++++++-
 7 files changed, 129 insertions(+), 21 deletions(-)

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 0d4dccb196a..a4c26b57af6 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
@@ -26,9 +26,9 @@ import org.apache.doris.qe.ConnectContext;
 import org.apache.doris.service.FeDiskInfo;
 import org.apache.doris.system.Frontend;
 import org.apache.doris.system.SystemInfoService.HostInfo;
+import org.apache.doris.tablefunction.FrontendsTableValuedFunction;
 
 import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
@@ -45,18 +45,6 @@ import java.util.List;
 public class FrontendsProcNode implements ProcNodeInterface {
     private static final Logger LOG = 
LogManager.getLogger(FrontendsProcNode.class);
 
-    public static final ImmutableList<String> TITLE_NAMES = new 
ImmutableList.Builder<String>()
-            
.add("Name").add("Host").add("EditLogPort").add("HttpPort").add("QueryPort").add("RpcPort")
-            
.add("ArrowFlightSqlPort").add("Role").add("IsMaster").add("ClusterId").add("Join").add("Alive")
-            
.add("ReplayedJournalId").add("LastStartTime").add("LastHeartbeat").add("IsHelper").add("ErrMsg")
-            .add("Version").add("CurrentConnected").add("LiveSince")
-            .build();
-
-    public static final ImmutableList<String> DISK_TITLE_NAMES = new 
ImmutableList.Builder<String>()
-            
.add("Name").add("Host").add("DirType").add("Dir").add("Filesystem")
-            
.add("Capacity").add("Used").add("Available").add("UseRate").add("MountOn")
-            .build();
-
     private Env env;
 
     public FrontendsProcNode(Env env) {
@@ -66,7 +54,7 @@ public class FrontendsProcNode implements ProcNodeInterface {
     @Override
     public ProcResult fetchResult() {
         BaseProcResult result = new BaseProcResult();
-        result.setNames(TITLE_NAMES);
+        result.setNames(FrontendsTableValuedFunction.getFrontendsTitleNames());
 
         List<List<String>> infos = Lists.newArrayList();
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowFrontendsCommand.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowFrontendsCommand.java
index d461a3efbb3..e119f3f3e69 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowFrontendsCommand.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowFrontendsCommand.java
@@ -34,6 +34,8 @@ import org.apache.doris.qe.ConnectContext;
 import org.apache.doris.qe.ShowResultSet;
 import org.apache.doris.qe.ShowResultSetMetaData;
 import org.apache.doris.qe.StmtExecutor;
+import org.apache.doris.tablefunction.FrontendsDisksTableValuedFunction;
+import org.apache.doris.tablefunction.FrontendsTableValuedFunction;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
@@ -60,9 +62,9 @@ public class ShowFrontendsCommand extends ShowCommand {
     public ShowResultSetMetaData getMetaData() {
         ShowResultSetMetaData.Builder builder = 
ShowResultSetMetaData.builder();
 
-        ImmutableList<String> titles = FrontendsProcNode.TITLE_NAMES;
+        ImmutableList<String> titles = 
FrontendsTableValuedFunction.getFrontendsTitleNames();
         if (detail != null && detail.equalsIgnoreCase("disks")) {
-            titles = FrontendsProcNode.DISK_TITLE_NAMES;
+            titles = 
FrontendsDisksTableValuedFunction.getFrontendsDisksTitleNames();
         }
         for (String title : titles) {
             builder.addColumn(new Column(title, ScalarType.createVarchar(30)));
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/tablefunction/FrontendsDisksTableValuedFunction.java
 
b/fe/fe-core/src/main/java/org/apache/doris/tablefunction/FrontendsDisksTableValuedFunction.java
index 31ddf55313a..7380585fdae 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/tablefunction/FrontendsDisksTableValuedFunction.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/tablefunction/FrontendsDisksTableValuedFunction.java
@@ -56,13 +56,17 @@ public class FrontendsDisksTableValuedFunction extends 
MetadataTableValuedFuncti
             new Column("MountOn", ScalarType.createStringType()));
 
     private static final ImmutableMap<String, Integer> COLUMN_TO_INDEX;
+    private static final ImmutableList<String> TITLE_NAMES;
 
     static {
         ImmutableMap.Builder<String, Integer> builder = new 
ImmutableMap.Builder();
+        ImmutableList.Builder<String> immutableListBuilder = 
ImmutableList.builder();
         for (int i = 0; i < SCHEMA.size(); i++) {
             builder.put(SCHEMA.get(i).getName().toLowerCase(), i);
+            immutableListBuilder.add(SCHEMA.get(i).getName());
         }
         COLUMN_TO_INDEX = builder.build();
+        TITLE_NAMES = immutableListBuilder.build();
     }
 
     public static Integer getColumnIndexFromColumnName(String columnName) {
@@ -105,4 +109,11 @@ public class FrontendsDisksTableValuedFunction extends 
MetadataTableValuedFuncti
     public List<Column> getTableColumns() throws AnalysisException {
         return SCHEMA;
     }
+
+    /**
+     * unify title names for frontends_disks function and show frontends disks 
command
+     */
+    public static ImmutableList<String> getFrontendsDisksTitleNames() {
+        return TITLE_NAMES;
+    }
 }
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 efb90070e65..79b61d33b28 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
@@ -62,16 +62,21 @@ public class FrontendsTableValuedFunction extends 
MetadataTableValuedFunction {
             new Column("IsHelper", ScalarType.createStringType()),
             new Column("ErrMsg", ScalarType.createStringType()),
             new Column("Version", ScalarType.createStringType()),
-            new Column("CurrentConnected", ScalarType.createStringType()));
-
+            new Column("CurrentConnected", ScalarType.createStringType()),
+            new Column("LiveSince", ScalarType.createStringType())
+    );
     private static final ImmutableMap<String, Integer> COLUMN_TO_INDEX;
+    private static final ImmutableList<String> TITLE_NAMES;
 
     static {
         ImmutableMap.Builder<String, Integer> builder = new 
ImmutableMap.Builder();
+        ImmutableList.Builder<String> immutableListBuilder = 
ImmutableList.builder();
         for (int i = 0; i < SCHEMA.size(); i++) {
             builder.put(SCHEMA.get(i).getName().toLowerCase(), i);
+            immutableListBuilder.add(SCHEMA.get(i).getName());
         }
         COLUMN_TO_INDEX = builder.build();
+        TITLE_NAMES = immutableListBuilder.build();
     }
 
     public static Integer getColumnIndexFromColumnName(String columnName) {
@@ -114,4 +119,11 @@ public class FrontendsTableValuedFunction extends 
MetadataTableValuedFunction {
     public List<Column> getTableColumns() throws AnalysisException {
         return SCHEMA;
     }
+
+    /**
+     * unify title names for frontends function and show frontends command
+     */
+    public static ImmutableList<String> getFrontendsTitleNames() {
+        return TITLE_NAMES;
+    }
 }
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/ShowFrontendsCommandTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/ShowFrontendsCommandTest.java
index 294b43d3960..68824500903 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/ShowFrontendsCommandTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/ShowFrontendsCommandTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.doris.nereids.trees.plans.commands;
 
+import org.apache.doris.catalog.Column;
 import org.apache.doris.catalog.Env;
 import org.apache.doris.catalog.InfoSchemaDb;
 import org.apache.doris.common.AnalysisException;
@@ -25,12 +26,18 @@ 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.qe.ShowResultSet;
+import org.apache.doris.tablefunction.FrontendsDisksTableValuedFunction;
+import org.apache.doris.tablefunction.FrontendsTableValuedFunction;
 
+import com.google.common.collect.ImmutableList;
 import mockit.Expectations;
 import mockit.Mocked;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
+import java.util.List;
+
 public class ShowFrontendsCommandTest {
     private static final String internalCtl = 
InternalCatalog.INTERNAL_CATALOG_NAME;
     private static final String infoDB = InfoSchemaDb.DATABASE_NAME;
@@ -80,7 +87,13 @@ public class ShowFrontendsCommandTest {
     public void testNormal() throws Exception {
         runBefore();
         ShowFrontendsCommand command = new ShowFrontendsCommand(null);
-        Assertions.assertDoesNotThrow(() -> command.doRun(ctx, null));
+        ShowResultSet showResultSet = command.doRun(ctx, null);
+        List<Column> columnList = showResultSet.getMetaData().getColumns();
+        ImmutableList<String> frontendsTitleNames = 
FrontendsTableValuedFunction.getFrontendsTitleNames();
+        Assertions.assertTrue(!columnList.isEmpty() && columnList.size() == 
frontendsTitleNames.size());
+        for (int i = 0; i < frontendsTitleNames.size(); i++) {
+            
Assertions.assertTrue(columnList.get(i).getName().equalsIgnoreCase(frontendsTitleNames.get(i)));
+        }
     }
 
     @Test
@@ -115,4 +128,51 @@ public class ShowFrontendsCommandTest {
         ShowFrontendsCommand command = new ShowFrontendsCommand(null);
         Assertions.assertThrows(AnalysisException.class, () -> 
command.doRun(ctx, null));
     }
+
+    @Test
+    public void testNormalShowFrontendsDisks() throws Exception {
+        runBefore();
+        ShowFrontendsCommand command = new ShowFrontendsCommand("disks");
+        ShowResultSet showResultSet = command.doRun(ctx, null);
+        List<Column> columnList = showResultSet.getMetaData().getColumns();
+        ImmutableList<String> frontendsDisksTitleNames = 
FrontendsDisksTableValuedFunction
+                .getFrontendsDisksTitleNames();
+        Assertions.assertTrue(!columnList.isEmpty() && columnList.size() == 
frontendsDisksTitleNames.size());
+        for (int i = 0; i < frontendsDisksTitleNames.size(); i++) {
+            
Assertions.assertTrue(columnList.get(i).getName().equalsIgnoreCase(frontendsDisksTitleNames.get(i)));
+        }
+    }
+
+    @Test
+    public void testNoPrivilegeShowFrontendsDisks() throws Exception {
+        new Expectations() {
+            {
+                Env.getCurrentEnv();
+                minTimes = 0;
+                result = env;
+
+                env.getAccessManager();
+                minTimes = 0;
+                result = accessControllerManager;
+
+                env.getCatalogMgr();
+                minTimes = 0;
+                result = catalogMgr;
+
+                catalogMgr.getCatalog(anyString);
+                minTimes = 0;
+                result = catalog;
+
+                ConnectContext.get();
+                minTimes = 0;
+                result = ctx;
+
+                accessControllerManager.checkDbPriv(ctx, internalCtl, infoDB, 
PrivPredicate.SELECT);
+                minTimes = 0;
+                result = false;
+            }
+        };
+        ShowFrontendsCommand command = new ShowFrontendsCommand("disks");
+        Assertions.assertThrows(AnalysisException.class, () -> 
command.doRun(ctx, null));
+    }
 }
diff --git 
a/regression-test/suites/external_table_p0/tvf/test_frontends_disks_tvf.groovy 
b/regression-test/suites/external_table_p0/tvf/test_frontends_disks_tvf.groovy
index 509fa5a75dc..07a7ca0639e 100644
--- 
a/regression-test/suites/external_table_p0/tvf/test_frontends_disks_tvf.groovy
+++ 
b/regression-test/suites/external_table_p0/tvf/test_frontends_disks_tvf.groovy
@@ -21,6 +21,19 @@ suite("test_frontends_disks_tvf", 
"p0,external,external_docker") {
     assertTrue(table.size() > 0)
     assertTrue(table[0].size() == 10)
 
+    List<List<Object>> titleNames =  sql """ describe function 
frontends_disks(); """
+
+    assertTrue(titleNames[0][0] == "Name")
+    assertTrue(titleNames[1][0] == "Host")
+    assertTrue(titleNames[2][0] == "DirType")
+    assertTrue(titleNames[3][0] == "Dir")
+    assertTrue(titleNames[4][0] == "Filesystem")
+    assertTrue(titleNames[5][0] == "Capacity")
+    assertTrue(titleNames[6][0] == "Used")
+    assertTrue(titleNames[7][0] == "Available")
+    assertTrue(titleNames[8][0] == "UseRate")
+    assertTrue(titleNames[9][0] == "MountOn")
+
     // filter columns
     table = sql """ select Name from `frontends_disks`();"""
     assertTrue(table.size() > 0)
diff --git 
a/regression-test/suites/external_table_p0/tvf/test_frontends_tvf.groovy 
b/regression-test/suites/external_table_p0/tvf/test_frontends_tvf.groovy
index 0fa743d03cd..623c54ae3c6 100644
--- a/regression-test/suites/external_table_p0/tvf/test_frontends_tvf.groovy
+++ b/regression-test/suites/external_table_p0/tvf/test_frontends_tvf.groovy
@@ -20,7 +20,29 @@ 
suite("test_frontends_tvf","p0,external,tvf,external_docker") {
     List<List<Object>> table =  sql """ select * from `frontends`(); """
     logger.info("${table}")
     assertTrue(table.size() > 0)
-    assertTrue(table[0].size() == 19)
+    assertTrue(table[0].size() == 20)
+
+    List<List<Object>> titleNames =  sql """ describe function frontends(); """
+    assertTrue(titleNames[0][0] == "Name")
+    assertTrue(titleNames[1][0] == "Host")
+    assertTrue(titleNames[2][0] == "EditLogPort")
+    assertTrue(titleNames[3][0] == "HttpPort")
+    assertTrue(titleNames[4][0] == "QueryPort")
+    assertTrue(titleNames[5][0] == "RpcPort")
+    assertTrue(titleNames[6][0] == "ArrowFlightSqlPort")
+    assertTrue(titleNames[7][0] == "Role")
+    assertTrue(titleNames[8][0] == "IsMaster")
+    assertTrue(titleNames[9][0] == "ClusterId")
+    assertTrue(titleNames[10][0] == "Join")
+    assertTrue(titleNames[11][0] == "Alive")
+    assertTrue(titleNames[12][0] == "ReplayedJournalId")
+    assertTrue(titleNames[13][0] == "LastStartTime")
+    assertTrue(titleNames[14][0] == "LastHeartbeat")
+    assertTrue(titleNames[15][0] == "IsHelper")
+    assertTrue(titleNames[16][0] == "ErrMsg")
+    assertTrue(titleNames[17][0] == "Version")
+    assertTrue(titleNames[18][0] == "CurrentConnected")
+    assertTrue(titleNames[19][0] == "LiveSince")
 
     // filter columns
     table = sql """ select Name from `frontends`();"""
@@ -46,7 +68,7 @@ suite("test_frontends_tvf","p0,external,tvf,external_docker") 
{
     sql """ select Name, Host, EditLogPort
             HttpPort, QueryPort, RpcPort, ArrowFlightSqlPort, `Role`, 
IsMaster, ClusterId
             `Join`, Alive, ReplayedJournalId, LastHeartbeat
-            IsHelper, ErrMsg, Version, CurrentConnected from frontends();
+            IsHelper, ErrMsg, Version, CurrentConnected, LiveSince from 
frontends();
     """
 
     // test exception


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

Reply via email to