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]