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

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


The following commit(s) were added to refs/heads/branch-4.1 by this push:
     new f22b4612936 [feature](compute group) Support show compute groups in 
non cloud mode (#66697) (#67298)
f22b4612936 is described below

commit f22b4612936d2528501b41d29bddaef6c6a137c0
Author: deardeng <[email protected]>
AuthorDate: Mon Aug 31 15:27:22 2026 +0800

    [feature](compute group) Support show compute groups in non cloud mode 
(#66697) (#67298)
    
    pick from https://github.com/apache/doris/pull/66697
    
    Expose resource groups as compute groups for SHOW CLUSTERS and SHOW
    COMPUTE GROUPS in non-cloud mode.
    
    (cherry picked from commit 788baa53665c96312a10b2d3830094b34d21c5c7)
    
    ### What problem does this PR solve?
    
    Issue Number: close #xxx
    
    Related PR: #xxx
    
    Problem Summary:
    
    ### Release note
    
    None
    
    ### Check List (For Author)
    
    - Test <!-- At least one of them must be included. -->
        - [ ] Regression test
        - [ ] Unit Test
        - [ ] Manual test (add detailed scripts or steps below)
        - [ ] No need to test or manual test. Explain why:
    - [ ] This is a refactor/code format and no logic has been changed.
            - [ ] Previous test can cover this change.
            - [ ] No code files have been changed.
            - [ ] Other reason <!-- Add your reason?  -->
    
    - Behavior changed:
        - [ ] No.
        - [ ] Yes. <!-- Explain the behavior change -->
    
    - Does this need documentation?
        - [ ] No.
    - [ ] Yes. <!-- Add document PR link here. eg:
    https://github.com/apache/doris-website/pull/1214 -->
    
    ### Check List (For Reviewer who merge this PR)
    
    - [ ] Confirm the release note
    - [ ] Confirm test cases
    - [ ] Confirm document
    - [ ] Add branch pick label <!-- Add branch pick label that this PR
    should merge into -->
---
 .../trees/plans/commands/ShowClustersCommand.java  | 43 +++++++++--------
 .../trees/plans/commands/ShowComputeGroupTest.java | 55 ++++++++++++++++++----
 2 files changed, 70 insertions(+), 28 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowClustersCommand.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowClustersCommand.java
index 366fc59c168..cc4c3e5a8f3 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowClustersCommand.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowClustersCommand.java
@@ -26,10 +26,7 @@ import org.apache.doris.cloud.catalog.CloudComputeGroupMeta;
 import org.apache.doris.cloud.qe.ComputeGroupException;
 import org.apache.doris.cloud.system.CloudSystemInfoService;
 import org.apache.doris.cluster.ClusterNamespace;
-import org.apache.doris.common.AnalysisException;
 import org.apache.doris.common.Config;
-import org.apache.doris.common.ErrorCode;
-import org.apache.doris.common.ErrorReport;
 import org.apache.doris.mysql.privilege.Auth;
 import org.apache.doris.mysql.privilege.PrivBitSet;
 import org.apache.doris.mysql.privilege.PrivPredicate;
@@ -40,6 +37,7 @@ import org.apache.doris.qe.ConnectContext;
 import org.apache.doris.qe.ShowResultSet;
 import org.apache.doris.qe.ShowResultSetMetaData;
 import org.apache.doris.qe.StmtExecutor;
+import org.apache.doris.resource.computegroup.ComputeGroup;
 
 import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableList;
@@ -50,7 +48,9 @@ import org.apache.logging.log4j.Logger;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
 import java.util.stream.Collectors;
 
 /**
@@ -65,6 +65,11 @@ public class ShowClustersCommand extends ShowCommand {
     public static final ImmutableList<String> COMPUTE_GROUP_TITLE_NAMES = new 
ImmutableList.Builder<String>()
             .add("Name").add("IsCurrent").add("Users").add("BackendNum")
             .add("SubComputeGroups").add("Policy").add("Properties").build();
+    // non cloud mode, a resource group(backend location tag) is the 
counterpart of a cloud compute group
+    public static final ImmutableList<String> CLUSTER_TITLE_NAMES_NON_CLOUD = 
new ImmutableList.Builder<String>()
+            .add("cluster").add("backend_num").build();
+    public static final ImmutableList<String> 
COMPUTE_GROUP_TITLE_NAMES_NON_CLOUD = new ImmutableList.Builder<String>()
+            .add("Name").add("BackendNum").build();
 
     private static final Logger LOG = 
LogManager.getLogger(ShowClustersCommand.class);
     private final boolean isComputeGroup;
@@ -74,22 +79,23 @@ public class ShowClustersCommand extends ShowCommand {
         this.isComputeGroup = isComputeGroup;
     }
 
-    private void validate(ConnectContext ctx) throws AnalysisException {
-        if (Config.isNotCloudMode()) {
-            // just user admin
-            if 
(!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ConnectContext.get().getCurrentUserIdentity(),
-                        PrivPredicate.of(PrivBitSet.of(Privilege.ADMIN_PRIV, 
Privilege.NODE_PRIV), Operator.OR))) {
-                
ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, 
"ADMIN");
-            }
-        }
-    }
-
     @Override
     public ShowResultSet doRun(ConnectContext ctx, StmtExecutor executor) 
throws Exception {
-        validate(ctx);
         final List<List<String>> rows = Lists.newArrayList();
-        if (!Config.isCloudMode()) {
-            ErrorReport.reportAnalysisException(ErrorCode.ERR_NOT_CLOUD_MODE);
+        if (Config.isNotCloudMode()) {
+            // resource group is the compute group of non cloud mode, a user 
only sees the resource groups
+            // it is allowed to use, same as the cloud mode which filters 
clusters by usage priv.
+            ComputeGroup userComputeGroup = ctx.getComputeGroup();
+            if (ComputeGroup.INVALID_COMPUTE_GROUP == userComputeGroup) {
+                return new ShowResultSet(getMetaData(), rows);
+            }
+            Map<String, Long> backendNumByGroup = 
Env.getCurrentSystemInfo().getAllClusterBackends(false).stream()
+                    .map(be -> be.getLocationTag().value)
+                    .filter(userComputeGroup::containsBackend)
+                    .collect(Collectors.groupingBy(name -> name, TreeMap::new, 
Collectors.counting()));
+            for (Map.Entry<String, Long> entry : backendNumByGroup.entrySet()) 
{
+                rows.add(Lists.newArrayList(entry.getKey(), 
String.valueOf(entry.getValue())));
+            }
             return new ShowResultSet(getMetaData(), rows);
         }
 
@@ -182,9 +188,9 @@ public class ShowClustersCommand extends ShowCommand {
 
         ImmutableList<String> titleNames = null;
         if (isComputeGroup) {
-            titleNames = COMPUTE_GROUP_TITLE_NAMES;
+            titleNames = Config.isNotCloudMode() ? 
COMPUTE_GROUP_TITLE_NAMES_NON_CLOUD : COMPUTE_GROUP_TITLE_NAMES;
         } else {
-            titleNames = CLUSTER_TITLE_NAMES;
+            titleNames = Config.isNotCloudMode() ? 
CLUSTER_TITLE_NAMES_NON_CLOUD : CLUSTER_TITLE_NAMES;
         }
 
         for (String title : titleNames) {
@@ -193,4 +199,3 @@ public class ShowClustersCommand extends ShowCommand {
         return builder.build();
     }
 }
-
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/ShowComputeGroupTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/ShowComputeGroupTest.java
index 06588301872..cab5353856c 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/ShowComputeGroupTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/ShowComputeGroupTest.java
@@ -18,11 +18,14 @@
 package org.apache.doris.nereids.trees.plans.commands;
 
 import org.apache.doris.catalog.Column;
-import org.apache.doris.common.AnalysisException;
+import org.apache.doris.catalog.Env;
 import org.apache.doris.common.Config;
 import org.apache.doris.qe.ShowResultSetMetaData;
+import org.apache.doris.resource.Tag;
+import org.apache.doris.system.Backend;
 import org.apache.doris.utframe.TestWithFeService;
 
+import com.google.common.collect.Lists;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
@@ -38,6 +41,7 @@ public class ShowComputeGroupTest extends TestWithFeService {
     @Test
     public void testShowComputeGroupsInCloudMode() throws Exception {
         Config.deploy_mode = "cloud";
+        Config.cloud_unique_id = "cloud_unique_id";
         ShowClustersCommand command = new ShowClustersCommand(true);
         ShowResultSetMetaData metaData = command.getMetaData();
         Assertions.assertNotNull(metaData);
@@ -56,15 +60,47 @@ public class ShowComputeGroupTest extends TestWithFeService 
{
 
     @Test
     public void testShowComputeGroupsInNonCloudMode() throws Exception {
-        Config.deploy_mode = "not-cloud";
+        Config.deploy_mode = "";
+        Config.cloud_unique_id = "";
+        Tag groupA = Tag.create(Tag.TYPE_LOCATION, "group_a");
+        Backend groupABackend1 = addNewBackend();
+        Backend groupABackend2 = addNewBackend();
+        Backend groupBBackend = addNewBackend();
+        groupABackend1.setTagMap(groupA.toMap());
+        groupABackend2.setTagMap(groupA.toMap());
+        groupBBackend.setTagMap(Tag.create(Tag.TYPE_LOCATION, 
"group_b").toMap());
+
         ShowClustersCommand command = new ShowClustersCommand(true);
-        Assertions.assertThrows(AnalysisException.class, () -> {
-            command.doRun(connectContext, null);
-        });
+        List<String> columnNames = command.getMetaData().getColumns().stream()
+                .map(Column::getName).collect(Collectors.toList());
+        Assertions.assertEquals(Lists.newArrayList("Name", "BackendNum"), 
columnNames);
+        List<List<String>> rows = command.doRun(connectContext, 
null).getResultRows();
+        List<List<String>> expectedRows = Lists.newArrayList(
+                Lists.newArrayList(Tag.VALUE_DEFAULT_TAG, "1"),
+                Lists.newArrayList("group_a", "2"),
+                Lists.newArrayList("group_b", "1"));
+        Assertions.assertEquals(expectedRows, rows);
+
+        // a user restricted by resource_tags.location only sees the resource 
groups it can use,
+        // this is the compute group bound to the session when the user logs 
in.
+        executeSql("CREATE USER show_cg_user IDENTIFIED BY '12345'");
+        try {
+            executeSql("SET PROPERTY FOR 'show_cg_user' 
'resource_tags.location' = 'group_a'");
+            
connectContext.setComputeGroup(Env.getCurrentEnv().getAuth().getComputeGroup("show_cg_user"));
+            Assertions.assertEquals(expectedRows.subList(1, 2), 
command.doRun(connectContext, null).getResultRows());
+
+            executeSql("SET PROPERTY FOR 'show_cg_user' 
'resource_tags.location' = 'no_such_resource_group'");
+            
connectContext.setComputeGroup(Env.getCurrentEnv().getAuth().getComputeGroup("show_cg_user"));
+            Assertions.assertTrue(command.doRun(connectContext, 
null).getResultRows().isEmpty());
+        } finally {
+            connectContext.setComputeGroup(null);
+        }
     }
 
     @Test
     public void testShowClustersInCloudMode() throws Exception {
+        Config.deploy_mode = "cloud";
+        Config.cloud_unique_id = "cloud_unique_id";
         ShowClustersCommand command = new ShowClustersCommand(false);
         ShowResultSetMetaData metaData = command.getMetaData();
         Assertions.assertNotNull(metaData);
@@ -82,10 +118,11 @@ public class ShowComputeGroupTest extends 
TestWithFeService {
 
     @Test
     public void testShowClustersInNonCloudMode() throws Exception {
-        Config.deploy_mode = "not-cloud";
+        Config.deploy_mode = "";
+        Config.cloud_unique_id = "";
         ShowClustersCommand command = new ShowClustersCommand(false);
-        Assertions.assertThrows(AnalysisException.class, () -> {
-            command.doRun(connectContext, null);
-        });
+        List<String> columnNames = command.getMetaData().getColumns().stream()
+                .map(Column::getName).collect(Collectors.toList());
+        Assertions.assertEquals(Lists.newArrayList("cluster", "backend_num"), 
columnNames);
     }
 }


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

Reply via email to