[Stmt] Support new show functions syntax to make user search function more conveniently (#2800)

SHOW [FULL] [BUILTIN] FUNCTIONS [IN|FROM db] [LIKE 'function_pattern'];
This commit is contained in:
caiconghui
2020-01-20 14:14:42 +08:00
committed by Mingyu Chen
parent 0f829ca4c4
commit 58ff952837
13 changed files with 362 additions and 112 deletions

View File

@ -17,42 +17,56 @@ specific language governing permissions and limitations
under the License.
-->
# SHOW FUNCTION
# SHOW FUNCTIONS
## description
### Syntax
```
SHOW FUNCTION [FROM db]
SHOW [FULL] [BUILTIN] FUNCTIONS [IN|FROM db] [LIKE 'function_pattern']
```
### Parameters
> `db`: 要查询的数据库名字
>`full`:表示显示函数的详细信息
>`builtin`:表示显示系统提供的函数
>`db`: 要查询的数据库名字
>`function_pattern`: 用来过滤函数名称的参数
查看数据库下所有的自定义函数。如果用户指定了数据库,那么查看对应数据库的,否则直接查询当前会话所在数据库
查看数据库下所有的自定义(系统提供)的函数。如果用户指定了数据库,那么查看对应数据库的,否则直接查询当前会话所在数据库
需要对这个数据库拥有 `SHOW` 权限
## example
```
mysql> show function in testDb\G
mysql> show full functions in testDb\G
*************************** 1. row ***************************
Signature: my_count(BIGINT)
Return Type: BIGINT
Function Type: Aggregate
Intermediate Type: NULL
Properties: {"object_file":"http://host:port/libudasample.so","finalize_fn":"_ZN9doris_udf13CountFinalizeEPNS_15FunctionContextERKNS_9BigIntValE","init_fn":"_ZN9doris_udf9CountInitEPNS_15FunctionContextEPNS_9BigIntValE","merge_fn":"_ZN9doris_udf10CountMergeEPNS_15FunctionContextERKNS_9BigIntValEPS2_","md5":"37d185f80f95569e2676da3d5b5b9d2f","update_fn":"_ZN9doris_udf11CountUpdateEPNS_15FunctionContextERKNS_6IntValEPNS_9BigIntValE"}
*************************** 2. row ***************************
Signature: my_add(INT,INT)
Return Type: INT
Function Type: Scalar
Intermediate Type: NULL
Properties: {"symbol":"_ZN9doris_udf6AddUdfEPNS_15FunctionContextERKNS_6IntValES4_","object_file":"http://host:port/libudfsample.so","md5":"cfe7a362d10f3aaf6c49974ee0f1f878"}
*************************** 2. row ***************************
Signature: my_count(BIGINT)
Return Type: BIGINT
Function Type: Aggregate
Intermediate Type: NULL
Properties: {"object_file":"http://host:port/libudasample.so","finalize_fn":"_ZN9doris_udf13CountFinalizeEPNS_15FunctionContextERKNS_9BigIntValE","init_fn":"_ZN9doris_udf9CountInitEPNS_15FunctionContextEPNS_9BigIntValE","merge_fn":"_ZN9doris_udf10CountMergeEPNS_15FunctionContextERKNS_9BigIntValEPS2_","md5":"37d185f80f95569e2676da3d5b5b9d2f","update_fn":"_ZN9doris_udf11CountUpdateEPNS_15FunctionContextERKNS_6IntValEPNS_9BigIntValE"}
2 rows in set (0.00 sec)
mysql> show builtin functions in testDb like 'year%';
+---------------+
| Function Name |
+---------------+
| year |
| years_add |
| years_diff |
| years_sub |
+---------------+
2 rows in set (0.00 sec)
```
## keyword
SHOW,FUNCTION
SHOW,FUNCTIONS

View File

@ -1,56 +0,0 @@
<!--
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.
-->
# SHOW FUNCTION
## Description
### Syntax
```
SHOW FUNCTION [FROM db]
```
### Parameters
>` DB `: The name of the database to query
Look at all the custom functions under the database. If the user specifies the database, then look at the corresponding database, otherwise directly query the database where the current session is located.
You need `SHOW'privileges for this database
## example
```
mysql> show function in testDb\G
*********************************1. row ************************
Signature: my_count(BIGINT)
Return Type: BIGINT
Function Type: Aggregate
Intermediate Type: NULL
Properties: {"object_file":"http://host:port/libudasample.so","finalize_fn":"_ZN9doris_udf13CountFinalizeEPNS_15FunctionContextERKNS_9BigIntValE","init_fn":"_ZN9doris_udf9CountInitEPNS_15FunctionContextEPNS_9BigIntValE","merge_fn":"_ZN9doris_udf10CountMergeEPNS_15FunctionContextERKNS_9BigIntValEPS2_","md5":"37d185f80f95569e2676da3d5b5b9d2f","update_fn":"_ZN9doris_udf11CountUpdateEPNS_15FunctionContextERKNS_6IntValEPNS_9BigIntValE"}
*********************************2. row ************************
Signature: my_add(INT,INT)
Return Type: INT
Function Type: Scalar
Intermediate Type: NULL
Properties: {"symbol":"_ZN9doris_udf6AddUdfEPNS_15FunctionContextERKNS_6IntValES4_","object_file":"http://host:port/libudfsample.so","md5":"cfe7a362d10f3aaf6c49974ee0f1f878"}
2 rows in set (0.00 sec)
```
##keyword
SHOW,FUNCTION

View File

@ -0,0 +1,70 @@
<!--
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.
-->
# SHOW FUNCTIONS
## Description
### Syntax
```
SHOW [FULL] [BUILTIN] FUNCTIONS [IN|FROM db] [LIKE 'function_pattern']
```
### Parameters
>`full`: Indicate to show the details of function
>`builtin`: Indicate to show the functions that doris provides
>`db`: The name of the database to query
>`function_pattern`: The parameter to filter function name
Look at all the custom(builtin) functions under the database. If the user specifies the database, then look at the corresponding database, otherwise directly query the database where the current session is located.
You need `SHOW'privileges for this database
## example
```
mysql> show full functions in testDb\G
*************************** 1. row ***************************
Signature: my_add(INT,INT)
Return Type: INT
Function Type: Scalar
Intermediate Type: NULL
Properties: {"symbol":"_ZN9doris_udf6AddUdfEPNS_15FunctionContextERKNS_6IntValES4_","object_file":"http://host:port/libudfsample.so","md5":"cfe7a362d10f3aaf6c49974ee0f1f878"}
*************************** 2. row ***************************
Signature: my_count(BIGINT)
Return Type: BIGINT
Function Type: Aggregate
Intermediate Type: NULL
Properties: {"object_file":"http://host:port/libudasample.so","finalize_fn":"_ZN9doris_udf13CountFinalizeEPNS_15FunctionContextERKNS_9BigIntValE","init_fn":"_ZN9doris_udf9CountInitEPNS_15FunctionContextEPNS_9BigIntValE","merge_fn":"_ZN9doris_udf10CountMergeEPNS_15FunctionContextERKNS_9BigIntValEPS2_","md5":"37d185f80f95569e2676da3d5b5b9d2f","update_fn":"_ZN9doris_udf11CountUpdateEPNS_15FunctionContextERKNS_6IntValEPNS_9BigIntValE"}
2 rows in set (0.00 sec)
mysql> show builtin functions in testDb like 'year%';
+---------------+
| Function Name |
+---------------+
| year |
| years_add |
| years_diff |
| years_sub |
+---------------+
2 rows in set (0.00 sec)
```
##keyword
SHOW,FUNCTIONS

View File

@ -194,14 +194,14 @@ parser code {:
// Total keywords of doris
terminal String KW_ADD, KW_ADMIN, KW_AFTER, KW_AGGREGATE, KW_ALL, KW_ALTER, KW_AND, KW_ANTI, KW_AS, KW_ASC, KW_AUTHORS,
KW_BACKEND, KW_BACKUP, KW_BETWEEN, KW_BEGIN, KW_BIGINT, KW_BITMAP, KW_BITMAP_UNION, KW_BOOLEAN, KW_BOTH, KW_BROKER, KW_BACKENDS, KW_BY,
KW_BACKEND, KW_BACKUP, KW_BETWEEN, KW_BEGIN, KW_BIGINT, KW_BITMAP, KW_BITMAP_UNION, KW_BOOLEAN, KW_BOTH, KW_BROKER, KW_BACKENDS, KW_BY, KW_BUILTIN,
KW_CANCEL, KW_CASE, KW_CAST, KW_CHAIN, KW_CHAR, KW_CHARSET, KW_CLUSTER, KW_CLUSTERS,
KW_COLLATE, KW_COLLATION, KW_COLUMN, KW_COLUMNS, KW_COMMENT, KW_COMMIT, KW_COMMITTED,
KW_CONFIG, KW_CONNECTION, KW_CONNECTION_ID, KW_CONSISTENT, KW_COUNT, KW_CREATE, KW_CROSS, KW_CUBE, KW_CURRENT, KW_CURRENT_USER,
KW_DATA, KW_DATABASE, KW_DATABASES, KW_DATE, KW_DATETIME, KW_DAY, KW_DECIMAL, KW_DECOMMISSION, KW_DEFAULT, KW_DESC, KW_DESCRIBE,
KW_DELETE, KW_DISTINCT, KW_DISTINCTPC, KW_DISTINCTPCSA, KW_DISTRIBUTED, KW_DISTRIBUTION, KW_DYNAMIC, KW_BUCKETS, KW_DIV, KW_DOUBLE, KW_DROP, KW_DROPP, KW_DUPLICATE,
KW_ELSE, KW_END, KW_ENGINE, KW_ENGINES, KW_ENTER, KW_ERRORS, KW_EVENTS, KW_EXISTS, KW_EXPORT, KW_EXTERNAL, KW_EXTRACT,
KW_FALSE, KW_FOLLOWER, KW_FOLLOWING, KW_FREE, KW_FROM, KW_FILE, KW_FIRST, KW_FLOAT, KW_FOR, KW_FORMAT, KW_FRONTEND, KW_FRONTENDS, KW_FULL, KW_FUNCTION,
KW_FALSE, KW_FOLLOWER, KW_FOLLOWING, KW_FREE, KW_FROM, KW_FILE, KW_FIRST, KW_FLOAT, KW_FOR, KW_FORMAT, KW_FRONTEND, KW_FRONTENDS, KW_FULL, KW_FUNCTION, KW_FUNCTIONS,
KW_GLOBAL, KW_GRANT, KW_GRANTS, KW_GROUP, KW_GROUPING,
KW_HASH, KW_HAVING, KW_HELP,KW_HLL, KW_HLL_UNION, KW_HOUR, KW_HUB,
KW_IDENTIFIED, KW_IF, KW_IN, KW_INDEX, KW_INDEXES, KW_INFILE,
@ -429,6 +429,7 @@ nonterminal Boolean opt_external;
nonterminal IndexDef.IndexType opt_index_type;
nonterminal ShowAlterStmt.AlterType opt_alter_type;
nonterminal Boolean opt_builtin;
precedence left KW_FULL, KW_MERGE;
precedence left DOT;
@ -2094,9 +2095,9 @@ show_param ::=
{:
RESULT = new ShowRolesStmt();
:}
| KW_FUNCTION opt_db:dbName
| opt_full opt_builtin:isBuiltin KW_FUNCTIONS opt_db:dbName opt_wild_where
{:
RESULT = new ShowFunctionStmt(dbName);
RESULT = new ShowFunctionsStmt(dbName, isBuiltin, parser.isVerbose, parser.wild, parser.where);
:}
| KW_FILE opt_db:dbName
{:
@ -2247,6 +2248,16 @@ opt_alter_type ::=
:}
;
opt_builtin ::=
{:
RESULT = false;
:}
| KW_BUILTIN
{:
RESULT = true;
:}
;
// Describe statement
describe_stmt ::=
describe_command table_name:table
@ -4189,6 +4200,8 @@ keyword ::=
{: RESULT = id; :}
| KW_BACKENDS:id
{: RESULT = id; :}
| KW_BUILTIN:id
{: RESULT = id; :}
| KW_CHAIN:id
{: RESULT = id; :}
| KW_CHARSET:id

View File

@ -22,6 +22,7 @@ import org.apache.doris.catalog.Catalog;
import org.apache.doris.catalog.Column;
import org.apache.doris.catalog.ScalarType;
import org.apache.doris.cluster.ClusterNamespace;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.ErrorCode;
import org.apache.doris.common.ErrorReport;
import org.apache.doris.common.UserException;
@ -29,7 +30,7 @@ import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.qe.ShowResultSetMetaData;
public class ShowFunctionStmt extends ShowStmt {
public class ShowFunctionsStmt extends ShowStmt {
private static final ShowResultSetMetaData META_DATA =
ShowResultSetMetaData.builder()
.addColumn(new Column("Signature", ScalarType.createVarchar(256)))
@ -41,15 +42,49 @@ public class ShowFunctionStmt extends ShowStmt {
private String dbName;
public ShowFunctionStmt(String dbName) {
private boolean isBuiltin;
private boolean isVerbose;
private String wild;
private Expr expr;
public ShowFunctionsStmt(String dbName, boolean isBuiltin, boolean isVerbose, String wild, Expr expr) {
this.dbName = dbName;
this.isBuiltin = isBuiltin;
this.isVerbose = isVerbose;
this.wild = wild;
this.expr = expr;
}
public String getDbName() { return dbName; }
public boolean getIsBuiltin() {
return isBuiltin;
}
public boolean getIsVerbose() {
return isVerbose;
}
public String getWild() {
return wild;
}
public Expr getExpr() {
return expr;
}
public boolean like(String str) {
str = str.toLowerCase();
return str.matches(wild.replace(".", "\\.").replace("?", ".").replace("%", ".*").toLowerCase());
}
@Override
public void analyze(Analyzer analyzer) throws UserException {
super.analyze(analyzer);
if (Strings.isNullOrEmpty(dbName)) {
dbName = analyzer.getDefaultDb();
if (Strings.isNullOrEmpty(dbName)) {
@ -61,7 +96,11 @@ public class ShowFunctionStmt extends ShowStmt {
if (!Catalog.getCurrentCatalog().getAuth().checkDbPriv(ConnectContext.get(), dbName, PrivPredicate.SHOW)) {
ErrorReport.reportAnalysisException(
ErrorCode.ERR_DB_ACCESS_DENIED, ConnectContext.get().getQualifiedUser(), dbName);
ErrorCode.ERR_DB_ACCESS_DENIED, ConnectContext.get().getQualifiedUser(), dbName);
}
if (expr != null) {
throw new AnalysisException("Only support like 'function_pattern' syntax.");
}
}
@ -69,4 +108,31 @@ public class ShowFunctionStmt extends ShowStmt {
public ShowResultSetMetaData getMetaData() {
return META_DATA;
}
@Override
public String toSql() {
StringBuilder sb = new StringBuilder();
sb.append("SHOW ");
if (isVerbose) {
sb.append("FULL ");
}
if (isBuiltin) {
sb.append("BUILTIN ");
}
sb.append("FUNCTIONS FROM ");
if (!Strings.isNullOrEmpty(dbName)) {
sb.append("`").append(dbName).append("` ");
}
if (wild != null) {
sb.append("LIKE ").append("`").append(wild).append("`");
}
return sb.toString();
}
@Override
public String toString() {
return toSql();
}
}

View File

@ -457,7 +457,7 @@ public class AggregateFunction extends Function {
@Override
public String getProperties() {
Map<String, String> properties = Maps.newHashMap();
properties.put(CreateFunctionStmt.OBJECT_FILE_KEY, getLocation().toString());
properties.put(CreateFunctionStmt.OBJECT_FILE_KEY, getLocation() == null ? "" : getLocation().toString());
properties.put(CreateFunctionStmt.MD5_CHECKSUM, checksum);
properties.put(CreateFunctionStmt.INIT_KEY, initFnSymbol);
properties.put(CreateFunctionStmt.UPDATE_KEY, updateFnSymbol);

View File

@ -5268,6 +5268,10 @@ public class Catalog {
return functionSet.getFunction(desc, mode);
}
public List<Function> getBuiltinFunctions() {
return functionSet.getBulitinFunctions();
}
/**
* create cluster
*

View File

@ -21,6 +21,7 @@ import static org.apache.doris.common.io.IOUtils.writeOptionString;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import org.apache.doris.analysis.FunctionName;
import org.apache.doris.analysis.HdfsURI;
import org.apache.doris.common.io.Text;
@ -668,4 +669,34 @@ public class Function implements Writable {
public String getProperties() {
return "";
}
public List<Comparable> getInfo(boolean isVerbose) {
List<Comparable> row = Lists.newArrayList();
if (isVerbose) {
// signature
row.add(getSignature());
// return type
row.add(getReturnType().getPrimitiveType().toString());
// function type
// intermediate type
if (this instanceof ScalarFunction) {
row.add("Scalar");
row.add("NULL");
} else {
row.add("Aggregate");
AggregateFunction aggFunc = (AggregateFunction) this;
Type intermediateType = aggFunc.getIntermediateType();
if (intermediateType != null) {
row.add(intermediateType.getPrimitiveType().toString());
} else {
row.add("NULL");
}
}
// property
row.add(getProperties());
} else {
row.add(functionName());
}
return row;
}
}

View File

@ -1320,4 +1320,12 @@ public class FunctionSet {
}
}
public List<Function> getBulitinFunctions() {
List<Function> builtinFunctions = Lists.newArrayList();
for (Map.Entry<String, List<Function>> entry : functions.entrySet()) {
builtinFunctions.addAll(entry.getValue());
}
return builtinFunctions;
}
}

View File

@ -304,7 +304,7 @@ public class ScalarFunction extends Function {
@Override
public String getProperties() {
Map<String, String> properties = Maps.newHashMap();
properties.put(CreateFunctionStmt.OBJECT_FILE_KEY, getLocation().toString());
properties.put(CreateFunctionStmt.OBJECT_FILE_KEY, getLocation() == null ? "" : getLocation().toString());
properties.put(CreateFunctionStmt.MD5_CHECKSUM, checksum);
properties.put(CreateFunctionStmt.SYMBOL_KEY, symbolName);
return new Gson().toJson(properties);

View File

@ -39,7 +39,7 @@ import org.apache.doris.analysis.ShowDynamicPartitionStmt;
import org.apache.doris.analysis.ShowEnginesStmt;
import org.apache.doris.analysis.ShowExportStmt;
import org.apache.doris.analysis.ShowFrontendsStmt;
import org.apache.doris.analysis.ShowFunctionStmt;
import org.apache.doris.analysis.ShowFunctionsStmt;
import org.apache.doris.analysis.ShowGrantsStmt;
import org.apache.doris.analysis.ShowIndexStmt;
import org.apache.doris.analysis.ShowLoadStmt;
@ -67,7 +67,6 @@ import org.apache.doris.backup.AbstractJob;
import org.apache.doris.backup.BackupJob;
import org.apache.doris.backup.Repository;
import org.apache.doris.backup.RestoreJob;
import org.apache.doris.catalog.AggregateFunction;
import org.apache.doris.catalog.Catalog;
import org.apache.doris.catalog.Column;
import org.apache.doris.catalog.Database;
@ -80,11 +79,10 @@ import org.apache.doris.catalog.MetadataViewer;
import org.apache.doris.catalog.OlapTable;
import org.apache.doris.catalog.Partition;
import org.apache.doris.catalog.Replica;
import org.apache.doris.catalog.ScalarFunction;
import org.apache.doris.catalog.ScalarType;
import org.apache.doris.catalog.Table;
import org.apache.doris.catalog.Tablet;
import org.apache.doris.catalog.TabletInvertedIndex;
import org.apache.doris.catalog.Type;
import org.apache.doris.catalog.View;
import org.apache.doris.clone.DynamicPartitionScheduler;
import org.apache.doris.cluster.BaseParam;
@ -138,6 +136,7 @@ import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -183,8 +182,8 @@ public class ShowExecutor {
handleShowProcesslist();
} else if (stmt instanceof ShowEnginesStmt) {
handleShowEngines();
} else if (stmt instanceof ShowFunctionStmt) {
handleShowFunction();
} else if (stmt instanceof ShowFunctionsStmt) {
handleShowFunctions();
} else if (stmt instanceof ShowVariablesStmt) {
handleShowVariables();
} else if (stmt instanceof ShowColumnStmt) {
@ -302,44 +301,51 @@ public class ShowExecutor {
resultSet = new ShowResultSet(showStmt.getMetaData(), rowSet);
}
// Handle show function
private void handleShowFunction() throws AnalysisException {
ShowFunctionStmt showStmt = (ShowFunctionStmt) stmt;
// Handle show functions
private void handleShowFunctions() throws AnalysisException {
ShowFunctionsStmt showStmt = (ShowFunctionsStmt) stmt;
Database db = ctx.getCatalog().getDb(showStmt.getDbName());
if (db == null) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_BAD_DB_ERROR, showStmt.getDbName());
}
List<Function> functions = db.getFunctions();
List<Function> functions = showStmt.getIsBuiltin() ? ctx.getCatalog().getBuiltinFunctions() :
db.getFunctions();
List<List<String>> rowSet = Lists.newArrayList();
List<List<Comparable>> rowSet = Lists.newArrayList();
for (Function function : functions) {
List<String> row = Lists.newArrayList();
// signature
row.add(function.getSignature());
// return type
row.add(function.getReturnType().getPrimitiveType().toString());
// function type
// intermediate type
if (function instanceof ScalarFunction) {
row.add("Scalar");
row.add("NULL");
} else {
row.add("Aggregate");
AggregateFunction aggFunc = (AggregateFunction) function;
Type intermediateType = aggFunc.getIntermediateType();
if (intermediateType != null) {
row.add(intermediateType.getPrimitiveType().toString());
} else {
row.add("NULL");
}
List<Comparable> row = function.getInfo(showStmt.getIsVerbose());
// like predicate
if (showStmt.getWild() == null || showStmt.like(function.functionName())) {
rowSet.add(row);
}
// property
row.add(function.getProperties());
rowSet.add(row);
}
// sort function rows by first column asc
ListComparator<List<Comparable>> comparator = null;
OrderByPair orderByPair = new OrderByPair(0, false);
comparator = new ListComparator<>(orderByPair);
Collections.sort(rowSet, comparator);
List<List<String>> resultRowSet = Lists.newArrayList();
Set<String> functionNameSet = new HashSet<>();
for (List<Comparable> row : rowSet) {
List<String> resultRow = Lists.newArrayList();
// if not verbose, remove duplicate function name
if (functionNameSet.contains(row.get(0).toString())) {
continue;
}
for (Comparable column : row) {
resultRow.add(column.toString());
}
resultRowSet.add(resultRow);
functionNameSet.add(resultRow.get(0));
}
// Only success
resultSet = new ShowResultSet(showStmt.getMetaData(), rowSet);
ShowResultSetMetaData showMetaData = showStmt.getIsVerbose() ? showStmt.getMetaData() :
ShowResultSetMetaData.builder()
.addColumn(new Column("Function Name", ScalarType.createVarchar(256))).build();
resultSet = new ShowResultSet(showMetaData, resultRowSet);
}
private void handleShowProc() throws AnalysisException {

View File

@ -111,6 +111,7 @@ import org.apache.doris.qe.SqlModeHelper;
keywordMap.put("both", new Integer(SqlParserSymbols.KW_BOTH));
keywordMap.put("broker", new Integer(SqlParserSymbols.KW_BROKER));
keywordMap.put("buckets", new Integer(SqlParserSymbols.KW_BUCKETS));
keywordMap.put("builtin", new Integer(SqlParserSymbols.KW_BUILTIN));
keywordMap.put("by", new Integer(SqlParserSymbols.KW_BY));
keywordMap.put("cancel", new Integer(SqlParserSymbols.KW_CANCEL));
keywordMap.put("case", new Integer(SqlParserSymbols.KW_CASE));
@ -189,6 +190,7 @@ import org.apache.doris.qe.SqlModeHelper;
keywordMap.put("frontends", new Integer(SqlParserSymbols.KW_FRONTENDS));
keywordMap.put("full", new Integer(SqlParserSymbols.KW_FULL));
keywordMap.put("function", new Integer(SqlParserSymbols.KW_FUNCTION));
keywordMap.put("functions", new Integer(SqlParserSymbols.KW_FUNCTIONS));
keywordMap.put("global", new Integer(SqlParserSymbols.KW_GLOBAL));
keywordMap.put("grant", new Integer(SqlParserSymbols.KW_GRANT));
keywordMap.put("grants", new Integer(SqlParserSymbols.KW_GRANTS));

View File

@ -0,0 +1,92 @@
// 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.analysis;
import mockit.Expectations;
import mockit.Mocked;
import org.apache.doris.catalog.Catalog;
import org.apache.doris.catalog.FakeCatalog;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.UserException;
import org.apache.doris.mysql.privilege.MockedAuth;
import org.apache.doris.mysql.privilege.PaloAuth;
import org.apache.doris.qe.ConnectContext;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
public class ShowFunctionsStmtTest {
@Mocked
private Analyzer analyzer;
private Catalog catalog;
@Mocked
private PaloAuth auth;
@Mocked
private ConnectContext ctx;
private FakeCatalog fakeCatalog;
@Rule
public ExpectedException expectedEx = ExpectedException.none();
@Before
public void setUp() {
fakeCatalog = new FakeCatalog();
catalog = AccessTestUtil.fetchAdminCatalog();
MockedAuth.mockedAuth(auth);
MockedAuth.mockedConnectContext(ctx, "root", "192.188.3.1");
FakeCatalog.setCatalog(catalog);
new Expectations() {
{
analyzer.getDefaultDb();
minTimes = 0;
result = "testDb";
analyzer.getCatalog();
minTimes = 0;
result = catalog;
analyzer.getClusterName();
minTimes = 0;
result = "testCluster";
}
};
}
@Test
public void testNormal() throws UserException {
ShowFunctionsStmt stmt = new ShowFunctionsStmt(null, true, true, "%year%", null);
stmt.analyze(analyzer);
Assert.assertEquals("SHOW FULL BUILTIN FUNCTIONS FROM `testDb` LIKE `%year%`", stmt.toString());
}
@Test
public void testUnsupportFilter() throws UserException {
SlotRef slotRef = new SlotRef(null, "Signature");
StringLiteral stringLiteral = new StringLiteral("year(DATETIME)");
BinaryPredicate binaryPredicate = new BinaryPredicate(BinaryPredicate.Operator.EQ, slotRef, stringLiteral);
ShowFunctionsStmt stmt = new ShowFunctionsStmt(null, true, true, null, binaryPredicate);
expectedEx.expect(AnalysisException.class);
expectedEx.expectMessage("Only support like 'function_pattern' syntax.");
stmt.analyze(analyzer);
}
}