diff --git a/docs/en/docs/sql-manual/sql-reference/Show-Statements/SHOW-TYPECAST.md b/docs/en/docs/sql-manual/sql-reference/Show-Statements/SHOW-TYPECAST.md new file mode 100644 index 0000000000..3378416f86 --- /dev/null +++ b/docs/en/docs/sql-manual/sql-reference/Show-Statements/SHOW-TYPECAST.md @@ -0,0 +1,71 @@ +--- +{ + "title": "SHOW-TYPECAST", + "language": "en" +} +--- + + + +## SHOW-TYPECAST + +### Name + +SHOW TYPECAST + +### Description + +View all type cast under the database. If the user specifies a database, then view the corresponding database, otherwise directly query the database where the current session is located + +Requires `SHOW` permission on this database + +grammar + +```sql +SHOW TYPE_CAST [IN|FROM db] +```` + + Parameters + +>`db`: database name to query + +### Example + +````sql +mysql> show type_cast in testDb\G +**************************** 1. row ******************** ****** +Origin Type: TIMEV2 + Cast Type: TIMEV2 +**************************** 2. row ******************** ****** +Origin Type: TIMEV2 + Cast Type: TIMEV2 +**************************** 3. row ******************** ****** +Origin Type: TIMEV2 + Cast Type: TIMEV2 + +3 rows in set (0.00 sec) +```` + +### Keywords + + SHOW, TYPECAST + +### Best Practice + diff --git a/docs/sidebars.json b/docs/sidebars.json index 2c8fe08f73..2a4ef60cb0 100644 --- a/docs/sidebars.json +++ b/docs/sidebars.json @@ -880,6 +880,7 @@ "sql-manual/sql-reference/Show-Statements/SHOW-EXPORT", "sql-manual/sql-reference/Show-Statements/SHOW-ENCRYPT-KEY", "sql-manual/sql-reference/Show-Statements/SHOW-FUNCTIONS", + "sql-manual/sql-reference/Show-Statements/SHOW-TYPECAST", "sql-manual/sql-reference/Show-Statements/SHOW-FILE", "sql-manual/sql-reference/Show-Statements/SHOW-GRANTS", "sql-manual/sql-reference/Show-Statements/SHOW-LAST-INSERT", diff --git a/docs/zh-CN/docs/sql-manual/sql-reference/Show-Statements/SHOW-TYPECAST.md b/docs/zh-CN/docs/sql-manual/sql-reference/Show-Statements/SHOW-TYPECAST.md new file mode 100644 index 0000000000..9f54d78895 --- /dev/null +++ b/docs/zh-CN/docs/sql-manual/sql-reference/Show-Statements/SHOW-TYPECAST.md @@ -0,0 +1,71 @@ +--- +{ + "title": "SHOW-TYPECAST", + "language": "zh-CN" +} +--- + + + +## SHOW-TYPECAST + +### Name + +SHOW TYPECAST + +### Description + +查看数据库下所有的类型转换。如果用户指定了数据库,那么查看对应数据库的,否则直接查询当前会话所在数据库 + +需要对这个数据库拥有 `SHOW` 权限 + +语法 + +```sql +SHOW TYPE_CAST [IN|FROM db] +```` + + Parameters + +>`db`: database name to query + +### Example + +````sql +mysql> show type_cast in testDb\G +**************************** 1. row ******************** ****** +Origin Type: TIMEV2 + Cast Type: TIMEV2 +**************************** 2. row ******************** ****** +Origin Type: TIMEV2 + Cast Type: TIMEV2 +**************************** 3. row ******************** ****** +Origin Type: TIMEV2 + Cast Type: TIMEV2 + +3 rows in set (0.00 sec) +```` + +### Keywords + + SHOW, TYPECAST + +### Best Practice + diff --git a/fe/fe-core/src/main/cup/sql_parser.cup b/fe/fe-core/src/main/cup/sql_parser.cup index 02179d4d58..ac678a2898 100644 --- a/fe/fe-core/src/main/cup/sql_parser.cup +++ b/fe/fe-core/src/main/cup/sql_parser.cup @@ -602,7 +602,8 @@ terminal String KW_WORK, KW_WRITE, KW_YEAR, - KW_MTMV; + KW_MTMV, + KW_TYPECAST; terminal COMMA, COLON, DOT, DOTDOTDOT, AT, STAR, LPAREN, RPAREN, SEMICOLON, LBRACKET, RBRACKET, DIVIDE, MOD, ADD, SUBTRACT; terminal BITAND, BITOR, BITXOR, BITNOT; @@ -3667,6 +3668,10 @@ show_param ::= {: RESULT = new ShowFunctionsStmt(dbName, isBuiltin, parser.isVerbose, parser.wild, parser.where); :} + | KW_TYPECAST opt_db:dbName + {: + RESULT = new ShowTypeCastStmt(dbName, parser.where); + :} | KW_FILE opt_db:dbName {: RESULT = new ShowSmallFilesStmt(dbName); diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowTypeCastStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowTypeCastStmt.java new file mode 100644 index 0000000000..84b161d069 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowTypeCastStmt.java @@ -0,0 +1,101 @@ +// 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 org.apache.doris.catalog.Column; +import org.apache.doris.catalog.Env; +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; +import org.apache.doris.mysql.privilege.PrivPredicate; +import org.apache.doris.qe.ConnectContext; +import org.apache.doris.qe.ShowResultSetMetaData; + +import com.google.common.base.Strings; + +public class ShowTypeCastStmt extends ShowStmt { + private static final ShowResultSetMetaData META_DATA = + ShowResultSetMetaData.builder() + .addColumn(new Column("Origin Type", ScalarType.createVarchar(32))) + .addColumn(new Column("Cast Type", ScalarType.createVarchar(32))) + .build(); + + @Override + public ShowResultSetMetaData getMetaData() { + return META_DATA; + } + + private String dbName; + + private Expr expr; + + public ShowTypeCastStmt(String dbName, Expr expr) { + this.dbName = dbName; + this.expr = expr; + } + + public String getDbName() { + return dbName; + } + + public Expr getExpr() { + return expr; + } + + @Override + public void analyze(Analyzer analyzer) throws UserException { + super.analyze(analyzer); + + if (Strings.isNullOrEmpty(dbName)) { + dbName = analyzer.getDefaultDb(); + if (Strings.isNullOrEmpty(dbName)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_NO_DB_ERROR); + } + } else { + dbName = ClusterNamespace.getFullName(getClusterName(), dbName); + } + + if (!Env.getCurrentEnv().getAuth().checkDbPriv(ConnectContext.get(), dbName, PrivPredicate.SHOW)) { + ErrorReport.reportAnalysisException( + ErrorCode.ERR_DBACCESS_DENIED_ERROR, ConnectContext.get().getQualifiedUser(), dbName); + } + + if (expr != null) { + throw new AnalysisException("Only support like 'function_pattern' syntax."); + } + } + + @Override + public String toSql() { + StringBuilder sb = new StringBuilder(); + sb.append("SHOW "); + sb.append("TypeCast FROM "); + if (!Strings.isNullOrEmpty(dbName)) { + sb.append("`").append(dbName).append("` "); + } + return sb.toString(); + } + + @Override + public String toString() { + return toSql(); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/PrimitiveType.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/PrimitiveType.java index c951a481f5..8ae8c76ed5 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/PrimitiveType.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/PrimitiveType.java @@ -94,6 +94,10 @@ public enum PrimitiveType { private static ImmutableSetMultimap implicitCastMap; + public static ImmutableSetMultimap getImplicitCastMap() { + return implicitCastMap; + } + static { ImmutableSetMultimap.Builder builder = ImmutableSetMultimap.builder(); // Nulltype diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java b/fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java index 6ea835fc77..5239a6c914 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java @@ -92,6 +92,7 @@ import org.apache.doris.analysis.ShowTabletStmt; import org.apache.doris.analysis.ShowTransactionStmt; import org.apache.doris.analysis.ShowTrashDiskStmt; import org.apache.doris.analysis.ShowTrashStmt; +import org.apache.doris.analysis.ShowTypeCastStmt; import org.apache.doris.analysis.ShowUserPropertyStmt; import org.apache.doris.analysis.ShowVariablesStmt; import org.apache.doris.analysis.ShowViewStmt; @@ -117,6 +118,7 @@ import org.apache.doris.catalog.MaterializedIndexMeta; import org.apache.doris.catalog.MetadataViewer; import org.apache.doris.catalog.OlapTable; import org.apache.doris.catalog.Partition; +import org.apache.doris.catalog.PrimitiveType; import org.apache.doris.catalog.Replica; import org.apache.doris.catalog.ReplicaAllocation; import org.apache.doris.catalog.ScalarType; @@ -196,6 +198,7 @@ import org.apache.doris.transaction.TransactionStatus; import com.google.common.base.Preconditions; import com.google.common.base.Strings; +import com.google.common.collect.ImmutableSetMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import org.apache.commons.lang3.tuple.Triple; @@ -387,6 +390,8 @@ public class ShowExecutor { handleMTMVJobs(); } else if (stmt instanceof ShowMTMVTaskStmt) { handleMTMVTasks(); + } else if (stmt instanceof ShowTypeCastStmt) { + handleShowTypeCastStmt(); } else { handleEmtpy(); } @@ -2472,4 +2477,26 @@ public class ShowExecutor { } resultSet = new ShowResultSet(showStmt.getMetaData(), results); } + + private void handleShowTypeCastStmt() throws AnalysisException { + ShowTypeCastStmt showStmt = (ShowTypeCastStmt) stmt; + + Util.prohibitExternalCatalog(ctx.getDefaultCatalog(), stmt.getClass().getSimpleName()); + DatabaseIf db = ctx.getCurrentCatalog().getDbOrAnalysisException(showStmt.getDbName()); + + List> resultRowSet = Lists.newArrayList(); + ImmutableSetMultimap castMap = PrimitiveType.getImplicitCastMap(); + if (db instanceof Database) { + resultRowSet = castMap.entries().stream().map(primitiveTypePrimitiveTypeEntry -> { + List list = Lists.newArrayList(); + list.add(primitiveTypePrimitiveTypeEntry.getKey().toString()); + list.add(primitiveTypePrimitiveTypeEntry.getValue().toString()); + return list; + }).collect(Collectors.toList()); + } + + // Only success + ShowResultSetMetaData showMetaData = showStmt.getMetaData(); + resultSet = new ShowResultSet(showMetaData, resultRowSet); + } } diff --git a/fe/fe-core/src/main/jflex/sql_scanner.flex b/fe/fe-core/src/main/jflex/sql_scanner.flex index 1f50df0105..2b0b02ecc6 100644 --- a/fe/fe-core/src/main/jflex/sql_scanner.flex +++ b/fe/fe-core/src/main/jflex/sql_scanner.flex @@ -235,6 +235,7 @@ import org.apache.doris.qe.SqlModeHelper; 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("type_cast", new Integer(SqlParserSymbols.KW_TYPECAST)); keywordMap.put("global", new Integer(SqlParserSymbols.KW_GLOBAL)); keywordMap.put("grant", new Integer(SqlParserSymbols.KW_GRANT)); keywordMap.put("grants", new Integer(SqlParserSymbols.KW_GRANTS));