diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalSetOperation.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalSetOperation.java index 9a5900908c..dd392ad16b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalSetOperation.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalSetOperation.java @@ -144,8 +144,8 @@ public abstract class LogicalSetOperation extends AbstractLogicalPlan implements Slot left = child(0).getOutput().get(i); Slot right = child(1).getOutput().get(i); DataType compatibleType = getAssignmentCompatibleType(left.getDataType(), right.getDataType()); - Expression newLeft = TypeCoercionUtils.castIfNotSameType(left, compatibleType); - Expression newRight = TypeCoercionUtils.castIfNotSameType(right, compatibleType); + Expression newLeft = TypeCoercionUtils.castIfNotSameTypeStrict(left, compatibleType); + Expression newRight = TypeCoercionUtils.castIfNotSameTypeStrict(right, compatibleType); if (newLeft instanceof Cast) { newLeft = new Alias(newLeft, left.getName()); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java index 2a6ba2f2ee..5991137f11 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java @@ -423,6 +423,20 @@ public class TypeCoercionUtils { } } + /** + * like castIfNotSameType does, but varchar or char type would be cast to target length exactly + */ + public static Expression castIfNotSameTypeStrict(Expression input, DataType targetType) { + if (input.isNullLiteral()) { + return new NullLiteral(targetType); + } else if (input.getDataType().equals(targetType) || isSubqueryAndDataTypeIsBitmap(input)) { + return input; + } else { + checkCanCastTo(input.getDataType(), targetType); + return unSafeCast(input, targetType); + } + } + private static boolean isSubqueryAndDataTypeIsBitmap(Expression input) { return input instanceof SubqueryExpr && input.getDataType().isBitmapType(); } diff --git a/regression-test/suites/nereids_p0/union/test_union.groovy b/regression-test/suites/nereids_p0/union/test_union.groovy index 536e52ba44..fda90bc1ca 100644 --- a/regression-test/suites/nereids_p0/union/test_union.groovy +++ b/regression-test/suites/nereids_p0/union/test_union.groovy @@ -320,4 +320,27 @@ suite("test_union") { sql """ insert into ${tblName1} values("1", "2", "3"),("2", "3", "4") """ qt_sql """ select a_key from (select * from ${tblName1} UNION ALL select * from ${tblName2}) t ORDER BY a_key + 1""" + + sql """DROP TABLE IF EXISTS c5770_t1""" + sql """CREATE TABLE c5770_t1 ( + `id` varchar(10) NULL + ) ENGINE=OLAP + UNIQUE KEY(`id`) + DISTRIBUTED BY HASH(`id`) BUCKETS AUTO + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1" + );""" + sql """DROP TABLE IF EXISTS c5770_t2""" + sql """CREATE TABLE c5770_t2 ( + `id` varchar(20) NULL + ) ENGINE=OLAP + UNIQUE KEY(`id`) + DISTRIBUTED BY HASH(`id`) BUCKETS AUTO + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1" + );""" + explain { + sql("""select id from ( select id from c5770_t1 union all select id from c5770_t2 ) t;""") + contains("CAST") + } }