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

morningman 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 a9258adf225 branch-4.1: [fix](functions) Fix privilege control for 
SHOW BUILTIN FUNCTIONS to treat builtin functions as system-level (#60215) 
(#61400)
a9258adf225 is described below

commit a9258adf225e7e9c6009ecbb136e6ef159458e2f
Author: Mingyu Chen (Rayner) <[email protected]>
AuthorDate: Mon Mar 16 14:52:20 2026 -0700

    branch-4.1: [fix](functions) Fix privilege control for SHOW BUILTIN 
FUNCTIONS to treat builtin functions as system-level (#60215) (#61400)
    
    bp #60215
    
    Co-authored-by: heguanhui <[email protected]>
---
 .../antlr4/org/apache/doris/nereids/DorisParser.g4 |   3 +-
 .../doris/nereids/parser/LogicalPlanBuilder.java   |  15 +-
 .../apache/doris/nereids/trees/plans/PlanType.java |   1 +
 ...mmand.java => ShowBuiltinFunctionsCommand.java} | 200 +++++++--------------
 .../trees/plans/commands/ShowFunctionsCommand.java |  27 ++-
 .../trees/plans/visitor/CommandVisitor.java        |   5 +
 .../commands/ShowBuiltinFunctionsCommandTest.java  | 103 +++++++++++
 .../plans/commands/ShowFunctionsCommandTest.java   |  49 ++---
 .../show/test_nereids_show_functions.groovy        |  32 ++--
 9 files changed, 231 insertions(+), 204 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 a07f8854090..d97bb9d3fd4 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
@@ -382,9 +382,10 @@ supportedShowStatement
     | SHOW CREATE statementScope? FUNCTION functionIdentifier
         LEFT_PAREN functionArguments? RIGHT_PAREN
         ((FROM | IN) database=multipartIdentifier)?                            
     #showCreateFunction
-    | SHOW FULL? BUILTIN? FUNCTIONS
+    | SHOW FULL? FUNCTIONS
         ((FROM | IN) database=multipartIdentifier)? (LIKE STRING_LITERAL)?     
     #showFunctions
     | SHOW GLOBAL FULL? FUNCTIONS (LIKE STRING_LITERAL)?                       
     #showGlobalFunctions
+    | SHOW FULL? BUILTIN FUNCTIONS (LIKE STRING_LITERAL)?                      
     #showBuiltinFunctions
     | SHOW ALL? GRANTS                                                         
     #showGrants
     | SHOW GRANTS FOR userIdentify                                             
     #showGrantsForUser
     | SHOW CREATE USER userIdentify                                            
     #showCreateUser
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 e0a05bfa8c2..452af0bd989 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
@@ -362,6 +362,7 @@ import 
org.apache.doris.nereids.DorisParser.ShowBackendsContext;
 import org.apache.doris.nereids.DorisParser.ShowBackupContext;
 import org.apache.doris.nereids.DorisParser.ShowBrokerContext;
 import org.apache.doris.nereids.DorisParser.ShowBuildIndexContext;
+import org.apache.doris.nereids.DorisParser.ShowBuiltinFunctionsContext;
 import org.apache.doris.nereids.DorisParser.ShowCatalogRecycleBinContext;
 import org.apache.doris.nereids.DorisParser.ShowCharsetContext;
 import org.apache.doris.nereids.DorisParser.ShowClustersContext;
@@ -784,6 +785,7 @@ import 
org.apache.doris.nereids.trees.plans.commands.ShowBackendsCommand;
 import org.apache.doris.nereids.trees.plans.commands.ShowBackupCommand;
 import org.apache.doris.nereids.trees.plans.commands.ShowBrokerCommand;
 import org.apache.doris.nereids.trees.plans.commands.ShowBuildIndexCommand;
+import 
org.apache.doris.nereids.trees.plans.commands.ShowBuiltinFunctionsCommand;
 import org.apache.doris.nereids.trees.plans.commands.ShowCatalogCommand;
 import 
org.apache.doris.nereids.trees.plans.commands.ShowCatalogRecycleBinCommand;
 import org.apache.doris.nereids.trees.plans.commands.ShowCharsetCommand;
@@ -6841,13 +6843,22 @@ public class LogicalPlanBuilder extends 
DorisParserBaseVisitor<Object> {
         }
 
         boolean isVerbose = ctx.FULL() != null;
-        boolean isBuiltin = ctx.BUILTIN() != null;
 
         String wild = null;
         if (ctx.STRING_LITERAL() != null) {
             wild = stripQuotes(ctx.STRING_LITERAL().getText());
         }
-        return new ShowFunctionsCommand(dbName, isBuiltin, isVerbose, wild);
+        return new ShowFunctionsCommand(dbName, isVerbose, wild);
+    }
+
+    @Override
+    public LogicalPlan visitShowBuiltinFunctions(ShowBuiltinFunctionsContext 
ctx) {
+        boolean isVerbose = ctx.FULL() != null;
+        String wild = null;
+        if (ctx.STRING_LITERAL() != null) {
+            wild = stripQuotes(ctx.STRING_LITERAL().getText());
+        }
+        return new ShowBuiltinFunctionsCommand(isVerbose, wild);
     }
 
     @Override
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 73e6fb602af..dba97409302 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
@@ -294,6 +294,7 @@ public enum PlanType {
     SHOW_FRONTENDS_COMMAND,
     SHOW_FUNCTIONS_COMMAND,
     SHOW_GLOBAL_FUNCTIONS_COMMAND,
+    SHOW_BUILTIN_FUNCTIONS_COMMAND,
     SHOW_GRANTS_COMMAND,
     SHOW_INDEX_COMMAND,
     SHOW_INDEX_STATS_COMMAND,
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowFunctionsCommand.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowBuiltinFunctionsCommand.java
similarity index 58%
copy from 
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowFunctionsCommand.java
copy to 
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowBuiltinFunctionsCommand.java
index f9913fc5ada..16fe6fc7682 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowFunctionsCommand.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowBuiltinFunctionsCommand.java
@@ -17,20 +17,16 @@
 
 package org.apache.doris.nereids.trees.plans.commands;
 
-import org.apache.doris.analysis.SetType;
 import org.apache.doris.catalog.Column;
-import org.apache.doris.catalog.Database;
-import org.apache.doris.catalog.DatabaseIf;
 import org.apache.doris.catalog.Env;
 import org.apache.doris.catalog.FunctionRegistry;
-import org.apache.doris.catalog.FunctionUtil;
+import org.apache.doris.catalog.InfoSchemaDb;
 import org.apache.doris.catalog.ScalarType;
 import org.apache.doris.common.AnalysisException;
 import org.apache.doris.common.ErrorCode;
 import org.apache.doris.common.ErrorReport;
 import org.apache.doris.common.util.ListComparator;
 import org.apache.doris.common.util.OrderByPair;
-import org.apache.doris.common.util.Util;
 import org.apache.doris.datasource.InternalCatalog;
 import org.apache.doris.mysql.privilege.PrivPredicate;
 import org.apache.doris.nereids.trees.expressions.functions.FunctionBuilder;
@@ -42,21 +38,20 @@ import org.apache.doris.qe.ShowResultSetMetaData;
 import org.apache.doris.qe.StmtExecutor;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Strings;
 import com.google.common.collect.Lists;
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 /**
- * show functions command
+ * show builtin functions command
  */
-public class ShowFunctionsCommand extends ShowCommand {
+public class ShowBuiltinFunctionsCommand extends ShowCommand {
+
     private static final ShowResultSetMetaData META_DATA =
             ShowResultSetMetaData.builder()
                 .addColumn(new Column("Signature", ScalarType.STRING))
@@ -65,74 +60,89 @@ public class ShowFunctionsCommand extends ShowCommand {
                 .addColumn(new Column("Intermediate Type", ScalarType.STRING))
                 .addColumn(new Column("Properties", ScalarType.STRING))
                 .build();
-
-    private String dbName;
-    private boolean isBuiltin;
     private boolean isVerbose;
     private String likeCondition;
-    private SetType type = SetType.DEFAULT;
 
-    /**
-     * constructor
-     */
-    public ShowFunctionsCommand(String dbName, boolean isBuiltin, boolean 
isVerbose, String likeCondition) {
-        super(PlanType.SHOW_FUNCTIONS_COMMAND);
-        this.dbName = dbName;
-        this.isBuiltin = isBuiltin;
+    public ShowBuiltinFunctionsCommand(boolean isVerbose, String 
likeCondition) {
+        super(PlanType.SHOW_BUILTIN_FUNCTIONS_COMMAND);
         this.isVerbose = isVerbose;
         this.likeCondition = likeCondition;
     }
 
+    @Override
+    public ShowResultSetMetaData getMetaData() {
+        if (isVerbose) {
+            return META_DATA;
+        }
+        return ShowResultSetMetaData.builder().addColumn(new Column("Function 
Name", ScalarType.STRING)).build();
+    }
+
+    @Override
+    public ShowResultSet doRun(ConnectContext ctx, StmtExecutor executor) 
throws Exception {
+        return handleShowBuiltinFunctions(ctx, executor);
+    }
+
+    @Override
+    public <R, C> R accept(PlanVisitor<R, C> visitor, C context) {
+        return visitor.visitShowBuiltinFunctionsCommand(this, context);
+    }
+
     /**
-     * constructor for global functions
+     * handle show builtin functions
      */
-    public ShowFunctionsCommand(boolean isVerbose, String likeCondition, 
boolean isGlobal) {
-        super(PlanType.SHOW_GLOBAL_FUNCTIONS_COMMAND);
-        this.isVerbose = isVerbose;
-        this.likeCondition = likeCondition;
-        if (isGlobal) {
-            this.type = SetType.GLOBAL;
+    @VisibleForTesting
+    protected ShowResultSet handleShowBuiltinFunctions(ConnectContext ctx, 
StmtExecutor executor) throws Exception {
+        // show builtin functions only need information_schema priv
+        if 
(!Env.getCurrentEnv().getAccessManager().checkDbPriv(ConnectContext.get(),
+                InternalCatalog.INTERNAL_CATALOG_NAME, 
InfoSchemaDb.DATABASE_NAME, PrivPredicate.SELECT)) {
+            
ErrorReport.reportAnalysisException(ErrorCode.ERR_DB_ACCESS_DENIED_ERROR,
+                    PrivPredicate.SELECT.getPrivs().toString(), 
InfoSchemaDb.DATABASE_NAME);
         }
+        List<List<String>> resultRowSet = getResultRowSet(ctx);
+        ShowResultSetMetaData showMetaData = getMetaData();
+        return new ShowResultSet(showMetaData, resultRowSet);
     }
 
     /***
-     * get Info by nereids.
-     * To make the code in nereids more concise, all irrelevant information 
here will use an empty string.
+     * get resultRowSet
      */
-    private List<Comparable> getInfo(boolean isVerbose, String funcName) {
-        List<Comparable> row = Lists.newArrayList();
-        if (isVerbose) {
-            // signature
-            row.add(funcName);
-            // return type
-            row.add("");
-            // function type
-            // intermediate type
-            row.add("");
-            row.add("");
-            // property
-            row.add("");
-        } else {
-            row.add(funcName);
-        }
-        return row;
+    private List<List<String>> getResultRowSet(ConnectContext ctx) throws 
AnalysisException {
+        List<String> functions = getFunctions(ctx);
+        return getResultRowSetByFunctions(functions);
     }
 
     @VisibleForTesting
-    protected boolean like(String funcName, String likeCondition) {
-        funcName = funcName.toLowerCase();
-        return funcName.matches(likeCondition.replace(".", "\\.").replace("?", 
".").replace("%", ".*").toLowerCase());
+    protected List<String> getFunctions(ConnectContext ctx) throws 
AnalysisException {
+        List<String> functions = Lists.newArrayList();
+        if (ctx == null || ctx.getEnv() == null || 
ctx.getEnv().getFunctionRegistry() == null) {
+            return functions;
+        }
+        FunctionRegistry functionRegistry = ctx.getEnv().getFunctionRegistry();
+        Map<String, List<FunctionBuilder>> builtinFunctions = 
functionRegistry.getName2BuiltinBuilders();
+        functions = new ArrayList<>(builtinFunctions.keySet());
+        return functions;
     }
 
-    /***
-     * get resultRowSet
-     */
     @VisibleForTesting
     protected List<List<String>> getResultRowSetByFunctions(List<String> 
functions) {
         List<List<String>> resultRowSet = Lists.newArrayList();
         List<List<Comparable>> rowSet = Lists.newArrayList();
         for (String function : functions) {
-            List<Comparable> row = getInfo(isVerbose, function);
+            List<Comparable> row = Lists.newArrayList();
+            if (isVerbose) {
+                // signature
+                row.add(function);
+                // return type
+                row.add("");
+                // function type
+                row.add("");
+                // intermediate type
+                row.add("");
+                // property
+                row.add("");
+            } else {
+                row.add(function);
+            }
             // like predicate
             if (likeCondition == null || like(function, likeCondition)) {
                 rowSet.add(row);
@@ -161,88 +171,10 @@ public class ShowFunctionsCommand extends ShowCommand {
         return resultRowSet;
     }
 
-    /***
-     * get resultRowSet
-     */
-    private List<List<String>> getResultRowSet(ConnectContext ctx) throws 
AnalysisException {
-        List<String> functions = getFunctions(ctx);
-        return getResultRowSetByFunctions(functions);
-    }
-
-    /***
-     * get functions by nereids.
-     * All functions including builtin and udf are registered in 
FunctionRegistry
-     */
-    @VisibleForTesting
-    protected List<String> getFunctions(ConnectContext ctx) throws 
AnalysisException {
-        List<String> functions = Lists.newArrayList();
-        if (ctx == null || ctx.getEnv() == null || 
ctx.getEnv().getFunctionRegistry() == null) {
-            return functions;
-        }
-
-        FunctionRegistry functionRegistry = ctx.getEnv().getFunctionRegistry();
-        Map<String, Map<String, List<FunctionBuilder>>> udfFunctions = 
functionRegistry.getName2UdfBuilders();
-        if (!FunctionUtil.isGlobalFunction(type)) {
-            Util.prohibitExternalCatalog(ctx.getDefaultCatalog(), 
this.getClass().getSimpleName());
-            DatabaseIf db = 
ctx.getCurrentCatalog().getDbOrAnalysisException(dbName);
-            if (db instanceof Database) {
-                Map<String, List<FunctionBuilder>> builtinFunctions = 
functionRegistry.getName2BuiltinBuilders();
-                functions = isBuiltin ? new 
ArrayList<>(builtinFunctions.keySet()) :
-                        new ArrayList<>(udfFunctions.getOrDefault(dbName, new 
HashMap<>()).keySet());
-            }
-        } else {
-            functions = new ArrayList<>(udfFunctions
-                .getOrDefault(functionRegistry.getGlobalFunctionDbName(), new 
HashMap<>()).keySet());
-        }
-        return functions;
-    }
-
-    private static String reAcquireDbName(ConnectContext ctx, String dbName) 
throws AnalysisException {
-        if (Strings.isNullOrEmpty(dbName)) {
-            dbName = ctx.getDatabase();
-            if (Strings.isNullOrEmpty(dbName)) {
-                ErrorReport.reportAnalysisException(ErrorCode.ERR_NO_DB_ERROR);
-            }
-        }
-        return dbName;
-    }
-
-    public ShowResultSetMetaData getMetaData() {
-        if (isVerbose) {
-            return META_DATA;
-        }
-        return ShowResultSetMetaData.builder().addColumn(new Column("Function 
Name", ScalarType.STRING)).build();
-    }
-
-    /**
-     * handle show functions
-     */
     @VisibleForTesting
-    protected ShowResultSet handleShowFunctions(ConnectContext ctx, 
StmtExecutor executor) throws Exception {
-        if (!FunctionUtil.isGlobalFunction(type)) {
-            this.dbName = reAcquireDbName(ctx, dbName);
-        }
-
-        if (!FunctionUtil.isGlobalFunction(type) && 
!Env.getCurrentEnv().getAccessManager()
-                .checkDbPriv(ConnectContext.get(), 
InternalCatalog.INTERNAL_CATALOG_NAME, dbName, PrivPredicate.SHOW)) {
-            
ErrorReport.reportAnalysisException(ErrorCode.ERR_DBACCESS_DENIED_ERROR,
-                    ConnectContext.get().getQualifiedUser(), dbName);
-        }
-
-        List<List<String>> resultRowSet = getResultRowSet(ctx);
-        // Only success
-        ShowResultSetMetaData showMetaData = getMetaData();
-        return new ShowResultSet(showMetaData, resultRowSet);
-    }
-
-    @Override
-    public ShowResultSet doRun(ConnectContext ctx, StmtExecutor executor) 
throws Exception {
-        return handleShowFunctions(ctx, executor);
-    }
-
-    @Override
-    public <R, C> R accept(PlanVisitor<R, C> visitor, C context) {
-        return visitor.visitShowFunctionsCommand(this, context);
+    protected boolean like(String funcName, String likeCondition) {
+        funcName = funcName.toLowerCase();
+        return funcName.matches(likeCondition.replace(".", "\\.").replace("?", 
".").replace("%", ".*").toLowerCase());
     }
 
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowFunctionsCommand.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowFunctionsCommand.java
index f9913fc5ada..881f188456b 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowFunctionsCommand.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowFunctionsCommand.java
@@ -67,7 +67,6 @@ public class ShowFunctionsCommand extends ShowCommand {
                 .build();
 
     private String dbName;
-    private boolean isBuiltin;
     private boolean isVerbose;
     private String likeCondition;
     private SetType type = SetType.DEFAULT;
@@ -75,10 +74,9 @@ public class ShowFunctionsCommand extends ShowCommand {
     /**
      * constructor
      */
-    public ShowFunctionsCommand(String dbName, boolean isBuiltin, boolean 
isVerbose, String likeCondition) {
+    public ShowFunctionsCommand(String dbName, boolean isVerbose, String 
likeCondition) {
         super(PlanType.SHOW_FUNCTIONS_COMMAND);
         this.dbName = dbName;
-        this.isBuiltin = isBuiltin;
         this.isVerbose = isVerbose;
         this.likeCondition = likeCondition;
     }
@@ -182,17 +180,16 @@ public class ShowFunctionsCommand extends ShowCommand {
 
         FunctionRegistry functionRegistry = ctx.getEnv().getFunctionRegistry();
         Map<String, Map<String, List<FunctionBuilder>>> udfFunctions = 
functionRegistry.getName2UdfBuilders();
-        if (!FunctionUtil.isGlobalFunction(type)) {
+        if (FunctionUtil.isGlobalFunction(type)) {
+            // handle show global functions
+            functions = new ArrayList<>(udfFunctions
+                .getOrDefault(functionRegistry.getGlobalFunctionDbName(), new 
HashMap<>()).keySet());
+        } else {
             Util.prohibitExternalCatalog(ctx.getDefaultCatalog(), 
this.getClass().getSimpleName());
             DatabaseIf db = 
ctx.getCurrentCatalog().getDbOrAnalysisException(dbName);
             if (db instanceof Database) {
-                Map<String, List<FunctionBuilder>> builtinFunctions = 
functionRegistry.getName2BuiltinBuilders();
-                functions = isBuiltin ? new 
ArrayList<>(builtinFunctions.keySet()) :
-                        new ArrayList<>(udfFunctions.getOrDefault(dbName, new 
HashMap<>()).keySet());
+                functions = new ArrayList<>(udfFunctions.getOrDefault(dbName, 
new HashMap<>()).keySet());
             }
-        } else {
-            functions = new ArrayList<>(udfFunctions
-                .getOrDefault(functionRegistry.getGlobalFunctionDbName(), new 
HashMap<>()).keySet());
         }
         return functions;
     }
@@ -223,10 +220,12 @@ public class ShowFunctionsCommand extends ShowCommand {
             this.dbName = reAcquireDbName(ctx, dbName);
         }
 
-        if (!FunctionUtil.isGlobalFunction(type) && 
!Env.getCurrentEnv().getAccessManager()
-                .checkDbPriv(ConnectContext.get(), 
InternalCatalog.INTERNAL_CATALOG_NAME, dbName, PrivPredicate.SHOW)) {
-            
ErrorReport.reportAnalysisException(ErrorCode.ERR_DBACCESS_DENIED_ERROR,
-                    ConnectContext.get().getQualifiedUser(), dbName);
+        if (!FunctionUtil.isGlobalFunction(type)) {
+            if 
(!Env.getCurrentEnv().getAccessManager().checkDbPriv(ConnectContext.get(),
+                    InternalCatalog.INTERNAL_CATALOG_NAME, dbName, 
PrivPredicate.SELECT)) {
+                
ErrorReport.reportAnalysisException(ErrorCode.ERR_DB_ACCESS_DENIED_ERROR,
+                        PrivPredicate.SELECT.getPrivs().toString(), dbName);
+            }
         }
 
         List<List<String>> resultRowSet = getResultRowSet(ctx);
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 aafc928ab8b..7ab5334529b 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
@@ -176,6 +176,7 @@ import 
org.apache.doris.nereids.trees.plans.commands.ShowBackendsCommand;
 import org.apache.doris.nereids.trees.plans.commands.ShowBackupCommand;
 import org.apache.doris.nereids.trees.plans.commands.ShowBrokerCommand;
 import org.apache.doris.nereids.trees.plans.commands.ShowBuildIndexCommand;
+import 
org.apache.doris.nereids.trees.plans.commands.ShowBuiltinFunctionsCommand;
 import org.apache.doris.nereids.trees.plans.commands.ShowCatalogCommand;
 import 
org.apache.doris.nereids.trees.plans.commands.ShowCatalogRecycleBinCommand;
 import org.apache.doris.nereids.trees.plans.commands.ShowCharsetCommand;
@@ -845,6 +846,10 @@ public interface CommandVisitor<R, C> {
         return visitCommand(showFunctionsCommand, context);
     }
 
+    default R visitShowBuiltinFunctionsCommand(ShowBuiltinFunctionsCommand 
showBuiltinFunctionsCommand, C context) {
+        return visitCommand(showBuiltinFunctionsCommand, context);
+    }
+
     default R visitAdminRebalanceDiskCommand(AdminRebalanceDiskCommand 
adminRebalanceDiskCommand, C context) {
         return visitCommand(adminRebalanceDiskCommand, context);
     }
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/ShowBuiltinFunctionsCommandTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/ShowBuiltinFunctionsCommandTest.java
new file mode 100644
index 00000000000..719cc0a7ed2
--- /dev/null
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/ShowBuiltinFunctionsCommandTest.java
@@ -0,0 +1,103 @@
+// 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.UserDesc;
+import org.apache.doris.analysis.UserIdentity;
+import org.apache.doris.catalog.Env;
+import org.apache.doris.common.AnalysisException;
+import org.apache.doris.mysql.privilege.Auth;
+import org.apache.doris.nereids.trees.plans.commands.info.CreateUserInfo;
+import org.apache.doris.qe.ConnectContext;
+import org.apache.doris.qe.ShowResultSet;
+import org.apache.doris.utframe.TestWithFeService;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+/**
+ * show builtin functions command test
+ */
+public class ShowBuiltinFunctionsCommandTest extends TestWithFeService {
+    private Auth auth;
+
+    @Override
+    protected void runBeforeAll() throws Exception {
+        createDatabase("test");
+        createDatabase("test_no_priv");
+        connectContext.setDatabase("test");
+        createFunction(
+                "CREATE ALIAS FUNCTION test.test_for_create_function(bigint) 
WITH PARAMETER(id) AS CONCAT(LEFT(id,3),'****',RIGHT(id,4));");
+    }
+
+    @Test
+    void testGetFunctions() throws AnalysisException {
+        // test for not full builtin functions
+        connectContext.setDatabase("");
+        ShowBuiltinFunctionsCommand sbf1 = new 
ShowBuiltinFunctionsCommand(false, null);
+        List<String> re1 = sbf1.getFunctions(connectContext);
+        Assertions.assertTrue(re1.size() >= 775);
+
+        // test for full builtin functions
+        ShowBuiltinFunctionsCommand sbf2 = new 
ShowBuiltinFunctionsCommand(true, null);
+        List<String> re3 = sbf2.getFunctions(connectContext);
+        Assertions.assertTrue(re3.size() >= 775);
+    }
+
+    @Test
+    void testGetResultRowSetByFunctions() throws AnalysisException {
+        // test for full builtin functions
+        connectContext.setDatabase("");
+        ShowBuiltinFunctionsCommand sbf2 = new 
ShowBuiltinFunctionsCommand(true, null);
+        List<String> func3 = sbf2.getFunctions(connectContext);
+        List<List<String>> re3 = sbf2.getResultRowSetByFunctions(func3);
+        Assertions.assertTrue(re3.size() >= 775);
+        for (List<String> funcItem : re3) {
+            Assertions.assertEquals("", funcItem.get(1));
+            Assertions.assertEquals("", funcItem.get(2));
+            Assertions.assertEquals("", funcItem.get(3));
+            Assertions.assertEquals("", funcItem.get(4));
+        }
+    }
+
+    @Test
+    void testLike() {
+        connectContext.setDatabase("");
+        ShowBuiltinFunctionsCommand sbf = new 
ShowBuiltinFunctionsCommand(false, null);
+        Assertions.assertTrue(sbf.like("year_of_week", "year_of_week%"));
+    }
+
+    @Test
+    void testAuth() throws Exception {
+        auth = Env.getCurrentEnv().getAuth();
+        UserIdentity noPrivUser = new UserIdentity("cmy", "%");
+        UserDesc userDesc = new UserDesc(noPrivUser, "12345", true);
+        CreateUserCommand createUserCommand = new CreateUserCommand(new 
CreateUserInfo(userDesc));
+        createUserCommand.getInfo().validate();
+        auth.createUser(createUserCommand.getInfo());
+        ConnectContext ctx = ConnectContext.get();
+        ctx.setCurrentUserIdentity(noPrivUser);
+        // user1 have no any privilege
+        ShowBuiltinFunctionsCommand sbf = new 
ShowBuiltinFunctionsCommand(false, null);
+        ShowResultSet showResultSet = sbf.handleShowBuiltinFunctions(ctx, 
null);
+        List<List<String>> ret = showResultSet.getResultRows();
+        Assertions.assertTrue(ret.size() >= 775);
+    }
+}
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/ShowFunctionsCommandTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/ShowFunctionsCommandTest.java
index eda01ca307a..5825a57e74f 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/ShowFunctionsCommandTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/ShowFunctionsCommandTest.java
@@ -52,62 +52,37 @@ public class ShowFunctionsCommandTest extends 
TestWithFeService {
     @Test
     void testGetFunctions() throws AnalysisException {
         // test No database selected
-        ShowFunctionsCommand sf = new ShowFunctionsCommand("", true, false, 
null);
+        ShowFunctionsCommand sf = new ShowFunctionsCommand("", false, null);
         connectContext.setDatabase("");
         ShowFunctionsCommand finalSf = sf;
         Assertions.assertThrows(AnalysisException.class, () -> 
finalSf.getFunctions(connectContext));
 
-        // test for builtin functions
-        connectContext.setDatabase("test");  // reset database
-        sf = new ShowFunctionsCommand("test", true, false, null);
-        List<String> re1 = sf.getFunctions(connectContext);
-        Assertions.assertTrue(re1.size() > 100);
-
         // test for not builtin functions
-        sf = new ShowFunctionsCommand("test", false, false, null);
+        sf = new ShowFunctionsCommand("test", false, null);
         List<String> re2 = sf.getFunctions(connectContext);
         Assertions.assertEquals(1, re2.size());
         Assertions.assertEquals("test_for_create_function", re2.get(0));
 
-        // test for full builtin functions
-        sf = new ShowFunctionsCommand("test", true, true, null);
-        List<String> re3 = sf.getFunctions(connectContext);
-        Assertions.assertTrue(re3.size() > 100);
-
         // test for full not builtin functions
-        sf = new ShowFunctionsCommand("test", false, true, null);
+        sf = new ShowFunctionsCommand("test", true, null);
         List<String> re4 = sf.getFunctions(connectContext);
         Assertions.assertEquals(1, re4.size());
     }
 
     @Test
     void testGetResultRowSetByFunctions() throws AnalysisException {
-        // test for builtin functions
-        connectContext.setDatabase("test");
-        ShowFunctionsCommand sf = new ShowFunctionsCommand("test", true, 
false, null);
-        List<String> func1 = sf.getFunctions(connectContext);
-        List<List<String>> re1 = sf.getResultRowSetByFunctions(func1);
-        Assertions.assertTrue(re1.size() > 100);
-
         // test for not builtin functions
-        sf = new ShowFunctionsCommand("test", false, false, null);
+        ShowFunctionsCommand sf;
+        connectContext.setDatabase("test");
+        sf = new ShowFunctionsCommand("test", false, null);
         List<String> func2 = sf.getFunctions(connectContext);
         List<List<String>> re2 = sf.getResultRowSetByFunctions(func2);
         Assertions.assertEquals(1, re2.get(0).size());
         Assertions.assertEquals("test_for_create_function", re2.get(0).get(0));
 
-        // test for full builtin functions
-        sf = new ShowFunctionsCommand("test", true, true, null);
-        List<String> func3 = sf.getFunctions(connectContext);
-        List<List<String>> re3 = sf.getResultRowSetByFunctions(func3);
-        Assertions.assertTrue(re3.size() > 100);
-        Assertions.assertEquals("", re3.get(0).get(1));
-        Assertions.assertEquals("", re3.get(0).get(2));
-        Assertions.assertEquals("", re3.get(0).get(3));
-        Assertions.assertEquals("", re3.get(0).get(4));
-
         // test for full not builtin functions
-        sf = new ShowFunctionsCommand("test", false, true, null);
+        connectContext.setDatabase("test");
+        sf = new ShowFunctionsCommand("test", true, null);
         List<String> func4 = sf.getFunctions(connectContext);
         List<List<String>> re4 = sf.getResultRowSetByFunctions(func4);
         Assertions.assertEquals(5, re4.get(0).size());
@@ -119,7 +94,7 @@ public class ShowFunctionsCommandTest extends 
TestWithFeService {
 
         // test for full not builtin functions with where condition
         String where = "test_for_create_function%";
-        sf = new ShowFunctionsCommand("test", false, true, where);
+        sf = new ShowFunctionsCommand("test", true, where);
         List<String> func5 = sf.getFunctions(connectContext);
         List<List<String>> re5 = sf.getResultRowSetByFunctions(func5);
         Assertions.assertEquals(5, re5.get(0).size());
@@ -133,7 +108,7 @@ public class ShowFunctionsCommandTest extends 
TestWithFeService {
     @Test
     void testLike() {
         connectContext.setDatabase("test");
-        ShowFunctionsCommand sf = new ShowFunctionsCommand("test", true, 
false, null);
+        ShowFunctionsCommand sf = new ShowFunctionsCommand("test", false, 
null);
         Assertions.assertTrue(sf.like("test_for_create_function", 
"test_for_create_function%"));
     }
 
@@ -163,11 +138,11 @@ public class ShowFunctionsCommandTest extends 
TestWithFeService {
         ctx.setCurrentUserIdentity(user1);
 
         // user1 have select privilege of db test
-        ShowFunctionsCommand sf = new ShowFunctionsCommand("test", true, true, 
null);
+        ShowFunctionsCommand sf = new ShowFunctionsCommand("test", true, null);
         sf.handleShowFunctions(ctx, null);
 
         // but user1 have not select privilege of db test_no_priv
-        ShowFunctionsCommand sfNoPriv = new 
ShowFunctionsCommand("test_no_priv", true, true, null);
+        ShowFunctionsCommand sfNoPriv = new 
ShowFunctionsCommand("test_no_priv", true, null);
         Assertions.assertThrows(AnalysisException.class, () -> 
sfNoPriv.handleShowFunctions(ctx, null));
     }
 }
diff --git 
a/regression-test/suites/nereids_p0/show/test_nereids_show_functions.groovy 
b/regression-test/suites/nereids_p0/show/test_nereids_show_functions.groovy
index 6f7c895b921..725d712bc3d 100644
--- a/regression-test/suites/nereids_p0/show/test_nereids_show_functions.groovy
+++ b/regression-test/suites/nereids_p0/show/test_nereids_show_functions.groovy
@@ -23,14 +23,14 @@ suite("test_nereids_show_functions") {
     sql """DROP FUNCTION IF EXISTS ${dbName}.${functionName}(INT);"""
     sql """CREATE ALIAS FUNCTION ${dbName}.${functionName}(INT) WITH 
PARAMETER(id)  AS CONCAT(LEFT(id, 3), '****', RIGHT(id, 4));"""
 
-    checkNereidsExecute("use ${dbName}; show builtin functions;")
-    checkNereidsExecute("use ${dbName}; show builtin functions like 'ye%'")
-    checkNereidsExecute("use ${dbName}; show full builtin functions;")
-    checkNereidsExecute("use ${dbName}; show full builtin functions like 
'ye%';")
+    checkNereidsExecute("show builtin functions;")
+    checkNereidsExecute("show builtin functions like 'ye%'")
+    checkNereidsExecute("show full builtin functions;")
+    checkNereidsExecute("show full builtin functions like 'ye%';")
     checkNereidsExecute("use ${dbName}; show functions;")
     checkNereidsExecute("use ${dbName}; show functions like 
'${functionName}%'")
     checkNereidsExecute("use ${dbName}; show full functions like 
'${functionName}%';")
-    def res = sql """use ${dbName}; show builtin functions like '%yow%';"""
+    def res = sql """show builtin functions like '%yow%';"""
     assertTrue(res.size() == 1)
     def res1 = sql """use ${dbName}; show functions;"""
     assertTrue(res1.size() == 1)
@@ -45,22 +45,22 @@ suite("test_nereids_show_functions") {
     assertEquals(res3.get(0).get(3), "")
     assertEquals(res3.get(0).get(4), "")
 
-    checkNereidsExecute("show builtin functions from ${dbName};")
-    checkNereidsExecute("show builtin functions from ${dbName} like 'ye%';")
-    checkNereidsExecute("show full builtin functions from ${dbName};")
-    checkNereidsExecute("show full builtin functions from ${dbName} like 
'ye%';")
+    checkNereidsExecute("show builtin functions;")
+    checkNereidsExecute("show builtin functions like 'ye%';")
+    checkNereidsExecute("show full builtin functions;")
+    checkNereidsExecute("show full builtin functions like 'ye%';")
     checkNereidsExecute("show functions from ${dbName};")
     checkNereidsExecute("show functions from ${dbName} like 
'${functionName}%';")
     checkNereidsExecute("show full functions from ${dbName};")
     checkNereidsExecute("show full functions from ${dbName} like 
'${functionName}%';")
-    def res4 = sql """show builtin functions from ${dbName} like '%yow%';"""
+    def res4 = sql """show builtin functions like '%yow%';"""
     assertTrue(res4.size() == 1)
     def res5 = sql """show functions from ${dbName}"""
     assertTrue(res5.size() == 1)
     def res6 = sql """show functions from ${dbName} like '${functionName}%';"""
     assertTrue(res6.size() == 1)
     // in nereids, each column of 'show full functions' is empty string, 
except Signature.
-    def res7 = sql """show full functions from ${dbName} like 
'${functionName}%';"""
+    def res7 = sql """show full functions like '${functionName}%';"""
     assertTrue(res7.size() == 1)
     assertEquals(res7.get(0).get(0), functionName)
     assertEquals(res7.get(0).get(1), "")
@@ -68,15 +68,15 @@ suite("test_nereids_show_functions") {
     assertEquals(res7.get(0).get(3), "")
     assertEquals(res7.get(0).get(4), "")
 
-    checkNereidsExecute("show builtin functions in ${dbName};")
-    checkNereidsExecute("show builtin functions in ${dbName} like 'ye%';")
-    checkNereidsExecute("show full builtin functions in ${dbName};")
-    checkNereidsExecute("show full builtin functions in ${dbName} like 'ye%';")
+    checkNereidsExecute("show builtin functions;")
+    checkNereidsExecute("show builtin functions like 'ye%';")
+    checkNereidsExecute("show full builtin functions;")
+    checkNereidsExecute("show full builtin functions like 'ye%';")
     checkNereidsExecute("show functions in ${dbName};")
     checkNereidsExecute("show functions in ${dbName} like '${functionName}%';")
     checkNereidsExecute("show full functions in ${dbName};")
     checkNereidsExecute("show full functions in ${dbName} like 
'${functionName}%';")
-    def res8 = sql """show builtin functions in ${dbName} like '%yow%';"""
+    def res8 = sql """show builtin functions like '%yow%';"""
     assertTrue(res8.size() == 1)
     def res9 = sql """show functions in ${dbName}"""
     assertTrue(res9.size() == 1)


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


Reply via email to