You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by lu...@apache.org on 2023/06/19 05:57:48 UTC

[doris] branch master updated: [Enhancement](tvf) Add frontends table-valued-function (#20857)

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

luozenglin 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 26cca5e00a [Enhancement](tvf) Add frontends table-valued-function (#20857)
26cca5e00a is described below

commit 26cca5e00a9822196755bac4f1a205a3de111079
Author: yongjinhou <10...@users.noreply.github.com>
AuthorDate: Mon Jun 19 13:57:40 2023 +0800

    [Enhancement](tvf) Add frontends table-valued-function (#20857)
---
 be/src/vec/exec/scan/vmeta_scanner.cpp             |  22 +++++
 be/src/vec/exec/scan/vmeta_scanner.h               |   2 +
 .../sql-functions/table-functions/backends.md      |  96 +++++++++----------
 .../sql-functions/table-functions/frontends.md     | 104 +++++++++++++++++++++
 docs/sidebars.json                                 |   1 +
 .../sql-functions/table-functions/backends.md      |  96 +++++++++----------
 .../sql-functions/table-functions/frontends.md     | 103 ++++++++++++++++++++
 .../FrontendsTableValuedFunction.java              | 104 +++++++++++++++++++++
 .../doris/tablefunction/MetadataGenerator.java     |  27 ++++++
 .../tablefunction/MetadataTableValuedFunction.java |   2 +
 .../doris/tablefunction/TableValuedFunctionIf.java |   2 +
 gensrc/thrift/FrontendService.thrift               |   1 +
 gensrc/thrift/PlanNodes.thrift                     |   5 +
 gensrc/thrift/Types.thrift                         |   3 +-
 .../test_frontends_tvf.groovy                      |  28 ++++++
 15 files changed, 495 insertions(+), 101 deletions(-)

diff --git a/be/src/vec/exec/scan/vmeta_scanner.cpp b/be/src/vec/exec/scan/vmeta_scanner.cpp
index 67c421b00b..030f710eba 100644
--- a/be/src/vec/exec/scan/vmeta_scanner.cpp
+++ b/be/src/vec/exec/scan/vmeta_scanner.cpp
@@ -210,6 +210,9 @@ Status VMetaScanner::_fetch_metadata(const TMetaScanRange& meta_scan_range) {
     case TMetadataType::BACKENDS:
         RETURN_IF_ERROR(_build_backends_metadata_request(meta_scan_range, &request));
         break;
+    case TMetadataType::FRONTENDS:
+        RETURN_IF_ERROR(_build_frontends_metadata_request(meta_scan_range, &request));
+        break;
     case TMetadataType::WORKLOAD_GROUPS:
         RETURN_IF_ERROR(_build_workload_groups_metadata_request(meta_scan_range, &request));
         break;
@@ -284,6 +287,25 @@ Status VMetaScanner::_build_backends_metadata_request(const TMetaScanRange& meta
     return Status::OK();
 }
 
+Status VMetaScanner::_build_frontends_metadata_request(const TMetaScanRange& meta_scan_range,
+                                                       TFetchSchemaTableDataRequest* request) {
+    VLOG_CRITICAL << "VMetaScanner::_build_frontends_metadata_request";
+    if (!meta_scan_range.__isset.frontends_params) {
+        return Status::InternalError("Can not find TFrontendsMetadataParams from meta_scan_range.");
+    }
+    // create request
+    request->__set_cluster_name("");
+    request->__set_schema_table_name(TSchemaTableName::METADATA_TABLE);
+
+    // create TMetadataTableRequestParams
+    TMetadataTableRequestParams metadata_table_params;
+    metadata_table_params.__set_metadata_type(TMetadataType::FRONTENDS);
+    metadata_table_params.__set_frontends_metadata_params(meta_scan_range.frontends_params);
+
+    request->__set_metada_table_params(metadata_table_params);
+    return Status::OK();
+}
+
 Status VMetaScanner::_build_workload_groups_metadata_request(
         const TMetaScanRange& meta_scan_range, TFetchSchemaTableDataRequest* request) {
     VLOG_CRITICAL << "VMetaScanner::_build_workload_groups_metadata_request";
diff --git a/be/src/vec/exec/scan/vmeta_scanner.h b/be/src/vec/exec/scan/vmeta_scanner.h
index d566225b60..ae3505d19f 100644
--- a/be/src/vec/exec/scan/vmeta_scanner.h
+++ b/be/src/vec/exec/scan/vmeta_scanner.h
@@ -67,6 +67,8 @@ private:
                                            TFetchSchemaTableDataRequest* request);
     Status _build_backends_metadata_request(const TMetaScanRange& meta_scan_range,
                                             TFetchSchemaTableDataRequest* request);
+    Status _build_frontends_metadata_request(const TMetaScanRange& meta_scan_range,
+                                             TFetchSchemaTableDataRequest* request);
     Status _build_workload_groups_metadata_request(const TMetaScanRange& meta_scan_range,
                                                    TFetchSchemaTableDataRequest* request);
 
diff --git a/docs/en/docs/sql-manual/sql-functions/table-functions/backends.md b/docs/en/docs/sql-manual/sql-functions/table-functions/backends.md
index 4fea18e317..7cf23cb9c0 100644
--- a/docs/en/docs/sql-manual/sql-functions/table-functions/backends.md
+++ b/docs/en/docs/sql-manual/sql-functions/table-functions/backends.md
@@ -47,36 +47,34 @@ This function is used in `FROM` clauses.
 The table schema of `backends()` tvf:
 ```
 mysql> desc function backends();
-+-------------------------+--------+------+-------+---------+-------+
-| Field                   | Type   | Null | Key   | Default | Extra |
-+-------------------------+--------+------+-------+---------+-------+
-| BackendId               | BIGINT | No   | false | NULL    | NONE  |
-| Cluster                 | TEXT   | No   | false | NULL    | NONE  |
-| Host                    | TEXT   | No   | false | NULL    | NONE  |
-| HeartbeatPort           | INT    | No   | false | NULL    | NONE  |
-| BePort                  | INT    | No   | false | NULL    | NONE  |
-| HttpPort                | INT    | No   | false | NULL    | NONE  |
-| BrpcPort                | INT    | No   | false | NULL    | NONE  |
-| LastStartTime           | TEXT   | No   | false | NULL    | NONE  |
-| LastHeartbeat           | TEXT   | No   | false | NULL    | NONE  |
-| Alive                   | TEXT   | No   | false | NULL    | NONE  |
-| SystemDecommissioned    | TEXT   | No   | false | NULL    | NONE  |
-| ClusterDecommissioned   | TEXT   | No   | false | NULL    | NONE  |
-| TabletNum               | BIGINT | No   | false | NULL    | NONE  |
-| DataUsedCapacity        | BIGINT | No   | false | NULL    | NONE  |
-| AvailCapacity           | BIGINT | No   | false | NULL    | NONE  |
-| TotalCapacity           | BIGINT | No   | false | NULL    | NONE  |
-| UsedPct                 | DOUBLE | No   | false | NULL    | NONE  |
-| MaxDiskUsedPct          | DOUBLE | No   | false | NULL    | NONE  |
-| RemoteUsedCapacity      | BIGINT | No   | false | NULL    | NONE  |
-| Tag                     | TEXT   | No   | false | NULL    | NONE  |
-| ErrMsg                  | TEXT   | No   | false | NULL    | NONE  |
-| Version                 | TEXT   | No   | false | NULL    | NONE  |
-| Status                  | TEXT   | No   | false | NULL    | NONE  |
-| HeartbeatFailureCounter | INT    | No   | false | NULL    | NONE  |
-| NodeRole                | TEXT   | No   | false | NULL    | NONE  |
-+-------------------------+--------+------+-------+---------+-------+
-25 rows in set (0.04 sec)
++-------------------------+---------+------+-------+---------+-------+
+| Field                   | Type    | Null | Key   | Default | Extra |
++-------------------------+---------+------+-------+---------+-------+
+| BackendId               | BIGINT  | No   | false | NULL    | NONE  |
+| Host                    | TEXT    | No   | false | NULL    | NONE  |
+| HeartbeatPort           | INT     | No   | false | NULL    | NONE  |
+| BePort                  | INT     | No   | false | NULL    | NONE  |
+| HttpPort                | INT     | No   | false | NULL    | NONE  |
+| BrpcPort                | INT     | No   | false | NULL    | NONE  |
+| LastStartTime           | TEXT    | No   | false | NULL    | NONE  |
+| LastHeartbeat           | TEXT    | No   | false | NULL    | NONE  |
+| Alive                   | BOOLEAN | No   | false | NULL    | NONE  |
+| SystemDecommissioned    | BOOLEAN | No   | false | NULL    | NONE  |
+| TabletNum               | BIGINT  | No   | false | NULL    | NONE  |
+| DataUsedCapacity        | BIGINT  | No   | false | NULL    | NONE  |
+| AvailCapacity           | BIGINT  | No   | false | NULL    | NONE  |
+| TotalCapacity           | BIGINT  | No   | false | NULL    | NONE  |
+| UsedPct                 | DOUBLE  | No   | false | NULL    | NONE  |
+| MaxDiskUsedPct          | DOUBLE  | No   | false | NULL    | NONE  |
+| RemoteUsedCapacity      | BIGINT  | No   | false | NULL    | NONE  |
+| Tag                     | TEXT    | No   | false | NULL    | NONE  |
+| ErrMsg                  | TEXT    | No   | false | NULL    | NONE  |
+| Version                 | TEXT    | No   | false | NULL    | NONE  |
+| Status                  | TEXT    | No   | false | NULL    | NONE  |
+| HeartbeatFailureCounter | INT     | No   | false | NULL    | NONE  |
+| NodeRole                | TEXT    | No   | false | NULL    | NONE  |
++-------------------------+---------+------+-------+---------+-------+
+23 rows in set (0.002 sec)
 ```
 
 The information displayed by the `backends` tvf is basically consistent with the information displayed by the `show backends` statement. However, the types of each field in the `backends` tvf are more specific, and you can use the `backends` tvf to perform operations such as filtering and joining.
@@ -87,32 +85,30 @@ The information displayed by the `backends` tvf is authenticated, which is consi
 ```
 mysql> select * from backends()\G
 *************************** 1. row ***************************
-              BackendId: 10022
-                Cluster: default_cluster
-                   Host: 10.16.10.14
-          HeartbeatPort: 9159
-                 BePort: 9169
-               HttpPort: 8149
-               BrpcPort: 8169
-          LastStartTime: 2023-03-24 14:37:00
-          LastHeartbeat: 2023-03-27 20:25:35
-                  Alive: true
-   SystemDecommissioned: false
-  ClusterDecommissioned: false
+              BackendId: 10002
+                   Host: 10.xx.xx.90
+          HeartbeatPort: 9053
+                 BePort: 9063
+               HttpPort: 8043
+               BrpcPort: 8069
+          LastStartTime: 2023-06-15 16:51:02
+          LastHeartbeat: 2023-06-15 17:09:58
+                  Alive: 1
+   SystemDecommissioned: 0
               TabletNum: 21
        DataUsedCapacity: 0
-          AvailCapacity: 787460558849
-          TotalCapacity: 3169589592064
-                UsedPct: 75.155756416520319
-         MaxDiskUsedPct: 75.155756416551881
+          AvailCapacity: 5187141550081
+          TotalCapacity: 7750977622016
+                UsedPct: 33.077583202570978
+         MaxDiskUsedPct: 33.077583202583881
      RemoteUsedCapacity: 0
                     Tag: {"location" : "default"}
-                 ErrMsg:
-                Version: doris-0.0.0-trunk-8de51f96f3
-                 Status: {"lastSuccessReportTabletsTime":"2023-03-27 20:24:55","lastStreamLoadTime":-1,"isQueryDisabled":false,"isLoadDisabled":false}
+                 ErrMsg: 
+                Version: doris-0.0.0-trunk-4b18cde0c7
+                 Status: {"lastSuccessReportTabletsTime":"2023-06-15 17:09:02","lastStreamLoadTime":-1,"isQueryDisabled":false,"isLoadDisabled":false}
 HeartbeatFailureCounter: 0
                NodeRole: mix
-1 row in set (0.03 sec)
+1 row in set (0.038 sec)
 ```
 
 ### keywords
diff --git a/docs/en/docs/sql-manual/sql-functions/table-functions/frontends.md b/docs/en/docs/sql-manual/sql-functions/table-functions/frontends.md
new file mode 100644
index 0000000000..4c16ff9c90
--- /dev/null
+++ b/docs/en/docs/sql-manual/sql-functions/table-functions/frontends.md
@@ -0,0 +1,104 @@
+---
+{
+    "title": "frontends",
+    "language": "en"
+}
+---
+
+<!--
+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.
+-->
+
+## `frontends`
+
+### Name
+
+<version since="dev">
+
+frontends
+
+</version>
+
+### description
+
+Table-Value-Function, generate a temporary table named `frontends`. This tvf is used to view the information of BE nodes in the doris cluster.
+
+This function is used in `FROM` clauses.
+
+#### syntax
+
+`frontends()`
+
+The table schema of `frontends()` tvf:
+```
+mysql> desc function frontends();
++-------------------+------+------+-------+---------+-------+
+| Field             | Type | Null | Key   | Default | Extra |
++-------------------+------+------+-------+---------+-------+
+| Name              | TEXT | No   | false | NULL    | NONE  |
+| Host              | TEXT | No   | false | NULL    | NONE  |
+| EditLogPort       | TEXT | No   | false | NULL    | NONE  |
+| HttpPort          | TEXT | No   | false | NULL    | NONE  |
+| QueryPort         | TEXT | No   | false | NULL    | NONE  |
+| RpcPort           | TEXT | No   | false | NULL    | NONE  |
+| Role              | TEXT | No   | false | NULL    | NONE  |
+| IsMaster          | TEXT | No   | false | NULL    | NONE  |
+| ClusterId         | TEXT | No   | false | NULL    | NONE  |
+| Join              | TEXT | No   | false | NULL    | NONE  |
+| Alive             | TEXT | No   | false | NULL    | NONE  |
+| ReplayedJournalId | TEXT | No   | false | NULL    | NONE  |
+| LastHeartbeat     | TEXT | No   | false | NULL    | NONE  |
+| IsHelper          | TEXT | No   | false | NULL    | NONE  |
+| ErrMsg            | TEXT | No   | false | NULL    | NONE  |
+| Version           | TEXT | No   | false | NULL    | NONE  |
+| CurrentConnected  | TEXT | No   | false | NULL    | NONE  |
++-------------------+------+------+-------+---------+-------+
+17 rows in set (0.022 sec)
+```
+
+The information displayed by the `frontends` tvf is basically consistent with the information displayed by the `show frontends` statement. However, the types of each field in the `frontends` tvf are more specific, and you can use the `frontends` tvf to perform operations such as filtering and joining.
+
+The information displayed by the `frontends` tvf is authenticated, which is consistent with the behavior of `show frontends`, user must have ADMIN/OPERATOR privelege.
+
+### example
+```
+mysql> select * from frontends()\G
+*************************** 1. row ***************************
+             Name: fe_5fa8bf19_fd6b_45cb_89c5_25a5ebc45582
+               IP: 10.xx.xx.14
+      EditLogPort: 9013
+         HttpPort: 8034
+        QueryPort: 9033
+          RpcPort: 9023
+             Role: FOLLOWER
+         IsMaster: true
+        ClusterId: 1258341841
+             Join: true
+            Alive: true
+ReplayedJournalId: 186
+    LastHeartbeat: 2023-06-15 16:53:12
+         IsHelper: true
+           ErrMsg: 
+          Version: doris-0.0.0-trunk-4b18cde0c7
+ CurrentConnected: Yes
+1 row in set (0.060 sec)
+```
+
+### keywords
+
+    frontends
\ No newline at end of file
diff --git a/docs/sidebars.json b/docs/sidebars.json
index 6b75e36d3a..d613fcaff5 100644
--- a/docs/sidebars.json
+++ b/docs/sidebars.json
@@ -700,6 +700,7 @@
                                 "sql-manual/sql-functions/table-functions/hdfs",
                                 "sql-manual/sql-functions/table-functions/iceberg_meta",
                                 "sql-manual/sql-functions/table-functions/backends",
+                                "sql-manual/sql-functions/table-functions/frontends",
                                 "sql-manual/sql-functions/table-functions/workload-group"
                             ]
                         },
diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/table-functions/backends.md b/docs/zh-CN/docs/sql-manual/sql-functions/table-functions/backends.md
index 14e792dc3d..741a986bfc 100644
--- a/docs/zh-CN/docs/sql-manual/sql-functions/table-functions/backends.md
+++ b/docs/zh-CN/docs/sql-manual/sql-functions/table-functions/backends.md
@@ -46,36 +46,34 @@ backends
 backends()表结构:
 ```
 mysql> desc function backends();
-+-------------------------+--------+------+-------+---------+-------+
-| Field                   | Type   | Null | Key   | Default | Extra |
-+-------------------------+--------+------+-------+---------+-------+
-| BackendId               | BIGINT | No   | false | NULL    | NONE  |
-| Cluster                 | TEXT   | No   | false | NULL    | NONE  |
-| Host                    | TEXT   | No   | false | NULL    | NONE  |
-| HeartbeatPort           | INT    | No   | false | NULL    | NONE  |
-| BePort                  | INT    | No   | false | NULL    | NONE  |
-| HttpPort                | INT    | No   | false | NULL    | NONE  |
-| BrpcPort                | INT    | No   | false | NULL    | NONE  |
-| LastStartTime           | TEXT   | No   | false | NULL    | NONE  |
-| LastHeartbeat           | TEXT   | No   | false | NULL    | NONE  |
-| Alive                   | TEXT   | No   | false | NULL    | NONE  |
-| SystemDecommissioned    | TEXT   | No   | false | NULL    | NONE  |
-| ClusterDecommissioned   | TEXT   | No   | false | NULL    | NONE  |
-| TabletNum               | BIGINT | No   | false | NULL    | NONE  |
-| DataUsedCapacity        | BIGINT | No   | false | NULL    | NONE  |
-| AvailCapacity           | BIGINT | No   | false | NULL    | NONE  |
-| TotalCapacity           | BIGINT | No   | false | NULL    | NONE  |
-| UsedPct                 | DOUBLE | No   | false | NULL    | NONE  |
-| MaxDiskUsedPct          | DOUBLE | No   | false | NULL    | NONE  |
-| RemoteUsedCapacity      | BIGINT | No   | false | NULL    | NONE  |
-| Tag                     | TEXT   | No   | false | NULL    | NONE  |
-| ErrMsg                  | TEXT   | No   | false | NULL    | NONE  |
-| Version                 | TEXT   | No   | false | NULL    | NONE  |
-| Status                  | TEXT   | No   | false | NULL    | NONE  |
-| HeartbeatFailureCounter | INT    | No   | false | NULL    | NONE  |
-| NodeRole                | TEXT   | No   | false | NULL    | NONE  |
-+-------------------------+--------+------+-------+---------+-------+
-25 rows in set (0.04 sec)
++-------------------------+---------+------+-------+---------+-------+
+| Field                   | Type    | Null | Key   | Default | Extra |
++-------------------------+---------+------+-------+---------+-------+
+| BackendId               | BIGINT  | No   | false | NULL    | NONE  |
+| Host                    | TEXT    | No   | false | NULL    | NONE  |
+| HeartbeatPort           | INT     | No   | false | NULL    | NONE  |
+| BePort                  | INT     | No   | false | NULL    | NONE  |
+| HttpPort                | INT     | No   | false | NULL    | NONE  |
+| BrpcPort                | INT     | No   | false | NULL    | NONE  |
+| LastStartTime           | TEXT    | No   | false | NULL    | NONE  |
+| LastHeartbeat           | TEXT    | No   | false | NULL    | NONE  |
+| Alive                   | BOOLEAN | No   | false | NULL    | NONE  |
+| SystemDecommissioned    | BOOLEAN | No   | false | NULL    | NONE  |
+| TabletNum               | BIGINT  | No   | false | NULL    | NONE  |
+| DataUsedCapacity        | BIGINT  | No   | false | NULL    | NONE  |
+| AvailCapacity           | BIGINT  | No   | false | NULL    | NONE  |
+| TotalCapacity           | BIGINT  | No   | false | NULL    | NONE  |
+| UsedPct                 | DOUBLE  | No   | false | NULL    | NONE  |
+| MaxDiskUsedPct          | DOUBLE  | No   | false | NULL    | NONE  |
+| RemoteUsedCapacity      | BIGINT  | No   | false | NULL    | NONE  |
+| Tag                     | TEXT    | No   | false | NULL    | NONE  |
+| ErrMsg                  | TEXT    | No   | false | NULL    | NONE  |
+| Version                 | TEXT    | No   | false | NULL    | NONE  |
+| Status                  | TEXT    | No   | false | NULL    | NONE  |
+| HeartbeatFailureCounter | INT     | No   | false | NULL    | NONE  |
+| NodeRole                | TEXT    | No   | false | NULL    | NONE  |
++-------------------------+---------+------+-------+---------+-------+
+23 rows in set (0.002 sec)
 ```
 
 `backends()` tvf展示出来的信息基本与 `show backends` 语句展示出的信息一致,但是 `backends()` tvf的各个字段类型更加明确,且可以利用tvf生成的表去做过滤、join等操作。
@@ -86,32 +84,30 @@ mysql> desc function backends();
 ```
 mysql> select * from backends()\G
 *************************** 1. row ***************************
-              BackendId: 10022
-                Cluster: default_cluster
-                   Host: 10.16.10.14
-          HeartbeatPort: 9159
-                 BePort: 9169
-               HttpPort: 8149
-               BrpcPort: 8169
-          LastStartTime: 2023-03-24 14:37:00
-          LastHeartbeat: 2023-03-27 20:25:35
-                  Alive: true
-   SystemDecommissioned: false
-  ClusterDecommissioned: false
+              BackendId: 10002
+                   Host: 10.xx.xx.90
+          HeartbeatPort: 9053
+                 BePort: 9063
+               HttpPort: 8043
+               BrpcPort: 8069
+          LastStartTime: 2023-06-15 16:51:02
+          LastHeartbeat: 2023-06-15 17:09:58
+                  Alive: 1
+   SystemDecommissioned: 0
               TabletNum: 21
        DataUsedCapacity: 0
-          AvailCapacity: 787460558849
-          TotalCapacity: 3169589592064
-                UsedPct: 75.155756416520319
-         MaxDiskUsedPct: 75.155756416551881
+          AvailCapacity: 5187141550081
+          TotalCapacity: 7750977622016
+                UsedPct: 33.077583202570978
+         MaxDiskUsedPct: 33.077583202583881
      RemoteUsedCapacity: 0
                     Tag: {"location" : "default"}
-                 ErrMsg:
-                Version: doris-0.0.0-trunk-8de51f96f3
-                 Status: {"lastSuccessReportTabletsTime":"2023-03-27 20:24:55","lastStreamLoadTime":-1,"isQueryDisabled":false,"isLoadDisabled":false}
+                 ErrMsg: 
+                Version: doris-0.0.0-trunk-4b18cde0c7
+                 Status: {"lastSuccessReportTabletsTime":"2023-06-15 17:09:02","lastStreamLoadTime":-1,"isQueryDisabled":false,"isLoadDisabled":false}
 HeartbeatFailureCounter: 0
                NodeRole: mix
-1 row in set (0.03 sec)
+1 row in set (0.038 sec)
 ```
 
 ### keywords
diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/table-functions/frontends.md b/docs/zh-CN/docs/sql-manual/sql-functions/table-functions/frontends.md
new file mode 100644
index 0000000000..893e013e54
--- /dev/null
+++ b/docs/zh-CN/docs/sql-manual/sql-functions/table-functions/frontends.md
@@ -0,0 +1,103 @@
+---
+{
+    "title": "frontends",
+    "language": "zh-CN"
+}
+---
+
+<!--
+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.
+-->
+
+## `frontends`
+
+### Name
+
+<version since="dev">
+
+frontends
+
+</version>
+
+### description
+
+表函数,生成frontends临时表,可以查看当前doris集群中的 FE 节点信息。
+
+该函数用于from子句中。
+
+#### syntax
+`frontends()`
+
+frontends()表结构:
+```
+mysql> desc function frontends();
++-------------------+------+------+-------+---------+-------+
+| Field             | Type | Null | Key   | Default | Extra |
++-------------------+------+------+-------+---------+-------+
+| Name              | TEXT | No   | false | NULL    | NONE  |
+| Host              | TEXT | No   | false | NULL    | NONE  |
+| EditLogPort       | TEXT | No   | false | NULL    | NONE  |
+| HttpPort          | TEXT | No   | false | NULL    | NONE  |
+| QueryPort         | TEXT | No   | false | NULL    | NONE  |
+| RpcPort           | TEXT | No   | false | NULL    | NONE  |
+| Role              | TEXT | No   | false | NULL    | NONE  |
+| IsMaster          | TEXT | No   | false | NULL    | NONE  |
+| ClusterId         | TEXT | No   | false | NULL    | NONE  |
+| Join              | TEXT | No   | false | NULL    | NONE  |
+| Alive             | TEXT | No   | false | NULL    | NONE  |
+| ReplayedJournalId | TEXT | No   | false | NULL    | NONE  |
+| LastHeartbeat     | TEXT | No   | false | NULL    | NONE  |
+| IsHelper          | TEXT | No   | false | NULL    | NONE  |
+| ErrMsg            | TEXT | No   | false | NULL    | NONE  |
+| Version           | TEXT | No   | false | NULL    | NONE  |
+| CurrentConnected  | TEXT | No   | false | NULL    | NONE  |
++-------------------+------+------+-------+---------+-------+
+17 rows in set (0.022 sec)
+```
+
+`frontends()` tvf展示出来的信息基本与 `show frontends` 语句展示出的信息一致,但是 `frontends()` tvf的各个字段类型更加明确,且可以利用tvf生成的表去做过滤、join等操作。
+
+对 `frontends()` tvf信息展示进行了鉴权,与 `show frontends` 行为保持一致,要求用户具有 ADMIN/OPERATOR 权限。
+
+### example
+```
+mysql> select * from frontends()\G
+*************************** 1. row ***************************
+             Name: fe_5fa8bf19_fd6b_45cb_89c5_25a5ebc45582
+               IP: 10.xx.xx.14
+      EditLogPort: 9013
+         HttpPort: 8034
+        QueryPort: 9033
+          RpcPort: 9023
+             Role: FOLLOWER
+         IsMaster: true
+        ClusterId: 1258341841
+             Join: true
+            Alive: true
+ReplayedJournalId: 186
+    LastHeartbeat: 2023-06-15 16:53:12
+         IsHelper: true
+           ErrMsg: 
+          Version: doris-0.0.0-trunk-4b18cde0c7
+ CurrentConnected: Yes
+1 row in set (0.060 sec)
+```
+
+### keywords
+
+    frontends
\ No newline at end of file
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
new file mode 100644
index 0000000000..122ecc9e48
--- /dev/null
+++ b/fe/fe-core/src/main/java/org/apache/doris/tablefunction/FrontendsTableValuedFunction.java
@@ -0,0 +1,104 @@
+// 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.Column;
+import org.apache.doris.catalog.ScalarType;
+import org.apache.doris.nereids.exceptions.AnalysisException;
+import org.apache.doris.thrift.TFrontendsMetadataParams;
+import org.apache.doris.thrift.TMetaScanRange;
+import org.apache.doris.thrift.TMetadataType;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The Implement of table valued function
+ * backends().
+ */
+public class FrontendsTableValuedFunction extends MetadataTableValuedFunction {
+    public static final String NAME = "frontends";
+
+    private static final ImmutableList<Column> SCHEMA = ImmutableList.of(
+            new Column("Name", ScalarType.createStringType()),
+            new Column("HOST", ScalarType.createStringType()),
+            new Column("EditLogPort", ScalarType.createStringType()),
+            new Column("HttpPort", ScalarType.createStringType()),
+            new Column("QueryPort", ScalarType.createStringType()),
+            new Column("RpcPort", ScalarType.createStringType()),
+            new Column("Role", ScalarType.createStringType()),
+            new Column("IsMaster", ScalarType.createStringType()),
+            new Column("ClusterId", ScalarType.createStringType()),
+            new Column("Join", ScalarType.createStringType()),
+            new Column("Alive", ScalarType.createStringType()),
+            new Column("ReplayedJournalId", ScalarType.createStringType()),
+            new Column("LastHeartbeat", ScalarType.createStringType()),
+            new Column("IsHelper", ScalarType.createStringType()),
+            new Column("ErrMsg", ScalarType.createStringType()),
+            new Column("Version", ScalarType.createStringType()),
+            new Column("CurrentConnected", ScalarType.createStringType()));
+
+    private static final ImmutableMap<String, Integer> COLUMN_TO_INDEX;
+
+    static {
+        ImmutableMap.Builder<String, Integer> builder = new ImmutableMap.Builder();
+        for (int i = 0; i < SCHEMA.size(); i++) {
+            builder.put(SCHEMA.get(i).getName().toLowerCase(), i);
+        }
+        COLUMN_TO_INDEX = builder.build();
+    }
+
+    public static Integer getColumnIndexFromColumnName(String columnName) {
+        return COLUMN_TO_INDEX.get(columnName.toLowerCase());
+    }
+
+    public FrontendsTableValuedFunction(Map<String, String> params) throws AnalysisException {
+        if (params.size() != 0) {
+            throw new AnalysisException("frontends table-valued-function does not support any params");
+        }
+    }
+
+    @Override
+    public TMetadataType getMetadataType() {
+        return TMetadataType.FRONTENDS;
+    }
+
+    @Override
+    public TMetaScanRange getMetaScanRange() {
+        TMetaScanRange metaScanRange = new TMetaScanRange();
+        metaScanRange.setMetadataType(TMetadataType.FRONTENDS);
+        TFrontendsMetadataParams frontendsMetadataParams = new TFrontendsMetadataParams();
+        frontendsMetadataParams.setClusterName("");
+        metaScanRange.setFrontendsParams(frontendsMetadataParams);
+        return metaScanRange;
+    }
+
+    @Override
+    public String getTableName() {
+        return "FrontendsTableValuedFunction";
+    }
+
+    @Override
+    public List<Column> getTableColumns() throws AnalysisException {
+        return SCHEMA;
+    }
+}
+
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 e43e619542..d2a0a2a5ee 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
@@ -20,6 +20,7 @@ package org.apache.doris.tablefunction;
 import org.apache.doris.catalog.Env;
 import org.apache.doris.common.AnalysisException;
 import org.apache.doris.common.MetaNotFoundException;
+import org.apache.doris.common.proc.FrontendsProcNode;
 import org.apache.doris.common.util.TimeUtils;
 import org.apache.doris.datasource.HMSExternalCatalog;
 import org.apache.doris.datasource.property.constants.HMSProperties;
@@ -73,6 +74,9 @@ public class MetadataGenerator {
             case BACKENDS:
                 result = backendsMetadataResult(params);
                 break;
+            case FRONTENDS:
+                result = frontendsMetadataResult(params);
+                break;
             case WORKLOAD_GROUPS:
                 result = workloadGroupsMetadataResult(params);
                 break;
@@ -229,6 +233,29 @@ public class MetadataGenerator {
         return result;
     }
 
+    private static TFetchSchemaTableDataResult frontendsMetadataResult(TMetadataTableRequestParams params) {
+        if (!params.isSetFrontendsMetadataParams()) {
+            return errorResult("frontends metadata param is not set.");
+        }
+
+        TFetchSchemaTableDataResult result = new TFetchSchemaTableDataResult();
+
+        List<TRow> dataBatch = Lists.newArrayList();
+        List<List<String>> infos = Lists.newArrayList();
+        FrontendsProcNode.getFrontendsInfo(Env.getCurrentEnv(), infos);
+        for (List<String> info : infos) {
+            TRow trow = new TRow();
+            for (String item : info) {
+                trow.addToColumnValue(new TCell().setStringVal(item));
+            }
+            dataBatch.add(trow);
+        }
+
+        result.setDataBatch(dataBatch);
+        result.setStatus(new TStatus(TStatusCode.OK));
+        return result;
+    }
+
     private static TFetchSchemaTableDataResult workloadGroupsMetadataResult(TMetadataTableRequestParams params) {
         List<List<String>> workloadGroupsInfo = Env.getCurrentEnv().getWorkloadGroupMgr()
                 .getResourcesInfo();
diff --git a/fe/fe-core/src/main/java/org/apache/doris/tablefunction/MetadataTableValuedFunction.java b/fe/fe-core/src/main/java/org/apache/doris/tablefunction/MetadataTableValuedFunction.java
index dc5f68a6db..ff01524e76 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/tablefunction/MetadataTableValuedFunction.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/tablefunction/MetadataTableValuedFunction.java
@@ -31,6 +31,8 @@ public abstract class MetadataTableValuedFunction extends TableValuedFunctionIf
         switch (type) {
             case BACKENDS:
                 return BackendsTableValuedFunction.getColumnIndexFromColumnName(columnName);
+            case FRONTENDS:
+                return FrontendsTableValuedFunction.getColumnIndexFromColumnName(columnName);
             case ICEBERG:
                 return IcebergTableValuedFunction.getColumnIndexFromColumnName(columnName);
             case WORKLOAD_GROUPS:
diff --git a/fe/fe-core/src/main/java/org/apache/doris/tablefunction/TableValuedFunctionIf.java b/fe/fe-core/src/main/java/org/apache/doris/tablefunction/TableValuedFunctionIf.java
index 5a44e7cd5d..0cc0a61067 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/tablefunction/TableValuedFunctionIf.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/tablefunction/TableValuedFunctionIf.java
@@ -53,6 +53,8 @@ public abstract class TableValuedFunctionIf {
                 return new IcebergTableValuedFunction(params);
             case BackendsTableValuedFunction.NAME:
                 return new BackendsTableValuedFunction(params);
+            case FrontendsTableValuedFunction.NAME:
+                return new FrontendsTableValuedFunction(params);
             case WorkloadGroupsTableValuedFunction.NAME:
                 return new WorkloadGroupsTableValuedFunction(params);
             default:
diff --git a/gensrc/thrift/FrontendService.thrift b/gensrc/thrift/FrontendService.thrift
index 28b77a3f20..fca5481f3b 100644
--- a/gensrc/thrift/FrontendService.thrift
+++ b/gensrc/thrift/FrontendService.thrift
@@ -805,6 +805,7 @@ struct TMetadataTableRequestParams {
   2: optional PlanNodes.TIcebergMetadataParams iceberg_metadata_params
   3: optional PlanNodes.TBackendsMetadataParams backends_metadata_params
   4: optional list<string> columns_name
+  5: optional PlanNodes.TFrontendsMetadataParams frontends_metadata_params
 }
 
 struct TFetchSchemaTableDataRequest {
diff --git a/gensrc/thrift/PlanNodes.thrift b/gensrc/thrift/PlanNodes.thrift
index 4844d2ed7f..6f5963f4fe 100644
--- a/gensrc/thrift/PlanNodes.thrift
+++ b/gensrc/thrift/PlanNodes.thrift
@@ -435,10 +435,15 @@ struct TBackendsMetadataParams {
   1: optional string cluster_name
 }
 
+struct TFrontendsMetadataParams {
+  1: optional string cluster_name
+}
+
 struct TMetaScanRange {
   1: optional Types.TMetadataType metadata_type
   2: optional TIcebergMetadataParams iceberg_params
   3: optional TBackendsMetadataParams backends_params
+  4: optional TFrontendsMetadataParams frontends_params
 }
 
 // Specification of an individual data range which is held in its entirety
diff --git a/gensrc/thrift/Types.thrift b/gensrc/thrift/Types.thrift
index 4949ca55f2..9dec29db22 100644
--- a/gensrc/thrift/Types.thrift
+++ b/gensrc/thrift/Types.thrift
@@ -688,7 +688,8 @@ enum TSortType {
 enum TMetadataType {
   ICEBERG,
   BACKENDS,
-  WORKLOAD_GROUPS
+  WORKLOAD_GROUPS,
+  FRONTENDS
 }
 
 enum TIcebergQueryType {
diff --git a/regression-test/suites/correctness_p0/table_valued_function/test_frontends_tvf.groovy b/regression-test/suites/correctness_p0/table_valued_function/test_frontends_tvf.groovy
new file mode 100644
index 0000000000..cc7d84d982
--- /dev/null
+++ b/regression-test/suites/correctness_p0/table_valued_function/test_frontends_tvf.groovy
@@ -0,0 +1,28 @@
+// 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.
+
+// This suit test the `frontends` tvf
+suite("test_frontends_tvf") {
+    List<List<Object>> table =  sql """ select * from `frontends`(); """
+    assertTrue(table.size() > 0)
+    assertTrue(table[0].size == 17)
+
+    // filter columns
+    table = sql """ select Name from `frontends`();"""
+    assertTrue(table.size() > 0)
+    assertTrue(table[0].size == 1)
+}


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