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

morningman 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 4cd0dae4b30 [improvement](auth) support show all properties (#25645)
4cd0dae4b30 is described below

commit 4cd0dae4b3033e851b3f0b736f083e426dec2d8e
Author: zhangdong <493738...@qq.com>
AuthorDate: Tue Oct 24 17:27:59 2023 +0800

    [improvement](auth) support show all properties (#25645)
    
    support `show all properties`
---
 .../sql-reference/Show-Statements/SHOW-PROPERTY.md | 35 +++++++++-
 .../sql-reference/Show-Statements/SHOW-PROPERTY.md | 33 ++++++++-
 fe/fe-core/src/main/cup/sql_parser.cup             |  6 +-
 .../doris/analysis/ShowUserPropertyStmt.java       | 78 +++++++++++++++++++---
 .../doris/common/proc/UserPropertyProcNode.java    |  4 ++
 .../org/apache/doris/mysql/privilege/Auth.java     |  3 +
 .../doris/analysis/ShowUserPropertyStmtTest.java   | 36 +++++++++-
 7 files changed, 177 insertions(+), 18 deletions(-)

diff --git 
a/docs/en/docs/sql-manual/sql-reference/Show-Statements/SHOW-PROPERTY.md 
b/docs/en/docs/sql-manual/sql-reference/Show-Statements/SHOW-PROPERTY.md
index 8eef274fa2d..9068a575b5c 100644
--- a/docs/en/docs/sql-manual/sql-reference/Show-Statements/SHOW-PROPERTY.md
+++ b/docs/en/docs/sql-manual/sql-reference/Show-Statements/SHOW-PROPERTY.md
@@ -31,7 +31,8 @@ under the License.
 This statement is used to view the attributes of the user
 
 ```
-SHOW PROPERTY [FOR user] [LIKE key];
+SHOW PROPERTY [FOR user] [LIKE key]
+SHOW ALL PROPERTIES [LIKE key]
 ```
 
 * `user`
@@ -42,6 +43,10 @@ SHOW PROPERTY [FOR user] [LIKE key];
 
     Fuzzy matching can be done by attribute name.
 
+* `ALL`
+
+  View the properties of all users (supported since version 2.0.3)
+
 Return result description:
 
 ```sql
@@ -62,6 +67,26 @@ mysql> show property like'%connection%';
 
     Attribute value.
 
+
+```sql
+mysql> show all properties like "%connection%";
++-------------------+--------------------------------------+
+| User              | Properties                           |
++-------------------+--------------------------------------+
+| root              | {"max_user_connections": "100"}      |
+| admin             | {"max_user_connections": "100"}      |
+| default_cluster:a | {"max_user_connections": "1000"}     |
++-------------------+--------------------------------------+
+```
+
+* `User`
+
+  username.
+
+* `Properties`
+
+  Key: value corresponding to each property of the user.
+
 ### Example
 
 1. View the attributes of the jack user
@@ -76,8 +101,14 @@ mysql> show property like'%connection%';
     SHOW PROPERTY FOR'jack' LIKE'%connection%';
     ```
 
+3. View all users importing cluster related properties
+
+   ```sql
+   SHOW ALL PROPERTIES LIKE '%load_cluster%'
+   ```
+
 ### Keywords
 
-    SHOW, PROPERTY
+    SHOW, PROPERTY, ALL
 
 ### Best Practice
diff --git 
a/docs/zh-CN/docs/sql-manual/sql-reference/Show-Statements/SHOW-PROPERTY.md 
b/docs/zh-CN/docs/sql-manual/sql-reference/Show-Statements/SHOW-PROPERTY.md
index 82ca0aa97d2..8f5685e2fe3 100644
--- a/docs/zh-CN/docs/sql-manual/sql-reference/Show-Statements/SHOW-PROPERTY.md
+++ b/docs/zh-CN/docs/sql-manual/sql-reference/Show-Statements/SHOW-PROPERTY.md
@@ -38,6 +38,7 @@ SHOW PROPERTY
 
 ```sql
 SHOW PROPERTY [FOR user] [LIKE key]
+SHOW ALL PROPERTIES [LIKE key]
 ```
 
 * `user`
@@ -48,6 +49,10 @@ SHOW PROPERTY [FOR user] [LIKE key]
 
    模糊匹配可以通过属性名来完成。
 
+* `ALL` 
+
+   查看所有用户的属性(从2.0.3版本开始支持)
+
 返回结果说明:
 
 ```sql
@@ -68,6 +73,26 @@ mysql> show property like'%connection%';
 
   属性值.
 
+
+```sql
+mysql> show all properties like "%connection%";
++-------------------+--------------------------------------+
+| User              | Properties                           |
++-------------------+--------------------------------------+
+| root              | {"max_user_connections": "100"}      |
+| admin             | {"max_user_connections": "100"}      |
+| default_cluster:a | {"max_user_connections": "1000"}     |
++-------------------+--------------------------------------+
+```
+
+* `User`
+
+  用户名.
+
+* `Properties`
+
+  对应用户各个property的key:value.
+
 ### Example
 
 1. 查看 jack 用户的属性
@@ -82,8 +107,14 @@ mysql> show property like'%connection%';
    SHOW PROPERTY FOR 'jack' LIKE '%load_cluster%'
    ```
 
+3. 查看所有用户导入cluster相关属性
+
+   ```sql
+   SHOW ALL PROPERTIES LIKE '%load_cluster%'
+   ```
+
 ### Keywords
 
-    SHOW, PROPERTY
+    SHOW, PROPERTY, ALL
 
 ### Best Practice
diff --git a/fe/fe-core/src/main/cup/sql_parser.cup 
b/fe/fe-core/src/main/cup/sql_parser.cup
index 930bbbbd97f..b0d487a6ca3 100644
--- a/fe/fe-core/src/main/cup/sql_parser.cup
+++ b/fe/fe-core/src/main/cup/sql_parser.cup
@@ -4122,7 +4122,11 @@ show_param ::=
     :}
     | KW_PROPERTY opt_user:user opt_wild_where
     {:
-        RESULT = new ShowUserPropertyStmt(user, parser.wild);
+        RESULT = new ShowUserPropertyStmt(user, parser.wild, false);
+    :}
+    | KW_ALL KW_PROPERTIES opt_wild_where
+    {:
+        RESULT = new ShowUserPropertyStmt(null, parser.wild, true);
     :}
     | KW_BACKUP opt_db:db opt_wild_where
     {:
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowUserPropertyStmt.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowUserPropertyStmt.java
index e6ed8f3670a..0c83376e048 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowUserPropertyStmt.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowUserPropertyStmt.java
@@ -30,39 +30,55 @@ import org.apache.doris.common.PatternMatcherWrapper;
 import org.apache.doris.common.UserException;
 import org.apache.doris.common.proc.UserPropertyProcNode;
 import org.apache.doris.mysql.privilege.PrivPredicate;
+import org.apache.doris.persist.gson.GsonUtils;
 import org.apache.doris.qe.ConnectContext;
 import org.apache.doris.qe.ShowResultSetMetaData;
 
 import com.google.common.base.Strings;
 import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 // Show Property Stmt
 //  syntax:
-//      SHOW PROPERTY [FOR user] [LIKE key pattern]
+//      SHOW [ALL] PROPERTY [FOR user] [LIKE key pattern]
 public class ShowUserPropertyStmt extends ShowStmt {
     private static final Logger LOG = 
LogManager.getLogger(ShowUserPropertyStmt.class);
 
     private String user;
     private String pattern;
+    private boolean isAll;
 
-    public ShowUserPropertyStmt(String user, String pattern) {
+    public ShowUserPropertyStmt(String user, String pattern, boolean isAll) {
         this.user = user;
         this.pattern = pattern;
+        this.isAll = isAll;
     }
 
     @Override
     public void analyze(Analyzer analyzer) throws AnalysisException, 
UserException {
         super.analyze(analyzer);
-        if (Strings.isNullOrEmpty(user)) {
-            user = analyzer.getQualifiedUser();
-            // user can see itself's property, no need to check privs
-        } else {
+        boolean needCheckAuth = true;
+        if (!Strings.isNullOrEmpty(user)) {
+            if (isAll) {
+                throw new AnalysisException("Can not specified keyword ALL 
when specified user");
+            }
             user = ClusterNamespace.getFullName(getClusterName(), user);
+        } else {
+            if (!isAll) {
+                // self
+                user = analyzer.getQualifiedUser();
+                // user can see itself's property, no need to check privs
+                needCheckAuth = false;
+            }
+        }
 
+        if (needCheckAuth) {
             if 
(!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ConnectContext.get(), 
PrivPredicate.GRANT)) {
                 
ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, 
"GRANT");
             }
@@ -72,6 +88,10 @@ public class ShowUserPropertyStmt extends ShowStmt {
     }
 
     public List<List<String>> getRows() throws AnalysisException {
+        return isAll ? getRowsForAllUser() : getRowsForOneUser();
+    }
+
+    public List<List<String>> getRowsForOneUser() throws AnalysisException {
         List<List<String>> rows = 
Env.getCurrentEnv().getAuth().getUserProperties(user);
 
         if (pattern == null) {
@@ -91,10 +111,42 @@ public class ShowUserPropertyStmt extends ShowStmt {
         return result;
     }
 
+    public List<List<String>> getRowsForAllUser() throws AnalysisException {
+        Set<String> allUser = Env.getCurrentEnv().getAuth().getAllUser();
+        List<List<String>> result = 
Lists.newArrayListWithCapacity(allUser.size());
+
+        for (String user : allUser) {
+            List<String> row = Lists.newArrayListWithCapacity(2);
+            row.add(user);
+            row.add(GsonUtils.GSON.toJson(getRowsForUser(user)));
+            result.add(row);
+        }
+        return result;
+    }
+
+    private Map<String, String> getRowsForUser(String user) throws 
AnalysisException {
+        Map<String, String> result = Maps.newHashMap();
+        List<List<String>> userProperties = Env.getCurrentEnv().getAuth()
+                
.getUserProperties(ClusterNamespace.getFullName(getClusterName(), user));
+        PatternMatcher matcher = null;
+        if (pattern != null) {
+            matcher = PatternMatcherWrapper.createMysqlPattern(pattern,
+                    CaseSensibility.USER.getCaseSensibility());
+        }
+
+        for (List<String> row : userProperties) {
+            String key = row.get(0).split("\\" + 
SetUserPropertyVar.DOT_SEPARATOR)[0];
+            if (matcher == null || matcher.match(key)) {
+                result.put(row.get(0), row.get(1));
+            }
+        }
+        return result;
+    }
+
     @Override
     public ShowResultSetMetaData getMetaData() {
         ShowResultSetMetaData.Builder builder = 
ShowResultSetMetaData.builder();
-        for (String col : UserPropertyProcNode.TITLE_NAMES) {
+        for (String col : isAll ? UserPropertyProcNode.ALL_USER_TITLE_NAMES : 
UserPropertyProcNode.TITLE_NAMES) {
             builder.addColumn(new Column(col, ScalarType.createVarchar(30)));
         }
         return builder.build();
@@ -103,10 +155,14 @@ public class ShowUserPropertyStmt extends ShowStmt {
     @Override
     public String toSql() {
         StringBuilder sb = new StringBuilder();
-        sb.append("SHOW PROPERTY FOR '");
-        sb.append(user);
-        sb.append("'");
-
+        sb.append("SHOW ");
+        if (isAll) {
+            sb.append("ALL PROPERTIES");
+        } else {
+            sb.append("PROPERTY FOR '");
+            sb.append(user);
+            sb.append("'");
+        }
         if (pattern != null) {
             sb.append(" LIKE '");
             sb.append(pattern);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/common/proc/UserPropertyProcNode.java
 
b/fe/fe-core/src/main/java/org/apache/doris/common/proc/UserPropertyProcNode.java
index 6a8c9eaec3f..db4ad520be4 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/common/proc/UserPropertyProcNode.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/common/proc/UserPropertyProcNode.java
@@ -31,6 +31,10 @@ public class UserPropertyProcNode implements 
ProcNodeInterface {
             .add("Key").add("Value")
             .build();
 
+    public static final ImmutableList<String> ALL_USER_TITLE_NAMES = new 
ImmutableList.Builder<String>()
+            .add("User").add("Properties")
+            .build();
+
     private Auth auth;
     private UserIdentity userIdent;
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java
index 9ebf6075aed..d07ba404c25 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java
@@ -1581,6 +1581,9 @@ public class Auth implements Writable {
         userRoleManager.addUserRole(userIdent, 
roleManager.getUserDefaultRoleName(userIdent));
     }
 
+    public Set<String> getAllUser() {
+        return userManager.getNameToUsers().keySet();
+    }
 
     /**
      * This is a bug that if created a normal user and grant it with 
ADMIN_PRIV/RESOURCE_PRIV/NODE_PRIV
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/analysis/ShowUserPropertyStmtTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/analysis/ShowUserPropertyStmtTest.java
index 3e88d9884fb..53b63a568b0 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/analysis/ShowUserPropertyStmtTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/analysis/ShowUserPropertyStmtTest.java
@@ -17,8 +17,9 @@
 
 package org.apache.doris.analysis;
 
-import org.apache.doris.common.AnalysisException;
+import org.apache.doris.catalog.Column;
 import org.apache.doris.common.UserException;
+import org.apache.doris.common.proc.UserPropertyProcNode;
 import org.apache.doris.mysql.privilege.AccessControllerManager;
 import org.apache.doris.mysql.privilege.MockedAuth;
 import org.apache.doris.qe.ConnectContext;
@@ -28,6 +29,8 @@ import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
+import java.util.List;
+
 public class ShowUserPropertyStmtTest {
     private Analyzer analyzer;
 
@@ -44,9 +47,36 @@ public class ShowUserPropertyStmtTest {
     }
 
     @Test
-    public void testNormal() throws UserException, AnalysisException {
-        ShowUserPropertyStmt stmt = new ShowUserPropertyStmt("testUser", 
"%load_cluster%");
+    public void testNormal() throws UserException {
+        ShowUserPropertyStmt stmt = new ShowUserPropertyStmt("testUser", 
"%load_cluster%", false);
         stmt.analyze(analyzer);
         Assert.assertEquals("SHOW PROPERTY FOR 'testCluster:testUser' LIKE 
'%load_cluster%'", stmt.toString());
+        List<Column> columns = stmt.getMetaData().getColumns();
+        for (int i = 0; i < columns.size(); i++) {
+            Assert.assertEquals(columns.get(i).getName(), 
UserPropertyProcNode.TITLE_NAMES.get(i));
+        }
+    }
+
+    @Test
+    public void testAll() throws UserException {
+        ShowUserPropertyStmt stmt = new ShowUserPropertyStmt(null, 
"%load_cluster%", true);
+        stmt.analyze(analyzer);
+        Assert.assertEquals("SHOW ALL PROPERTIES LIKE '%load_cluster%'", 
stmt.toString());
+        List<Column> columns = stmt.getMetaData().getColumns();
+        for (int i = 0; i < columns.size(); i++) {
+            Assert.assertEquals(columns.get(i).getName(), 
UserPropertyProcNode.ALL_USER_TITLE_NAMES.get(i));
+        }
+    }
+
+    @Test
+    public void testError() {
+        ShowUserPropertyStmt stmt = new ShowUserPropertyStmt("testUser", 
"%load_cluster%", true);
+        try {
+            stmt.analyze(analyzer);
+            Assert.fail();
+        } catch (UserException e) {
+            Assert.assertTrue(e.getMessage().contains("ALL"));
+        }
+
     }
 }


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

Reply via email to