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

starocean999 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 c37fbe52ef9 [Enhancement] (nereids)implement showUserPropertiesCommand 
and showAllPropertiesCommand in nereids (#45145)
c37fbe52ef9 is described below

commit c37fbe52ef96ede5039efbd546395e1c34150505
Author: Sridhar R Manikarnike <sridhar.n...@gmail.com>
AuthorDate: Thu Jan 2 07:03:29 2025 +0530

    [Enhancement] (nereids)implement showUserPropertiesCommand and 
showAllPropertiesCommand in nereids (#45145)
    
    Issue Number: close #42759 close #42760
---
 .../antlr4/org/apache/doris/nereids/DorisParser.g4 |   4 +-
 .../doris/nereids/parser/LogicalPlanBuilder.java   |  22 +++
 .../apache/doris/nereids/trees/plans/PlanType.java |   1 +
 .../plans/commands/ShowUserPropertyCommand.java    | 161 +++++++++++++++++++++
 .../trees/plans/visitor/CommandVisitor.java        |   5 +
 .../show/test_show_user_properties_command.groovy  |  48 ++++++
 6 files changed, 239 insertions(+), 2 deletions(-)

diff --git a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 
b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
index 8a4490bda83..907c25cfe2d 100644
--- a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
+++ b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
@@ -272,6 +272,8 @@ supportedShowStatement
     | SHOW FILE ((FROM | IN) database=multipartIdentifier)?                    
     #showSmallFiles 
     | SHOW STORAGE? ENGINES                                                    
     #showStorageEngines
     | SHOW CREATE CATALOG name=identifier                                      
     #showCreateCatalog
+    | SHOW PROPERTY (FOR user=identifierOrText)? (LIKE STRING_LITERAL)?        
                 #showUserProperties
+    | SHOW ALL PROPERTIES (LIKE STRING_LITERAL)?                               
                #showAllProperties
     | SHOW COLLATION wildWhere?                                                
     #showCollation
     | SHOW SQL_BLOCK_RULE (FOR ruleName=identifier)?                           
     #showSqlBlockRule
     | SHOW CREATE VIEW name=multipartIdentifier                                
     #showCreateView
@@ -368,8 +370,6 @@ unsupportedShowStatement
     | SHOW TABLET tabletId=INTEGER_VALUE                                       
     #showTabletId
     | SHOW TABLETS FROM tableName=multipartIdentifier partitionSpec?
         wildWhere? sortClause? limitClause?                                    
     #showTabletsFromTable
-    | SHOW PROPERTY (FOR user=identifierOrText)? wildWhere?                    
     #showUserProperties
-    | SHOW ALL PROPERTIES wildWhere?                                           
     #showAllProperties
     | SHOW BACKUP ((FROM | IN) database=multipartIdentifier)? wildWhere?       
     #showBackup
     | SHOW BRIEF? RESTORE ((FROM | IN) database=multipartIdentifier)? 
wildWhere?    #showRestore
     | SHOW RESOURCES wildWhere? sortClause? limitClause?                       
     #showResources
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
index f33d414eda6..82c8be68e48 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
@@ -267,6 +267,7 @@ import 
org.apache.doris.nereids.DorisParser.SetTransactionContext;
 import org.apache.doris.nereids.DorisParser.SetUserPropertiesContext;
 import org.apache.doris.nereids.DorisParser.SetUserVariableContext;
 import org.apache.doris.nereids.DorisParser.SetVariableWithTypeContext;
+import org.apache.doris.nereids.DorisParser.ShowAllPropertiesContext;
 import org.apache.doris.nereids.DorisParser.ShowAuthorsContext;
 import org.apache.doris.nereids.DorisParser.ShowBackendsContext;
 import org.apache.doris.nereids.DorisParser.ShowBrokerContext;
@@ -316,6 +317,7 @@ import 
org.apache.doris.nereids.DorisParser.ShowTabletStorageFormatContext;
 import org.apache.doris.nereids.DorisParser.ShowTabletsBelongContext;
 import org.apache.doris.nereids.DorisParser.ShowTrashContext;
 import org.apache.doris.nereids.DorisParser.ShowTriggersContext;
+import org.apache.doris.nereids.DorisParser.ShowUserPropertiesContext;
 import org.apache.doris.nereids.DorisParser.ShowVariablesContext;
 import org.apache.doris.nereids.DorisParser.ShowViewContext;
 import org.apache.doris.nereids.DorisParser.ShowWarningErrorCountContext;
@@ -599,6 +601,7 @@ import 
org.apache.doris.nereids.trees.plans.commands.ShowTabletStorageFormatComm
 import org.apache.doris.nereids.trees.plans.commands.ShowTabletsBelongCommand;
 import org.apache.doris.nereids.trees.plans.commands.ShowTrashCommand;
 import org.apache.doris.nereids.trees.plans.commands.ShowTriggersCommand;
+import org.apache.doris.nereids.trees.plans.commands.ShowUserPropertyCommand;
 import org.apache.doris.nereids.trees.plans.commands.ShowVariablesCommand;
 import org.apache.doris.nereids.trees.plans.commands.ShowViewCommand;
 import 
org.apache.doris.nereids.trees.plans.commands.ShowWarningErrorCountCommand;
@@ -5021,6 +5024,25 @@ public class LogicalPlanBuilder extends 
DorisParserBaseVisitor<Object> {
         return new ShowWhiteListCommand();
     }
 
+    @Override
+    public LogicalPlan visitShowUserProperties(ShowUserPropertiesContext ctx) {
+        String user = ctx.user != null ? stripQuotes(ctx.user.getText()) : 
null;
+        String pattern = null;
+        if (ctx.LIKE() != null) {
+            pattern = stripQuotes(ctx.STRING_LITERAL().getText());
+        }
+        return new ShowUserPropertyCommand(user, pattern, false);
+    }
+
+    @Override
+    public LogicalPlan visitShowAllProperties(ShowAllPropertiesContext ctx) {
+        String pattern = null;
+        if (ctx.LIKE() != null) {
+            pattern = stripQuotes(ctx.STRING_LITERAL().getText());
+        }
+        return new ShowUserPropertyCommand(null, pattern, true);
+    }
+
     @Override
     public LogicalPlan visitAlterCatalogComment(AlterCatalogCommentContext 
ctx) {
         String catalogName = stripQuotes(ctx.name.getText());
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java
index 9c7c82a337c..c90734ce8a7 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java
@@ -252,6 +252,7 @@ public enum PlanType {
     SHOW_TRIGGERS_COMMAND,
     SHOW_VARIABLES_COMMAND,
     SHOW_AUTHORS_COMMAND,
+    SHOW_USER_PROPERTY_COMMAND,
     SHOW_VIEW_COMMAND,
     SHOW_WARNING_ERRORS_COMMAND,
     SHOW_WARNING_ERROR_COUNT_COMMAND,
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowUserPropertyCommand.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowUserPropertyCommand.java
new file mode 100644
index 00000000000..edc3f03f6f4
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowUserPropertyCommand.java
@@ -0,0 +1,161 @@
+// 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.nereids.trees.plans.commands;
+
+import org.apache.doris.analysis.SetUserPropertyVar;
+import org.apache.doris.catalog.Column;
+import org.apache.doris.catalog.Env;
+import org.apache.doris.catalog.ScalarType;
+import org.apache.doris.common.AnalysisException;
+import org.apache.doris.common.CaseSensibility;
+import org.apache.doris.common.ErrorCode;
+import org.apache.doris.common.ErrorReport;
+import org.apache.doris.common.PatternMatcher;
+import org.apache.doris.common.PatternMatcherWrapper;
+import org.apache.doris.common.proc.UserPropertyProcNode;
+import org.apache.doris.mysql.privilege.PrivPredicate;
+import org.apache.doris.nereids.trees.plans.PlanType;
+import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
+import org.apache.doris.persist.gson.GsonUtils;
+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 com.google.common.base.Strings;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Represents the command for SHOW ALL/USER PROPERTIES COMMAND.
+ */
+public class ShowUserPropertyCommand extends ShowCommand {
+    private String user;
+    private String pattern;
+    private boolean isAll;
+
+    public ShowUserPropertyCommand(String user, String pattern, boolean isAll) 
{
+        super(PlanType.SHOW_USER_PROPERTY_COMMAND);
+        this.user = user;
+        this.pattern = pattern;
+        this.isAll = isAll;
+    }
+
+    private void validate(ConnectContext ctx) throws AnalysisException {
+        boolean needCheckAuth = true;
+        if (!Strings.isNullOrEmpty(user)) {
+            if (isAll) {
+                throw new AnalysisException("Can not specified keyword ALL 
when specified user");
+            }
+        } else {
+            if (!isAll) {
+                // self
+                user = ctx.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");
+            }
+        }
+
+        pattern = Strings.emptyToNull(pattern);
+    }
+
+    @Override
+    public <R, C> R accept(PlanVisitor<R, C> visitor, C context) {
+        return visitor.visitShowUserPropertyCommand(this, context);
+    }
+
+    @Override
+    public ShowResultSet doRun(ConnectContext ctx, StmtExecutor executor) 
throws Exception {
+        validate(ctx);
+        return new ShowResultSet(getMetaData(), getRows());
+    }
+
+    private List<List<String>> getRows() throws AnalysisException {
+        return isAll ? getRowsForAllUser() : getRowsForOneUser();
+    }
+
+    private List<List<String>> getRowsForOneUser() throws AnalysisException {
+        List<List<String>> rows = 
Env.getCurrentEnv().getAuth().getUserProperties(user);
+
+        if (pattern == null) {
+            return rows;
+        }
+
+        List<List<String>> result = Lists.newArrayList();
+        PatternMatcher matcher = 
PatternMatcherWrapper.createMysqlPattern(pattern,
+                CaseSensibility.USER.getCaseSensibility());
+        for (List<String> row : rows) {
+            String key = row.get(0).split("\\" + 
SetUserPropertyVar.DOT_SEPARATOR)[0];
+            if (matcher.match(key)) {
+                result.add(row);
+            }
+        }
+
+        return result;
+    }
+
+    private 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(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;
+    }
+
+    public ShowResultSetMetaData getMetaData() {
+        ShowResultSetMetaData.Builder builder = 
ShowResultSetMetaData.builder();
+        for (String col : isAll ? UserPropertyProcNode.ALL_USER_TITLE_NAMES : 
UserPropertyProcNode.TITLE_NAMES) {
+            builder.addColumn(new Column(col, ScalarType.createVarchar(30)));
+        }
+        return builder.build();
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/CommandVisitor.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/CommandVisitor.java
index c0be169ef30..e7f9660ebef 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/CommandVisitor.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/CommandVisitor.java
@@ -138,6 +138,7 @@ import 
org.apache.doris.nereids.trees.plans.commands.ShowTabletStorageFormatComm
 import org.apache.doris.nereids.trees.plans.commands.ShowTabletsBelongCommand;
 import org.apache.doris.nereids.trees.plans.commands.ShowTrashCommand;
 import org.apache.doris.nereids.trees.plans.commands.ShowTriggersCommand;
+import org.apache.doris.nereids.trees.plans.commands.ShowUserPropertyCommand;
 import org.apache.doris.nereids.trees.plans.commands.ShowVariablesCommand;
 import org.apache.doris.nereids.trees.plans.commands.ShowViewCommand;
 import 
org.apache.doris.nereids.trees.plans.commands.ShowWarningErrorCountCommand;
@@ -682,6 +683,10 @@ public interface CommandVisitor<R, C> {
         return visitCommand(showPrivilegesCommand, context);
     }
 
+    default R visitShowUserPropertyCommand(ShowUserPropertyCommand 
showUserpropertyCommand, C context) {
+        return visitCommand(showUserpropertyCommand, context);
+    }
+
     default R visitShowTabletsBelongCommand(ShowTabletsBelongCommand 
showTabletBelongCommand, C context) {
         return visitCommand(showTabletBelongCommand, context);
     }
diff --git 
a/regression-test/suites/nereids_p0/show/test_show_user_properties_command.groovy
 
b/regression-test/suites/nereids_p0/show/test_show_user_properties_command.groovy
new file mode 100644
index 00000000000..be11af1596e
--- /dev/null
+++ 
b/regression-test/suites/nereids_p0/show/test_show_user_properties_command.groovy
@@ -0,0 +1,48 @@
+// 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.
+
+suite("test_show_user_properties_command", "query,nereids") {
+    def currentUser = "root"
+
+    // Test SHOW PROPERTY FOR USER command
+    try {
+        checkNereidsExecute("""SHOW PROPERTY FOR USER ${currentUser};""")
+    } catch (Exception e) {
+        log.error("Failed to execute SHOW PROPERTY FOR USER command", e)
+    }
+
+    // Test SHOW PROPERTY FOR USER command with wildWhere condition
+    try {
+        checkNereidsExecute("""SHOW PROPERTY FOR USER ${currentUser} LIKE 
'property_name%';""")
+    } catch (Exception e) {
+        log.error("Failed to execute SHOW PROPERTY FOR USER command with LIKE 
clause", e)
+    }
+
+    // Test SHOW ALL PROPERTIES command
+    try {
+        checkNereidsExecute("""SHOW ALL PROPERTIES;""")
+    } catch (Exception e) {
+        log.error("Failed to execute SHOW ALL PROPERTIES command", e)
+    }
+
+    // Test SHOW ALL PROPERTIES with wildWhere condition
+    try {
+        checkNereidsExecute("""SHOW ALL PROPERTIES LIKE 'property%';""")
+    } catch (Exception e) {
+        log.error("Failed to execute SHOW ALL PROPERTIES command with LIKE 
clause", e)
+    }
+}


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

Reply via email to