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

tanxinyu pushed a commit to branch show_cluster_version
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 384517502743cca22fc80dad89bba4b3e1cb61b8
Author: OneSizeFitQuorum <[email protected]>
AuthorDate: Mon Jul 31 16:56:44 2023 +0800

    finish
    
    Signed-off-by: OneSizeFitQuorum <[email protected]>
---
 .../consensus/request/ConfigPhysicalPlan.java      |  6 +-
 .../consensus/request/ConfigPhysicalPlanType.java  |  2 +-
 ...ildInfoPlan.java => UpdateVersionInfoPlan.java} | 32 +++++----
 .../iotdb/confignode/manager/ConfigManager.java    |  5 +-
 .../iotdb/confignode/manager/ProcedureManager.java |  2 +-
 .../iotdb/confignode/manager/node/NodeManager.java | 48 +++++++------
 .../persistence/executor/ConfigPlanExecutor.java   |  6 +-
 .../confignode/persistence/node/NodeInfo.java      | 84 +++++++++++-----------
 .../procedure/env/ConfigNodeProcedureEnv.java      |  8 ++-
 .../impl/node/AddConfigNodeProcedure.java          | 23 +++---
 .../iotdb/confignode/service/ConfigNode.java       | 10 ++-
 .../impl/node/AddConfigNodeProcedureTest.java      |  3 +-
 .../common/header/ColumnHeaderConstant.java        |  5 +-
 .../config/metadata/ShowClusterDetailsTask.java    | 25 ++++---
 .../execution/config/metadata/ShowClusterTask.java | 10 +--
 .../java/org/apache/iotdb/db/service/DataNode.java |  5 +-
 .../src/main/thrift/confignode.thrift              | 13 ++--
 17 files changed, 164 insertions(+), 123 deletions(-)

diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlan.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlan.java
index ffd7fc4c5f9..b097bdb7499 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlan.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlan.java
@@ -53,7 +53,7 @@ import 
org.apache.iotdb.confignode.consensus.request.read.trigger.GetTriggerLoca
 import 
org.apache.iotdb.confignode.consensus.request.read.trigger.GetTriggerTablePlan;
 import 
org.apache.iotdb.confignode.consensus.request.write.confignode.ApplyConfigNodePlan;
 import 
org.apache.iotdb.confignode.consensus.request.write.confignode.RemoveConfigNodePlan;
-import 
org.apache.iotdb.confignode.consensus.request.write.confignode.UpdateBuildInfoPlan;
+import 
org.apache.iotdb.confignode.consensus.request.write.confignode.UpdateVersionInfoPlan;
 import org.apache.iotdb.confignode.consensus.request.write.cq.ActiveCQPlan;
 import org.apache.iotdb.confignode.consensus.request.write.cq.AddCQPlan;
 import org.apache.iotdb.confignode.consensus.request.write.cq.DropCQPlan;
