From 3f20cf145672b23f5b55053b0ecde18e38942d76 Mon Sep 17 00:00:00 2001 From: starocean999 <40539150+starocean999@users.noreply.github.com> Date: Fri, 1 Dec 2023 18:40:06 +0800 Subject: [PATCH] [fix](nereids)set operation's result type is wrong if decimal overflows (#27870) --- .../plans/logical/LogicalSetOperation.java | 22 ++++++++++++++----- .../nereids_p0/datatype/test_cast.groovy | 19 ++++++++++++++++ 2 files changed, 36 insertions(+), 5 deletions(-) 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 dd392ad16b..0a3a29e1ef 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 @@ -17,6 +17,7 @@ package org.apache.doris.nereids.trees.plans.logical; +import org.apache.doris.catalog.ScalarType; import org.apache.doris.catalog.Type; import org.apache.doris.nereids.exceptions.AnalysisException; import org.apache.doris.nereids.memo.GroupExpression; @@ -251,10 +252,21 @@ public abstract class LogicalSetOperation extends AbstractLogicalPlan implements } return new StructType(commonFields.build()); } - return DataType.fromCatalogType(Type.getAssignmentCompatibleType( - left.toCatalogDataType(), - right.toCatalogDataType(), - false, - SessionVariable.getEnableDecimal256())); + boolean enableDecimal256 = SessionVariable.getEnableDecimal256(); + Type resultType = Type.getAssignmentCompatibleType(left.toCatalogDataType(), + right.toCatalogDataType(), false, enableDecimal256); + if (resultType.isDecimalV3()) { + int oldPrecision = resultType.getPrecision(); + int oldScale = resultType.getDecimalDigits(); + int integerPart = oldPrecision - oldScale; + int maxPrecision = enableDecimal256 ? ScalarType.MAX_DECIMAL256_PRECISION + : ScalarType.MAX_DECIMAL128_PRECISION; + if (oldPrecision > maxPrecision) { + int newScale = maxPrecision - integerPart; + resultType = + ScalarType.createDecimalType(maxPrecision, newScale < 0 ? 0 : newScale); + } + } + return DataType.fromCatalogType(resultType); } } diff --git a/regression-test/suites/nereids_p0/datatype/test_cast.groovy b/regression-test/suites/nereids_p0/datatype/test_cast.groovy index 29691297ef..30530a26da 100644 --- a/regression-test/suites/nereids_p0/datatype/test_cast.groovy +++ b/regression-test/suites/nereids_p0/datatype/test_cast.groovy @@ -94,4 +94,23 @@ suite("test_cast") { sql "select cast(true as date);" result([[null]]) } + sql """ DROP TABLE IF EXISTS table_decimal38_4;""" + sql """ + CREATE TABLE IF NOT EXISTS table_decimal38_4 ( + `k0` decimal(38, 4) + ) + DISTRIBUTED BY HASH(`k0`) BUCKETS 5 properties("replication_num" = "1"); + """ + + sql """ DROP TABLE IF EXISTS table_decimal27_9;""" + sql """ + CREATE TABLE IF NOT EXISTS table_decimal27_9 ( + `k0` decimal(27, 9) + ) + DISTRIBUTED BY HASH(`k0`) BUCKETS 5 properties("replication_num" = "1"); + """ + explain { + sql """select k0 from table_decimal38_4 union all select k0 from table_decimal27_9;""" + contains """AS DECIMALV3(38, 4)""" + } } \ No newline at end of file