diff --git a/fe/fe-core/src/main/cup/sql_parser.cup b/fe/fe-core/src/main/cup/sql_parser.cup index 587b7f865d..e25605f3e0 100644 --- a/fe/fe-core/src/main/cup/sql_parser.cup +++ b/fe/fe-core/src/main/cup/sql_parser.cup @@ -5561,7 +5561,23 @@ func_args_def ::= cast_expr ::= KW_CAST LPAREN expr:e KW_AS type_def:targetType RPAREN - {: RESULT = new CastExpr(targetType, e); :} + {: + CastExpr castExpr = new CastExpr(targetType, e); + if (targetType.getType().getLength() != -1 + && (targetType.getType().getPrimitiveType() == PrimitiveType.VARCHAR + || targetType.getType().getPrimitiveType() == PrimitiveType.CHAR)) { + // transfer cast(xx as char(N)/varchar(N)) to substr(cast(xx as char), 1, N) + // this is just a workaround to make the result correct + ArrayList exprs = new ArrayList<>(); + exprs.add(castExpr); + exprs.add(new IntLiteral(1)); + exprs.add(new IntLiteral(targetType.getType().getLength())); + RESULT = new FunctionCallExpr("substr", new FunctionParams(exprs)); + } + else { + RESULT = castExpr; + } + :} ; case_expr ::= diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java index f72c3cce8a..905720826e 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java @@ -321,8 +321,12 @@ public class CastExpr extends Expr { } if (fn == null) { - throw new AnalysisException("Invalid type cast of " + getChild(0).toSql() + if (childType.isNull() && Type.canCastTo(childType, type)) { + return; + } else { + throw new AnalysisException("Invalid type cast of " + getChild(0).toSql() + " from " + childType + " to " + type); + } } if (PrimitiveType.typeWithPrecision.contains(type.getPrimitiveType())) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/rewrite/FoldConstantsRule.java b/fe/fe-core/src/main/java/org/apache/doris/rewrite/FoldConstantsRule.java index 16dd084886..d812146a35 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/rewrite/FoldConstantsRule.java +++ b/fe/fe-core/src/main/java/org/apache/doris/rewrite/FoldConstantsRule.java @@ -110,7 +110,7 @@ public class FoldConstantsRule implements ExprRewriteRule { if (expr instanceof CastExpr) { CastExpr castExpr = (CastExpr) expr; if (castExpr.getChild(0) instanceof NullLiteral) { - return expr; + return castExpr.getChild(0); } } diff --git a/regression-test/data/query_p0/sql_functions/cast_function/test_cast_function.out b/regression-test/data/query_p0/sql_functions/cast_function/test_cast_function.out index 6577c6c9fe..af6349c750 100644 --- a/regression-test/data/query_p0/sql_functions/cast_function/test_cast_function.out +++ b/regression-test/data/query_p0/sql_functions/cast_function/test_cast_function.out @@ -11,6 +11,12 @@ -- !sql -- \N +-- !sql -- +\N + +-- !sql -- +20 + -- !sql -- 1 @@ -23,3 +29,9 @@ -- !sql -- \N +-- !sql -- +\N + +-- !sql -- +20 + diff --git a/regression-test/suites/query_p0/sql_functions/cast_function/test_cast_function.groovy b/regression-test/suites/query_p0/sql_functions/cast_function/test_cast_function.groovy index 2c94eb3bb3..4dd916141a 100644 --- a/regression-test/suites/query_p0/sql_functions/cast_function/test_cast_function.groovy +++ b/regression-test/suites/query_p0/sql_functions/cast_function/test_cast_function.groovy @@ -22,6 +22,8 @@ suite("test_cast_function") { qt_sql """ select cast(cast ("11.2" as double) as bigint) """ qt_sql """ select cast ("0.0101031417" as datetime) """ qt_sql """ select cast ("0.0000031417" as datetime) """ + qt_sql """ select cast (NULL AS CHAR(1)); """ + qt_sql """ select cast ('20190101' AS CHAR(2)); """ sql """ SET enable_vectorized_engine = FALSE; """ @@ -29,6 +31,7 @@ suite("test_cast_function") { qt_sql """ select cast(cast ("11.2" as double) as bigint) """ qt_sql """ select cast ("0.0101031417" as datetime) """ qt_sql """ select cast ("0.0000031417" as datetime) """ - + qt_sql """ select cast (NULL AS CHAR(1)); """ + qt_sql """ select cast ('20190101' AS CHAR(2)); """ }