@@ -281,8 +281,8 @@ public abstract class ConfigPhysicalPlan implements 
IConsensusRequest {
         case RemoveConfigNode:
           plan = new RemoveConfigNodePlan();
           break;
-        case UpdateBuildInfo:
-          plan = new UpdateBuildInfoPlan();
+        case UpdateVersionInfo:
+          plan = new UpdateVersionInfoPlan();
           break;
         case CreateFunction:
           plan = new CreateFunctionPlan();
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanType.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanType.java
index 8644823b62b..3392b283646 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanType.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanType.java
@@ -27,7 +27,7 @@ public enum ConfigPhysicalPlanType {
   /** ConfigNode. */
   ApplyConfigNode((short) 0),
   RemoveConfigNode((short) 1),
-  UpdateBuildInfo((short) 2),
+  UpdateVersionInfo((short) 2),
 
   /** DataNode. */
   RegisterDataNode((short) 100),
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/write/confignode/UpdateBuildInfoPlan.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/write/confignode/UpdateVersionInfoPlan.java
similarity index 66%
rename from 
iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/write/confignode/UpdateBuildInfoPlan.java
rename to 
iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/write/confignode/UpdateVersionInfoPlan.java
index 8fdee39a5cf..3a562f19538 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/write/confignode/UpdateBuildInfoPlan.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/write/confignode/UpdateVersionInfoPlan.java
@@ -21,6 +21,7 @@ package 
org.apache.iotdb.confignode.consensus.request.write.confignode;
 
 import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlan;
 import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanType;
+import org.apache.iotdb.confignode.rpc.thrift.TNodeVersionInfo;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.io.DataOutputStream;
@@ -28,23 +29,23 @@ import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.Objects;
 
-public class UpdateBuildInfoPlan extends ConfigPhysicalPlan {
+public class UpdateVersionInfoPlan extends ConfigPhysicalPlan {
 
   private int nodeId;
-  private String buildInfo;
+  private TNodeVersionInfo versionInfo;
 
-  public UpdateBuildInfoPlan() {
-    super(ConfigPhysicalPlanType.UpdateBuildInfo);
+  public UpdateVersionInfoPlan() {
+    super(ConfigPhysicalPlanType.UpdateVersionInfo);
   }
 
-  public UpdateBuildInfoPlan(String buildInfo, int nodeId) {
+  public UpdateVersionInfoPlan(TNodeVersionInfo versionInfo, int nodeId) {
     this();
-    this.buildInfo = buildInfo;
+    this.versionInfo = versionInfo;
     this.nodeId = nodeId;
   }
 
-  public String getBuildInfo() {
-    return buildInfo;
+  public TNodeVersionInfo getVersionInfo() {
+    return versionInfo;
   }
 
   public int getNodeId() {
@@ -55,13 +56,16 @@ public class UpdateBuildInfoPlan extends ConfigPhysicalPlan 
{
   protected void serializeImpl(DataOutputStream stream) throws IOException {
     ReadWriteIOUtils.write(getType().getPlanType(), stream);
     ReadWriteIOUtils.write(nodeId, stream);
-    ReadWriteIOUtils.write(buildInfo, stream);
+    ReadWriteIOUtils.write(versionInfo.getVersion(), stream);
+    ReadWriteIOUtils.write(versionInfo.getBuildInfo(), stream);
   }
 
   @Override
   protected void deserializeImpl(ByteBuffer buffer) {
     nodeId = ReadWriteIOUtils.readInt(buffer);
-    buildInfo = ReadWriteIOUtils.readString(buffer);
+    versionInfo =
+        new TNodeVersionInfo(
+            ReadWriteIOUtils.readString(buffer), 
ReadWriteIOUtils.readString(buffer));
   }
 
   @Override
@@ -72,15 +76,15 @@ public class UpdateBuildInfoPlan extends ConfigPhysicalPlan 
{
     if (o == null || getClass() != o.getClass()) {
       return false;
     }
-    if (!getType().equals(((UpdateBuildInfoPlan) o).getType())) {
+    if (!getType().equals(((UpdateVersionInfoPlan) o).getType())) {
       return false;
     }
-    UpdateBuildInfoPlan that = (UpdateBuildInfoPlan) o;
-    return nodeId == that.nodeId && buildInfo.equals(that.buildInfo);
+    UpdateVersionInfoPlan that = (UpdateVersionInfoPlan) o;
+    return nodeId == that.nodeId && versionInfo.equals(that.versionInfo);
   }
 
   @Override
   public int hashCode() {
-    return Objects.hash(nodeId, buildInfo);
+    return Objects.hash(nodeId, versionInfo);
   }
 }
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
index 69645b5061a..f1f6cbdef2f 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
@@ -144,6 +144,7 @@ import 
org.apache.iotdb.confignode.rpc.thrift.TGetTimeSlotListResp;
 import org.apache.iotdb.confignode.rpc.thrift.TGetTriggerTableResp;
 import org.apache.iotdb.confignode.rpc.thrift.TGetUDFTableResp;
 import org.apache.iotdb.confignode.rpc.thrift.TMigrateRegionReq;
+import org.apache.iotdb.confignode.rpc.thrift.TNodeVersionInfo;
 import org.apache.iotdb.confignode.rpc.thrift.TPermissionInfoResp;
 import org.apache.iotdb.confignode.rpc.thrift.TRegionMigrateResultReportReq;
 import org.apache.iotdb.confignode.rpc.thrift.TRegionRouteMapResp;
@@ -444,9 +445,9 @@ public class ConfigManager implements IManager {
               
.sorted(Comparator.comparingInt(TDataNodeLocation::getDataNodeId))
               .collect(Collectors.toList());
       Map<Integer, String> nodeStatus = 
getLoadManager().getNodeStatusWithReason();
-      Map<Integer, String> nodeBuildInfo = getNodeManager().getNodeBuildInfo();
+      Map<Integer, TNodeVersionInfo> nodeVersionInfo = 
getNodeManager().getNodeVersionInfo();
       return new TShowClusterResp(
-          status, configNodeLocations, dataNodeInfoLocations, nodeStatus, 
nodeBuildInfo);
+          status, configNodeLocations, dataNodeInfoLocations, nodeStatus, 
nodeVersionInfo);
     } else {
       return new TShowClusterResp(
           status, new ArrayList<>(), new ArrayList<>(), new HashMap<>(), new 
HashMap<>());
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java
index 21f81248d7e..c4b504abdb2 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java
@@ -467,7 +467,7 @@ public class ProcedureManager {
    */
   public void addConfigNode(TConfigNodeRegisterReq req) {
     AddConfigNodeProcedure addConfigNodeProcedure =
-        new AddConfigNodeProcedure(req.getConfigNodeLocation(), 
req.getBuildInfo());
+        new AddConfigNodeProcedure(req.getConfigNodeLocation(), 
req.getVersionInfo());
     this.executor.submitProcedure(addConfigNodeProcedure);
   }
 
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/node/NodeManager.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/node/NodeManager.java
index c34a5d54cdb..55d3ab05345 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/node/NodeManager.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/node/NodeManager.java
@@ -40,7 +40,7 @@ import org.apache.iotdb.confignode.conf.ConfigNodeDescriptor;
 import 
org.apache.iotdb.confignode.consensus.request.read.datanode.GetDataNodeConfigurationPlan;
 import 
org.apache.iotdb.confignode.consensus.request.write.confignode.ApplyConfigNodePlan;
 import 
org.apache.iotdb.confignode.consensus.request.write.confignode.RemoveConfigNodePlan;
-import 
org.apache.iotdb.confignode.consensus.request.write.confignode.UpdateBuildInfoPlan;
+import 
org.apache.iotdb.confignode.consensus.request.write.confignode.UpdateVersionInfoPlan;
 import 
org.apache.iotdb.confignode.consensus.request.write.datanode.RegisterDataNodePlan;
 import 
org.apache.iotdb.confignode.consensus.request.write.datanode.RemoveDataNodePlan;
 import 
org.apache.iotdb.confignode.consensus.request.write.datanode.UpdateDataNodePlan;
@@ -70,6 +70,7 @@ import 
org.apache.iotdb.confignode.rpc.thrift.TDataNodeRegisterReq;
 import org.apache.iotdb.confignode.rpc.thrift.TDataNodeRestartReq;
 import org.apache.iotdb.confignode.rpc.thrift.TDataNodeRestartResp;
 import org.apache.iotdb.confignode.rpc.thrift.TGlobalConfig;
+import org.apache.iotdb.confignode.rpc.thrift.TNodeVersionInfo;
 import org.apache.iotdb.confignode.rpc.thrift.TRatisConfig;
 import org.apache.iotdb.confignode.rpc.thrift.TRuntimeConfiguration;
 import org.apache.iotdb.confignode.rpc.thrift.TSetDataNodeStatusReq;
@@ -251,10 +252,10 @@ public class NodeManager {
     
registerDataNodePlan.getDataNodeConfiguration().getLocation().setDataNodeId(dataNodeId);
     getConsensusManager().write(registerDataNodePlan);
 
-    // update datanode's buildInfo
-    UpdateBuildInfoPlan updateBuildInfoPlan =
-        new UpdateBuildInfoPlan(req.getBuildInfo(), dataNodeId);
-    getConsensusManager().write(updateBuildInfoPlan);
+    // update datanode's versionInfo
+    UpdateVersionInfoPlan updateVersionInfoPlan =
+        new UpdateVersionInfoPlan(req.getVersionInfo(), dataNodeId);
+    getConsensusManager().write(updateVersionInfoPlan);
 
     // Bind DataNode metrics
     PartitionMetrics.bindDataNodePartitionMetrics(
@@ -282,11 +283,12 @@ public class NodeManager {
           new UpdateDataNodePlan(req.getDataNodeConfiguration());
       getConsensusManager().write(updateDataNodePlan);
     }
-    String recordBuildInfo = nodeInfo.getBuildInfo(nodeId);
-    if (!req.getBuildInfo().equals(recordBuildInfo)) {
-      // Update buildInfo when modified during restart
-      UpdateBuildInfoPlan updateBuildInfoPlan = new 
UpdateBuildInfoPlan(req.getBuildInfo(), nodeId);
-      getConsensusManager().write(updateBuildInfoPlan);
+    TNodeVersionInfo versionInfo = nodeInfo.getVersionInfo(nodeId);
+    if (!req.getVersionInfo().equals(versionInfo)) {
+      // Update versionInfo when modified during restart
+      UpdateVersionInfoPlan updateVersionInfoPlan =
+          new UpdateVersionInfoPlan(req.getVersionInfo(), nodeId);
+      getConsensusManager().write(updateVersionInfoPlan);
     }
 
     TDataNodeRestartResp resp = new TDataNodeRestartResp();
@@ -355,11 +357,12 @@ public class NodeManager {
         .setConfigNodeId(nodeId);
   }
 
-  public TSStatus updateConfigNodeIfNecessary(int configNodeId, String 
buildInfo) {
-    String recordBuildInfo = nodeInfo.getBuildInfo(configNodeId);
-    if (!recordBuildInfo.equals(buildInfo)) {
-      // Update buildInfo when modified during restart
-      UpdateBuildInfoPlan updateConfigNodePlan = new 
UpdateBuildInfoPlan(buildInfo, configNodeId);
+  public TSStatus updateConfigNodeIfNecessary(int configNodeId, 
TNodeVersionInfo versionInfo) {
+    TNodeVersionInfo recordVersionInfo = nodeInfo.getVersionInfo(configNodeId);
+    if (!recordVersionInfo.equals(versionInfo)) {
+      // Update versionInfo when modified during restart
+      UpdateVersionInfoPlan updateConfigNodePlan =
+          new UpdateVersionInfoPlan(versionInfo, configNodeId);
       ConsensusWriteResponse result = 
getConsensusManager().write(updateConfigNodePlan);
       return result.getStatus();
     }
@@ -484,8 +487,8 @@ public class NodeManager {
     return nodeInfo.getRegisteredConfigNodes();
   }
 
-  public Map<Integer, String> getNodeBuildInfo() {
-    return nodeInfo.getNodeBuildInfo();
+  public Map<Integer, TNodeVersionInfo> getNodeVersionInfo() {
+    return nodeInfo.getNodeVersionInfo();
   }
 
   public List<TConfigNodeInfo> getRegisteredConfigNodeInfoList() {
@@ -515,14 +518,15 @@ public class NodeManager {
    * Only leader use this interface, record the new ConfigNode's information.
    *
    * @param configNodeLocation The new ConfigNode.
-   * @param buildInfo The new ConfigNode's buildInfo.
+   * @param versionInfo The new ConfigNode's versionInfo.
    */
-  public void applyConfigNode(TConfigNodeLocation configNodeLocation, String 
buildInfo) {
+  public void applyConfigNode(
+      TConfigNodeLocation configNodeLocation, TNodeVersionInfo versionInfo) {
     ApplyConfigNodePlan applyConfigNodePlan = new 
ApplyConfigNodePlan(configNodeLocation);
     getConsensusManager().write(applyConfigNodePlan);
-    UpdateBuildInfoPlan updateBuildInfoPlan =
-        new UpdateBuildInfoPlan(buildInfo, 
configNodeLocation.getConfigNodeId());
-    getConsensusManager().write(updateBuildInfoPlan);
+    UpdateVersionInfoPlan updateVersionInfoPlan =
+        new UpdateVersionInfoPlan(versionInfo, 
configNodeLocation.getConfigNodeId());
+    getConsensusManager().write(updateVersionInfoPlan);
   }
 
   /**
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/executor/ConfigPlanExecutor.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/executor/ConfigPlanExecutor.java
index 205eece1ca9..2aff2dc81f0 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/executor/ConfigPlanExecutor.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/executor/ConfigPlanExecutor.java
@@ -51,7 +51,7 @@ import 
org.apache.iotdb.confignode.consensus.request.read.trigger.GetTriggerLoca
 import 
org.apache.iotdb.confignode.consensus.request.read.trigger.GetTriggerTablePlan;
 import 
org.apache.iotdb.confignode.consensus.request.write.confignode.ApplyConfigNodePlan;
 import 
org.apache.iotdb.confignode.consensus.request.write.confignode.RemoveConfigNodePlan;
-import 
org.apache.iotdb.confignode.consensus.request.write.confignode.UpdateBuildInfoPlan;
+import 
org.apache.iotdb.confignode.consensus.request.write.confignode.UpdateVersionInfoPlan;
 import org.apache.iotdb.confignode.consensus.request.write.cq.ActiveCQPlan;
 import org.apache.iotdb.confignode.consensus.request.write.cq.AddCQPlan;
 import org.apache.iotdb.confignode.consensus.request.write.cq.DropCQPlan;
@@ -364,8 +364,8 @@ public class ConfigPlanExecutor {
         return nodeInfo.applyConfigNode((ApplyConfigNodePlan) physicalPlan);
       case RemoveConfigNode:
         return nodeInfo.removeConfigNode((RemoveConfigNodePlan) physicalPlan);
-      case UpdateBuildInfo:
-        return nodeInfo.updateBuildInfo((UpdateBuildInfoPlan) physicalPlan);
+      case UpdateVersionInfo:
+        return nodeInfo.updateVersionInfo((UpdateVersionInfoPlan) 
physicalPlan);
       case CreateFunction:
         return udfInfo.addUDFInTable((CreateFunctionPlan) physicalPlan);
       case DropFunction:
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/node/NodeInfo.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/node/NodeInfo.java
index d5300f8296c..aa5e0ed29c3 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/node/NodeInfo.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/node/NodeInfo.java
@@ -28,11 +28,12 @@ import 
org.apache.iotdb.confignode.conf.SystemPropertiesUtils;
 import 
org.apache.iotdb.confignode.consensus.request.read.datanode.GetDataNodeConfigurationPlan;
 import 
org.apache.iotdb.confignode.consensus.request.write.confignode.ApplyConfigNodePlan;
 import 
org.apache.iotdb.confignode.consensus.request.write.confignode.RemoveConfigNodePlan;
-import 
org.apache.iotdb.confignode.consensus.request.write.confignode.UpdateBuildInfoPlan;
+import 
org.apache.iotdb.confignode.consensus.request.write.confignode.UpdateVersionInfoPlan;
 import 
org.apache.iotdb.confignode.consensus.request.write.datanode.RegisterDataNodePlan;
 import 
org.apache.iotdb.confignode.consensus.request.write.datanode.RemoveDataNodePlan;
 import 
org.apache.iotdb.confignode.consensus.request.write.datanode.UpdateDataNodePlan;
 import 
org.apache.iotdb.confignode.consensus.response.datanode.DataNodeConfigurationResp;
+import org.apache.iotdb.confignode.rpc.thrift.TNodeVersionInfo;
 import org.apache.iotdb.rpc.TSStatusCode;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
@@ -88,12 +89,12 @@ public class NodeInfo implements SnapshotProcessor {
   // Registered DataNodes
   private final ReentrantReadWriteLock dataNodeInfoReadWriteLock;
 
-  private final ReentrantReadWriteLock buildInfoReadWriteLock;
+  private final ReentrantReadWriteLock versionInfoReadWriteLock;
 
   private final AtomicInteger nextNodeId = new AtomicInteger(-1);
   private final Map<Integer, TDataNodeConfiguration> registeredDataNodes;
 
-  private final Map<Integer, String> nodeBuildInfo;
+  private final Map<Integer, TNodeVersionInfo> nodeVersionInfo;
   private static final String SNAPSHOT_FILENAME = "node_info.bin";
 
   public NodeInfo() {
@@ -103,8 +104,8 @@ public class NodeInfo implements SnapshotProcessor {
     this.dataNodeInfoReadWriteLock = new ReentrantReadWriteLock();
     this.registeredDataNodes = new ConcurrentHashMap<>();
 
-    this.nodeBuildInfo = new ConcurrentHashMap<>();
-    this.buildInfoReadWriteLock = new ReentrantReadWriteLock();
+    this.nodeVersionInfo = new ConcurrentHashMap<>();
+    this.versionInfoReadWriteLock = new ReentrantReadWriteLock();
   }
 
   /**
@@ -156,17 +157,17 @@ public class NodeInfo implements SnapshotProcessor {
         registeredDataNodes.size());
 
     dataNodeInfoReadWriteLock.writeLock().lock();
-    buildInfoReadWriteLock.writeLock().lock();
+    versionInfoReadWriteLock.writeLock().lock();
     try {
       req.getDataNodeLocations()
           .forEach(
               removeDataNodes -> {
                 registeredDataNodes.remove(removeDataNodes.getDataNodeId());
-                nodeBuildInfo.remove(removeDataNodes.getDataNodeId());
+                nodeVersionInfo.remove(removeDataNodes.getDataNodeId());
                 LOGGER.info("Removed the datanode {} from cluster", 
removeDataNodes);
               });
     } finally {
-      buildInfoReadWriteLock.writeLock().unlock();
+      versionInfoReadWriteLock.writeLock().unlock();
       dataNodeInfoReadWriteLock.writeLock().unlock();
     }
     LOGGER.info(
@@ -336,10 +337,10 @@ public class NodeInfo implements SnapshotProcessor {
   public TSStatus removeConfigNode(RemoveConfigNodePlan removeConfigNodePlan) {
     TSStatus status = new TSStatus();
     configNodeInfoReadWriteLock.writeLock().lock();
-    buildInfoReadWriteLock.writeLock().lock();
+    versionInfoReadWriteLock.writeLock().lock();
     try {
       
registeredConfigNodes.remove(removeConfigNodePlan.getConfigNodeLocation().getConfigNodeId());
-      
nodeBuildInfo.remove(removeConfigNodePlan.getConfigNodeLocation().getConfigNodeId());
+      
nodeVersionInfo.remove(removeConfigNodePlan.getConfigNodeLocation().getConfigNodeId());
       SystemPropertiesUtils.storeConfigNodeList(new 
ArrayList<>(registeredConfigNodes.values()));
       LOGGER.info(
           "Successfully remove ConfigNode: {}. Current ConfigNodeGroup: {}",
@@ -352,26 +353,27 @@ public class NodeInfo implements SnapshotProcessor {
       status.setMessage(
           "Remove ConfigNode failed because current ConfigNode can't store 
ConfigNode information.");
     } finally {
-      buildInfoReadWriteLock.writeLock().unlock();
+      versionInfoReadWriteLock.writeLock().unlock();
       configNodeInfoReadWriteLock.writeLock().unlock();
     }
     return status;
   }
 
   /**
-   * Update the specified Node‘s buildInfo.
+   * Update the specified Node‘s versionInfo.
    *
-   * @param updateBuildInfoPlan UpdateBuildInfoPlan
+   * @param updateVersionInfoPlan UpdateVersionInfoPlan
    * @return {@link TSStatusCode#SUCCESS_STATUS} if update build info 
successfully.
    */
-  public TSStatus updateBuildInfo(UpdateBuildInfoPlan updateBuildInfoPlan) {
-    buildInfoReadWriteLock.writeLock().lock();
+  public TSStatus updateVersionInfo(UpdateVersionInfoPlan 
updateVersionInfoPlan) {
+    versionInfoReadWriteLock.writeLock().lock();
     try {
-      nodeBuildInfo.put(updateBuildInfoPlan.getNodeId(), 
updateBuildInfoPlan.getBuildInfo());
+      nodeVersionInfo.put(
+          updateVersionInfoPlan.getNodeId(), 
updateVersionInfoPlan.getVersionInfo());
     } finally {
-      buildInfoReadWriteLock.writeLock().unlock();
+      versionInfoReadWriteLock.writeLock().unlock();
     }
-    LOGGER.info("Successfully update Node {} 's buildInfo.", 
updateBuildInfoPlan.getNodeId());
+    LOGGER.info("Successfully update Node {} 's version.", 
updateVersionInfoPlan.getNodeId());
     return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode());
   }
 
@@ -405,23 +407,23 @@ public class NodeInfo implements SnapshotProcessor {
   }
 
   /** @return all nodes buildInfo */
-  public Map<Integer, String> getNodeBuildInfo() {
-    Map<Integer, String> result = new HashMap<>();
-    buildInfoReadWriteLock.readLock().lock();
+  public Map<Integer, TNodeVersionInfo> getNodeVersionInfo() {
+    Map<Integer, TNodeVersionInfo> result = new 
HashMap<>(nodeVersionInfo.size());
+    versionInfoReadWriteLock.readLock().lock();
     try {
-      result.putAll(nodeBuildInfo);
+      result.putAll(nodeVersionInfo);
     } finally {
-      buildInfoReadWriteLock.readLock().unlock();
+      versionInfoReadWriteLock.readLock().unlock();
     }
     return result;
   }
 
-  public String getBuildInfo(int nodeId) {
-    buildInfoReadWriteLock.readLock().lock();
+  public TNodeVersionInfo getVersionInfo(int nodeId) {
+    versionInfoReadWriteLock.readLock().lock();
     try {
-      return nodeBuildInfo.getOrDefault(nodeId, "Unknown");
+      return nodeVersionInfo.getOrDefault(nodeId, new 
TNodeVersionInfo("Unknown", "Unknown"));
     } finally {
-      buildInfoReadWriteLock.readLock().unlock();
+      versionInfoReadWriteLock.readLock().unlock();
     }
   }
 
@@ -442,7 +444,7 @@ public class NodeInfo implements SnapshotProcessor {
     File tmpFile = new File(snapshotFile.getAbsolutePath() + "-" + 
UUID.randomUUID());
     configNodeInfoReadWriteLock.readLock().lock();
     dataNodeInfoReadWriteLock.readLock().lock();
-    buildInfoReadWriteLock.readLock().lock();
+    versionInfoReadWriteLock.readLock().lock();
     try (FileOutputStream fileOutputStream = new FileOutputStream(tmpFile);
         TIOStreamTransport tioStreamTransport = new 
TIOStreamTransport(fileOutputStream)) {
 
@@ -454,7 +456,7 @@ public class NodeInfo implements SnapshotProcessor {
 
       serializeRegisteredDataNode(fileOutputStream, protocol);
 
-      serializeBuildInfo(fileOutputStream);
+      serializeVersionInfo(fileOutputStream);
 
       fileOutputStream.flush();
 
@@ -463,7 +465,7 @@ public class NodeInfo implements SnapshotProcessor {
       return tmpFile.renameTo(snapshotFile);
 
     } finally {
-      buildInfoReadWriteLock.readLock().unlock();
+      versionInfoReadWriteLock.readLock().unlock();
       dataNodeInfoReadWriteLock.readLock().unlock();
       configNodeInfoReadWriteLock.readLock().unlock();
       for (int retry = 0; retry < 5; retry++) {
@@ -495,11 +497,12 @@ public class NodeInfo implements SnapshotProcessor {
     }
   }
 
-  private void serializeBuildInfo(OutputStream outputStream) throws 
IOException {
-    ReadWriteIOUtils.write(nodeBuildInfo.size(), outputStream);
-    for (Entry<Integer, String> entry : nodeBuildInfo.entrySet()) {
+  private void serializeVersionInfo(OutputStream outputStream) throws 
IOException {
+    ReadWriteIOUtils.write(nodeVersionInfo.size(), outputStream);
+    for (Entry<Integer, TNodeVersionInfo> entry : nodeVersionInfo.entrySet()) {
       ReadWriteIOUtils.write(entry.getKey(), outputStream);
-      ReadWriteIOUtils.write(entry.getValue(), outputStream);
+      ReadWriteIOUtils.write(entry.getValue().getVersion(), outputStream);
+      ReadWriteIOUtils.write(entry.getValue().getBuildInfo(), outputStream);
     }
   }
 
@@ -516,7 +519,7 @@ public class NodeInfo implements SnapshotProcessor {
 
     configNodeInfoReadWriteLock.writeLock().lock();
     dataNodeInfoReadWriteLock.writeLock().lock();
-    buildInfoReadWriteLock.writeLock().lock();
+    versionInfoReadWriteLock.writeLock().lock();
 
     try (FileInputStream fileInputStream = new FileInputStream(snapshotFile);
         TIOStreamTransport tioStreamTransport = new 
TIOStreamTransport(fileInputStream)) {
@@ -533,7 +536,7 @@ public class NodeInfo implements SnapshotProcessor {
       deserializeBuildInfo(fileInputStream);
 
     } finally {
-      buildInfoReadWriteLock.writeLock().unlock();
+      versionInfoReadWriteLock.writeLock().unlock();
       dataNodeInfoReadWriteLock.writeLock().unlock();
       configNodeInfoReadWriteLock.writeLock().unlock();
     }
@@ -570,8 +573,9 @@ public class NodeInfo implements SnapshotProcessor {
       int size = ReadWriteIOUtils.readInt(inputStream);
       while (size > 0) {
         int nodeId = ReadWriteIOUtils.readInt(inputStream);
+        String version = ReadWriteIOUtils.readString(inputStream);
         String buildInfo = ReadWriteIOUtils.readString(inputStream);
-        nodeBuildInfo.put(nodeId, buildInfo);
+        nodeVersionInfo.put(nodeId, new TNodeVersionInfo(version, buildInfo));
         size--;
       }
     }
@@ -585,7 +589,7 @@ public class NodeInfo implements SnapshotProcessor {
     nextNodeId.set(-1);
     registeredDataNodes.clear();
     registeredConfigNodes.clear();
-    nodeBuildInfo.clear();
+    nodeVersionInfo.clear();
   }
 
   @Override
@@ -600,11 +604,11 @@ public class NodeInfo implements SnapshotProcessor {
     return registeredConfigNodes.equals(nodeInfo.registeredConfigNodes)
         && nextNodeId.get() == nodeInfo.nextNodeId.get()
         && registeredDataNodes.equals(nodeInfo.registeredDataNodes)
-        && nodeBuildInfo.equals(nodeInfo.nodeBuildInfo);
+        && nodeVersionInfo.equals(nodeInfo.nodeVersionInfo);
   }
 
   @Override
   public int hashCode() {
-    return Objects.hash(registeredConfigNodes, nextNodeId, 
registeredDataNodes, nodeBuildInfo);
+    return Objects.hash(registeredConfigNodes, nextNodeId, 
registeredDataNodes, nodeVersionInfo);
   }
 }
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/env/ConfigNodeProcedureEnv.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/env/ConfigNodeProcedureEnv.java
index df6c32999b4..371243bc197 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/env/ConfigNodeProcedureEnv.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/env/ConfigNodeProcedureEnv.java
@@ -57,6 +57,7 @@ import 
org.apache.iotdb.confignode.procedure.exception.ProcedureException;
 import org.apache.iotdb.confignode.procedure.scheduler.LockQueue;
 import org.apache.iotdb.confignode.procedure.scheduler.ProcedureScheduler;
 import org.apache.iotdb.confignode.rpc.thrift.TAddConsensusGroupReq;
+import org.apache.iotdb.confignode.rpc.thrift.TNodeVersionInfo;
 import org.apache.iotdb.mpp.rpc.thrift.TActiveTriggerInstanceReq;
 import org.apache.iotdb.mpp.rpc.thrift.TCreateDataRegionReq;
 import org.apache.iotdb.mpp.rpc.thrift.TCreatePipePluginInstanceReq;
@@ -324,10 +325,11 @@ public class ConfigNodeProcedureEnv {
    * Leader will record the new ConfigNode's information.
    *
    * @param configNodeLocation The new ConfigNode
-   * @param buildInfo The new ConfigNode's buildInfo
+   * @param versionInfo The new ConfigNode's versionInfo
    */
-  public void applyConfigNode(TConfigNodeLocation configNodeLocation, String 
buildInfo) {
-    configManager.getNodeManager().applyConfigNode(configNodeLocation, 
buildInfo);
+  public void applyConfigNode(
+      TConfigNodeLocation configNodeLocation, TNodeVersionInfo versionInfo) {
+    configManager.getNodeManager().applyConfigNode(configNodeLocation, 
versionInfo);
   }
 
   /**
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/node/AddConfigNodeProcedure.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/node/AddConfigNodeProcedure.java
index d09d331e57d..d799762ad67 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/node/AddConfigNodeProcedure.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/node/AddConfigNodeProcedure.java
@@ -26,6 +26,7 @@ import 
org.apache.iotdb.confignode.procedure.env.ConfigNodeProcedureEnv;
 import org.apache.iotdb.confignode.procedure.exception.ProcedureException;
 import org.apache.iotdb.confignode.procedure.state.AddConfigNodeState;
 import org.apache.iotdb.confignode.procedure.store.ProcedureType;
+import org.apache.iotdb.confignode.rpc.thrift.TNodeVersionInfo;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import org.slf4j.Logger;
@@ -43,16 +44,17 @@ public class AddConfigNodeProcedure extends 
AbstractNodeProcedure<AddConfigNodeS
 
   private TConfigNodeLocation tConfigNodeLocation;
 
-  private String buildInfo;
+  private TNodeVersionInfo versionInfo;
 
   public AddConfigNodeProcedure() {
     super();
   }
 
-  public AddConfigNodeProcedure(TConfigNodeLocation tConfigNodeLocation, 
String buildInfo) {
+  public AddConfigNodeProcedure(
+      TConfigNodeLocation tConfigNodeLocation, TNodeVersionInfo versionInfo) {
     super();
     this.tConfigNodeLocation = tConfigNodeLocation;
-    this.buildInfo = buildInfo;
+    this.versionInfo = versionInfo;
   }
 
   @Override
@@ -79,7 +81,7 @@ public class AddConfigNodeProcedure extends 
AbstractNodeProcedure<AddConfigNodeS
           break;
         case REGISTER_SUCCESS:
           env.notifyRegisterSuccess(tConfigNodeLocation);
-          env.applyConfigNode(tConfigNodeLocation, buildInfo);
+          env.applyConfigNode(tConfigNodeLocation, versionInfo);
           env.broadCastTheLatestConfigNodeGroup();
           LOG.info("The ConfigNode: {} is successfully added to the cluster", 
tConfigNodeLocation);
           return Flow.NO_MORE_STATE;
@@ -149,7 +151,8 @@ public class AddConfigNodeProcedure extends 
AbstractNodeProcedure<AddConfigNodeS
     stream.writeShort(ProcedureType.ADD_CONFIG_NODE_PROCEDURE.getTypeCode());
     super.serialize(stream);
     
ThriftConfigNodeSerDeUtils.serializeTConfigNodeLocation(tConfigNodeLocation, 
stream);
-    ReadWriteIOUtils.write(buildInfo, stream);
+    ReadWriteIOUtils.write(versionInfo.getVersion(), stream);
+    ReadWriteIOUtils.write(versionInfo.getBuildInfo(), stream);
   }
 
   @Override
@@ -157,10 +160,12 @@ public class AddConfigNodeProcedure extends 
AbstractNodeProcedure<AddConfigNodeS
     super.deserialize(byteBuffer);
     try {
       tConfigNodeLocation = 
ThriftConfigNodeSerDeUtils.deserializeTConfigNodeLocation(byteBuffer);
-      // old version may not have build info,
+      // old version may not have version info,
       // thus we need to check inputStream before deserialize.
       if (byteBuffer.hasRemaining()) {
-        buildInfo = ReadWriteIOUtils.readString(byteBuffer);
+        versionInfo =
+            new TNodeVersionInfo(
+                ReadWriteIOUtils.readString(byteBuffer), 
ReadWriteIOUtils.readString(byteBuffer));
       }
     } catch (ThriftSerDeException e) {
       LOG.error("Error in deserialize AddConfigNodeProcedure", e);
@@ -174,13 +179,13 @@ public class AddConfigNodeProcedure extends 
AbstractNodeProcedure<AddConfigNodeS
       return thatProc.getProcId() == this.getProcId()
           && thatProc.getState() == this.getState()
           && thatProc.tConfigNodeLocation.equals(this.tConfigNodeLocation)
-          && thatProc.buildInfo.equals(this.buildInfo);
+          && thatProc.versionInfo.equals(this.versionInfo);
     }
     return false;
   }
 
   @Override
   public int hashCode() {
-    return Objects.hash(this.tConfigNodeLocation, this.buildInfo);
+    return Objects.hash(this.tConfigNodeLocation, this.versionInfo);
   }
 }
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/ConfigNode.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/ConfigNode.java
index 40314a5a856..8caacd274ce 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/ConfigNode.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/ConfigNode.java
@@ -43,6 +43,7 @@ import org.apache.iotdb.confignode.manager.ConfigManager;
 import org.apache.iotdb.confignode.rpc.thrift.TConfigNodeRegisterReq;
 import org.apache.iotdb.confignode.rpc.thrift.TConfigNodeRegisterResp;
 import org.apache.iotdb.confignode.rpc.thrift.TConfigNodeRestartReq;
+import org.apache.iotdb.confignode.rpc.thrift.TNodeVersionInfo;
 import org.apache.iotdb.confignode.service.thrift.ConfigNodeRPCService;
 import 
org.apache.iotdb.confignode.service.thrift.ConfigNodeRPCServiceProcessor;
 import org.apache.iotdb.db.service.metrics.ProcessMetrics;
@@ -150,7 +151,9 @@ public class ConfigNode implements ConfigNodeMBean {
           TSStatus status =
               configManager
                   .getNodeManager()
-                  .updateConfigNodeIfNecessary(configNodeId, 
IoTDBConstant.BUILD_INFO);
+                  .updateConfigNodeIfNecessary(
+                      configNodeId,
+                      new TNodeVersionInfo(IoTDBConstant.VERSION, 
IoTDBConstant.BUILD_INFO));
           if (status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) 
{
             break;
           } else {
@@ -178,7 +181,8 @@ public class ConfigNode implements ConfigNodeMBean {
         configManager
             .getNodeManager()
             .applyConfigNode(
-                generateConfigNodeLocation(SEED_CONFIG_NODE_ID), 
IoTDBConstant.BUILD_INFO);
+                generateConfigNodeLocation(SEED_CONFIG_NODE_ID),
+                new TNodeVersionInfo(IoTDBConstant.VERSION, 
IoTDBConstant.BUILD_INFO));
         setUpMetricService();
         // Notice: We always set up Seed-ConfigNode's RPC service lastly to 
ensure
         // that the external service is not provided until Seed-ConfigNode is 
fully initialized
@@ -308,7 +312,7 @@ public class ConfigNode implements ConfigNodeMBean {
             configManager.getClusterParameters(),
             generateConfigNodeLocation(INIT_NON_SEED_CONFIG_NODE_ID));
 
-    req.setBuildInfo(IoTDBConstant.BUILD_INFO);
+    req.setVersionInfo(new TNodeVersionInfo(IoTDBConstant.VERSION, 
IoTDBConstant.BUILD_INFO));
 
     TEndPoint targetConfigNode = CONF.getTargetConfigNode();
     if (targetConfigNode == null) {
diff --git 
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/node/AddConfigNodeProcedureTest.java
 
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/node/AddConfigNodeProcedureTest.java
index d95d49c6aa2..b6eaa316217 100644
--- 
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/node/AddConfigNodeProcedureTest.java
+++ 
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/node/AddConfigNodeProcedureTest.java
@@ -22,6 +22,7 @@ import org.apache.iotdb.common.rpc.thrift.TConfigNodeLocation;
 import org.apache.iotdb.common.rpc.thrift.TEndPoint;
 import org.apache.iotdb.commons.conf.IoTDBConstant;
 import org.apache.iotdb.confignode.procedure.store.ProcedureFactory;
+import org.apache.iotdb.confignode.rpc.thrift.TNodeVersionInfo;
 import org.apache.iotdb.tsfile.utils.PublicBAOS;
 
 import org.junit.Assert;
@@ -39,7 +40,7 @@ public class AddConfigNodeProcedureTest {
         new AddConfigNodeProcedure(
             new TConfigNodeLocation(
                 0, new TEndPoint("127.0.0.1", 10710), new TEndPoint("0.0.0.0", 
10720)),
-            IoTDBConstant.BUILD_INFO);
+            new TNodeVersionInfo(IoTDBConstant.VERSION, 
IoTDBConstant.BUILD_INFO));
 
     try (PublicBAOS byteArrayOutputStream = new PublicBAOS();
         DataOutputStream outputStream = new 
DataOutputStream(byteArrayOutputStream)) {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/header/ColumnHeaderConstant.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/header/ColumnHeaderConstant.java
index 7035a2bbd3d..5cd5e9a2e22 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/header/ColumnHeaderConstant.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/header/ColumnHeaderConstant.java
@@ -330,6 +330,7 @@ public class ColumnHeaderConstant {
           new ColumnHeader(STATUS, TSDataType.TEXT),
           new ColumnHeader(INTERNAL_ADDRESS, TSDataType.TEXT),
           new ColumnHeader(INTERNAL_PORT, TSDataType.INT32),
+          new ColumnHeader(VERSION, TSDataType.TEXT),
           new ColumnHeader(BUILD_INFO, TSDataType.TEXT));
 
   public static final List<ColumnHeader> showClusterDetailsColumnHeaders =
@@ -344,7 +345,9 @@ public class ColumnHeaderConstant {
           new ColumnHeader(RPC_PORT, TSDataType.TEXT),
           new ColumnHeader(MPP_PORT, TSDataType.TEXT),
           new ColumnHeader(SCHEMA_CONSENSUS_PORT, TSDataType.TEXT),
-          new ColumnHeader(DATA_CONSENSUS_PORT, TSDataType.TEXT));
+          new ColumnHeader(DATA_CONSENSUS_PORT, TSDataType.TEXT),
+          new ColumnHeader(VERSION, TSDataType.TEXT),
+          new ColumnHeader(BUILD_INFO, TSDataType.TEXT));
 
   public static final List<ColumnHeader> showVariablesColumnHeaders =
       ImmutableList.of(
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/ShowClusterDetailsTask.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/ShowClusterDetailsTask.java
index fb10d52cbe2..65b7b3cf8a0 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/ShowClusterDetailsTask.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/ShowClusterDetailsTask.java
@@ -19,6 +19,7 @@
 
 package org.apache.iotdb.db.queryengine.plan.execution.config.metadata;
 
+import org.apache.iotdb.confignode.rpc.thrift.TNodeVersionInfo;
 import org.apache.iotdb.confignode.rpc.thrift.TShowClusterResp;
 import org.apache.iotdb.db.queryengine.common.header.ColumnHeader;
 import org.apache.iotdb.db.queryengine.common.header.ColumnHeaderConstant;
@@ -53,14 +54,14 @@ public class ShowClusterDetailsTask implements IConfigTask {
   private static void buildConfigNodesTsBlock(
       TsBlockBuilder builder,
       int nodeId,
-      String nodeType,
       String nodeStatus,
       String internalAddress,
       int internalPort,
-      int configConsensusPort) {
+      int configConsensusPort,
+      TNodeVersionInfo versionInfo) {
     builder.getTimeColumnBuilder().writeLong(0L);
     builder.getColumnBuilder(0).writeInt(nodeId);
-    builder.getColumnBuilder(1).writeBinary(new Binary(nodeType));
+    builder.getColumnBuilder(1).writeBinary(new Binary(NODE_TYPE_CONFIG_NODE));
     builder.getColumnBuilder(2).writeBinary(new Binary(nodeStatus));
     builder.getColumnBuilder(3).writeBinary(new Binary(internalAddress));
     builder.getColumnBuilder(4).writeInt(internalPort);
@@ -70,6 +71,8 @@ public class ShowClusterDetailsTask implements IConfigTask {
     builder.getColumnBuilder(8).writeBinary(new Binary(""));
     builder.getColumnBuilder(9).writeBinary(new Binary(""));
     builder.getColumnBuilder(10).writeBinary(new Binary(""));
+    builder.getColumnBuilder(11).writeBinary(new 
Binary(versionInfo.getVersion()));
+    builder.getColumnBuilder(12).writeBinary(new 
Binary(versionInfo.getBuildInfo()));
     builder.declarePosition();
   }
 
@@ -77,7 +80,6 @@ public class ShowClusterDetailsTask implements IConfigTask {
   private static void buildDataNodesTsBlock(
       TsBlockBuilder builder,
       int nodeId,
-      String nodeType,
       String nodeStatus,
       String internalAddress,
       int internalPort,
@@ -85,10 +87,11 @@ public class ShowClusterDetailsTask implements IConfigTask {
       int rpcPort,
       int dataConsensusPort,
       int schemaConsensusPort,
-      int mppPort) {
+      int mppPort,
+      TNodeVersionInfo versionInfo) {
     builder.getTimeColumnBuilder().writeLong(0L);
     builder.getColumnBuilder(0).writeInt(nodeId);
-    builder.getColumnBuilder(1).writeBinary(new Binary(nodeType));
+    builder.getColumnBuilder(1).writeBinary(new Binary(NODE_TYPE_DATA_NODE));
     builder.getColumnBuilder(2).writeBinary(new Binary(nodeStatus));
     builder.getColumnBuilder(3).writeBinary(new Binary(internalAddress));
     builder.getColumnBuilder(4).writeInt(internalPort);
@@ -98,6 +101,8 @@ public class ShowClusterDetailsTask implements IConfigTask {
     builder.getColumnBuilder(8).writeBinary(new 
Binary(Integer.toString(dataConsensusPort)));
     builder.getColumnBuilder(9).writeBinary(new 
Binary(Integer.toString(schemaConsensusPort)));
     builder.getColumnBuilder(10).writeBinary(new 
Binary(Integer.toString(mppPort)));
+    builder.getColumnBuilder(11).writeBinary(new 
Binary(versionInfo.getVersion()));
+    builder.getColumnBuilder(12).writeBinary(new 
Binary(versionInfo.getBuildInfo()));
     builder.declarePosition();
   }
 
@@ -116,11 +121,11 @@ public class ShowClusterDetailsTask implements 
IConfigTask {
                 buildConfigNodesTsBlock(
                     builder,
                     e.getConfigNodeId(),
-                    NODE_TYPE_CONFIG_NODE,
                     clusterNodeInfos.getNodeStatus().get(e.getConfigNodeId()),
                     e.getInternalEndPoint().getIp(),
                     e.getInternalEndPoint().getPort(),
-                    e.getConsensusEndPoint().getPort()));
+                    e.getConsensusEndPoint().getPort(),
+                    
clusterNodeInfos.getNodeVersionInfo().get(e.getConfigNodeId())));
 
     clusterNodeInfos
         .getDataNodeList()
@@ -129,7 +134,6 @@ public class ShowClusterDetailsTask implements IConfigTask {
                 buildDataNodesTsBlock(
                     builder,
                     e.getDataNodeId(),
-                    NODE_TYPE_DATA_NODE,
                     clusterNodeInfos.getNodeStatus().get(e.getDataNodeId()),
                     e.getInternalEndPoint().getIp(),
                     e.getInternalEndPoint().getPort(),
@@ -137,7 +141,8 @@ public class ShowClusterDetailsTask implements IConfigTask {
                     e.getClientRpcEndPoint().getPort(),
                     e.getMPPDataExchangeEndPoint().getPort(),
                     e.getSchemaRegionConsensusEndPoint().getPort(),
-                    e.getDataRegionConsensusEndPoint().getPort()));
+                    e.getDataRegionConsensusEndPoint().getPort(),
+                    
clusterNodeInfos.getNodeVersionInfo().get(e.getDataNodeId())));
 
     DatasetHeader datasetHeader = 
DatasetHeaderFactory.getShowClusterDetailsHeader();
     future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS, 
builder.build(), datasetHeader));
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/ShowClusterTask.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/ShowClusterTask.java
index 71db942031c..65ebb459a92 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/ShowClusterTask.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/ShowClusterTask.java
@@ -19,6 +19,7 @@
 
 package org.apache.iotdb.db.queryengine.plan.execution.config.metadata;
 
+import org.apache.iotdb.confignode.rpc.thrift.TNodeVersionInfo;
 import org.apache.iotdb.confignode.rpc.thrift.TShowClusterResp;
 import org.apache.iotdb.db.queryengine.common.header.ColumnHeader;
 import org.apache.iotdb.db.queryengine.common.header.ColumnHeaderConstant;
@@ -63,14 +64,15 @@ public class ShowClusterTask implements IConfigTask {
       String nodeStatus,
       String hostAddress,
       int port,
-      String buildInfo) {
+      TNodeVersionInfo versionInfo) {
     builder.getTimeColumnBuilder().writeLong(0L);
     builder.getColumnBuilder(0).writeInt(nodeId);
     builder.getColumnBuilder(1).writeBinary(new Binary(nodeType));
     builder.getColumnBuilder(2).writeBinary(new Binary(nodeStatus));
     builder.getColumnBuilder(3).writeBinary(new Binary(hostAddress));
     builder.getColumnBuilder(4).writeInt(port);
-    builder.getColumnBuilder(5).writeBinary(new Binary(buildInfo));
+    builder.getColumnBuilder(5).writeBinary(new 
Binary(versionInfo.getVersion()));
+    builder.getColumnBuilder(6).writeBinary(new 
Binary(versionInfo.getBuildInfo()));
     builder.declarePosition();
   }
 
@@ -93,7 +95,7 @@ public class ShowClusterTask implements IConfigTask {
                     clusterNodeInfos.getNodeStatus().get(e.getConfigNodeId()),
                     e.getInternalEndPoint().getIp(),
                     e.getInternalEndPoint().getPort(),
-                    
clusterNodeInfos.getNodeBuildInfo().get(e.getConfigNodeId())));
+                    
clusterNodeInfos.getNodeVersionInfo().get(e.getConfigNodeId())));
 
     clusterNodeInfos
         .getDataNodeList()
@@ -106,7 +108,7 @@ public class ShowClusterTask implements IConfigTask {
                     clusterNodeInfos.getNodeStatus().get(e.getDataNodeId()),
                     e.getInternalEndPoint().getIp(),
                     e.getInternalEndPoint().getPort(),
-                    
clusterNodeInfos.getNodeBuildInfo().get(e.getDataNodeId())));
+                    
clusterNodeInfos.getNodeVersionInfo().get(e.getDataNodeId())));
 
     DatasetHeader datasetHeader = DatasetHeaderFactory.getShowClusterHeader();
     future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS, 
builder.build(), datasetHeader));
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/DataNode.java 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/DataNode.java
index fce5216b9c5..7aa275ae1dc 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/DataNode.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/DataNode.java
@@ -48,6 +48,7 @@ import 
org.apache.iotdb.confignode.rpc.thrift.TDataNodeRestartReq;
 import org.apache.iotdb.confignode.rpc.thrift.TDataNodeRestartResp;
 import org.apache.iotdb.confignode.rpc.thrift.TGetJarInListReq;
 import org.apache.iotdb.confignode.rpc.thrift.TGetJarInListResp;
+import org.apache.iotdb.confignode.rpc.thrift.TNodeVersionInfo;
 import org.apache.iotdb.confignode.rpc.thrift.TRuntimeConfiguration;
 import org.apache.iotdb.confignode.rpc.thrift.TSystemConfigurationResp;
 import org.apache.iotdb.consensus.ConsensusFactory;
@@ -361,7 +362,7 @@ public class DataNode implements DataNodeMBean {
     TDataNodeRegisterReq req = new TDataNodeRegisterReq();
     req.setDataNodeConfiguration(generateDataNodeConfiguration());
     req.setClusterName(config.getClusterName());
-    req.setBuildInfo(IoTDBConstant.BUILD_INFO);
+    req.setVersionInfo(new TNodeVersionInfo(IoTDBConstant.VERSION, 
IoTDBConstant.BUILD_INFO));
     TDataNodeRegisterResp dataNodeRegisterResp = null;
     while (retry > 0) {
       try (ConfigNodeClient configNodeClient =
@@ -421,7 +422,7 @@ public class DataNode implements DataNodeMBean {
     req.setClusterName(
         config.getClusterName() == null ? DEFAULT_CLUSTER_NAME : 
config.getClusterName());
     req.setDataNodeConfiguration(generateDataNodeConfiguration());
-    req.setBuildInfo(IoTDBConstant.BUILD_INFO);
+    req.setVersionInfo(new TNodeVersionInfo(IoTDBConstant.VERSION, 
IoTDBConstant.BUILD_INFO));
     TDataNodeRestartResp dataNodeRestartResp = null;
     while (retry > 0) {
       try (ConfigNodeClient configNodeClient =
diff --git a/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift 
b/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift
index b4b8cd9e379..dff1a0736ed 100644
--- a/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift
+++ b/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift
@@ -102,7 +102,7 @@ struct TRuntimeConfiguration {
 struct TDataNodeRegisterReq {
   1: required string clusterName
   2: required common.TDataNodeConfiguration dataNodeConfiguration
-  3: optional string buildInfo = "Unknown"
+  3: optional TNodeVersionInfo versionInfo
 }
 
 struct TDataNodeRegisterResp {
@@ -115,7 +115,7 @@ struct TDataNodeRegisterResp {
 struct TDataNodeRestartReq {
   1: required string clusterName
   2: required common.TDataNodeConfiguration dataNodeConfiguration
-  3: optional string buildInfo = "Unknown"
+  3: optional TNodeVersionInfo versionInfo
 }
 
 struct TDataNodeRestartResp {
@@ -368,7 +368,7 @@ struct TConfigNodeRegisterReq {
   // fields are consistent with the Seed-ConfigNode
   1: required TClusterParameters clusterParameters
   2: required common.TConfigNodeLocation configNodeLocation
-  3: optional string buildInfo = "Unknown"
+  3: optional TNodeVersionInfo versionInfo
 }
 
 struct TConfigNodeRegisterResp {
@@ -486,7 +486,12 @@ struct TShowClusterResp {
   2: required list<common.TConfigNodeLocation> configNodeList
   3: required list<common.TDataNodeLocation> dataNodeList
   4: required map<i32, string> nodeStatus
-  5: required map<i32, string> nodeBuildInfo
+  5: required map<i32, TNodeVersionInfo> nodeVersionInfo
+}
+
+struct TNodeVersionInfo {
+  1: required string version;
+  2: required string buildInfo;
 }
 
 struct TShowVariablesResp {

Reply via email to