diff --git a/docs/en/docs/sql-manual/sql-reference/Data-Types/DECIMALV3.md b/docs/en/docs/sql-manual/sql-reference/Data-Types/DECIMALV3.md index c5d5c7d10b..c8f228a80b 100644 --- a/docs/en/docs/sql-manual/sql-reference/Data-Types/DECIMALV3.md +++ b/docs/en/docs/sql-manual/sql-reference/Data-Types/DECIMALV3.md @@ -48,7 +48,7 @@ DECIMALV3 has a very complex set of type inference rules. For different expressi #### Arithmetic Expressions * Plus / Minus: DECIMALV3(a, b) + DECIMALV3(x, y) -> DECIMALV3(max(a - b, x - y) + max(b, y), max(b, y)). That is, the integer part and the decimal part use the larger value of the two operands respectively. -* Multiply: DECIMALV3(a, b) + DECIMALV3(x, y) -> DECIMALV3(max(a, x), max(b, y)). +* Multiply: DECIMALV3(a, b) + DECIMALV3(x, y) -> DECIMALV3(a + x, b + y). * Divide: DECIMALV3(a, b) + DECIMALV3(x, y) -> DECIMALV3(a + y, b). #### Aggregation functions diff --git a/docs/zh-CN/docs/sql-manual/sql-reference/Data-Types/DECIMALV3.md b/docs/zh-CN/docs/sql-manual/sql-reference/Data-Types/DECIMALV3.md index 4d238ddc70..ff9d64c472 100644 --- a/docs/zh-CN/docs/sql-manual/sql-reference/Data-Types/DECIMALV3.md +++ b/docs/zh-CN/docs/sql-manual/sql-reference/Data-Types/DECIMALV3.md @@ -46,7 +46,7 @@ DECIMALV3有一套很复杂的类型推演规则,针对不同的表达式, #### 四则运算 * 加法 / 减法:DECIMALV3(a, b) + DECIMALV3(x, y) -> DECIMALV3(max(a - b, x - y) + max(b, y), max(b, y)),即整数部分和小数部分都分别使用两个操作数中较大的值。 -* 乘法:DECIMALV3(a, b) + DECIMALV3(x, y) -> DECIMALV3(max(a, x), max(b, y))。 +* 乘法:DECIMALV3(a, b) + DECIMALV3(x, y) -> DECIMALV3(a + x, b + y)。 * 除法:DECIMALV3(a, b) + DECIMALV3(x, y) -> DECIMALV3(a + y, b)。 #### 聚合运算 diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/ScalarType.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/ScalarType.java index e97471f73d..3cd713b507 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/ScalarType.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/ScalarType.java @@ -1022,9 +1022,13 @@ public class ScalarType extends Type { } if (t1.isDecimalV3() && t2.isDecimalV3()) { - return ScalarType.createDecimalV3Type(Math.max(t1.decimalPrecision() - t1.decimalScale(), - t2.decimalPrecision() - t2.decimalScale()) + Math.max(t1.decimalScale(), - t2.decimalScale()), Math.max(t1.decimalScale(), t2.decimalScale())); + ScalarType finalType = ScalarType.createDecimalV3Type(Math.max(t1.decimalPrecision() - t1.decimalScale(), + t2.decimalPrecision() - t2.decimalScale()) + Math.max(t1.decimalScale(), + t2.decimalScale()), Math.max(t1.decimalScale(), t2.decimalScale())); + if (finalType.getPrecision() > MAX_PRECISION) { + finalType = ScalarType.createDecimalV3Type(MAX_PRECISION, finalType.getScalarScale()); + } + return finalType; } PrimitiveType smallerType = diff --git a/regression-test/data/datatype_p0/decimalv3/test_arithmetic_expressions.out b/regression-test/data/datatype_p0/decimalv3/test_arithmetic_expressions.out new file mode 100644 index 0000000000..a8d9df8d8d --- /dev/null +++ b/regression-test/data/datatype_p0/decimalv3/test_arithmetic_expressions.out @@ -0,0 +1,19 @@ +-- This file is automatically generated. You should know what you did if you want to edit this +-- !select_all -- +1.100000000000000000 1.200000000000000000 1.300000000000000000 +1.200000000000000000 1.200000000000000000 1.300000000000000000 +1.500000000000000000 1.200000000000000000 1.300000000000000000 + +-- !select -- +1.320000000000000000000000000000000000 +1.440000000000000000000000000000000000 +1.800000000000000000000000000000000000 + +-- !select -- +1.300000000000000000000000000000000000 +1.300000000000000000000000000000000000 +1.300000000000000000000000000000000000 +1.320000000000000000000000000000000000 +1.440000000000000000000000000000000000 +1.800000000000000000000000000000000000 + diff --git a/regression-test/suites/datatype_p0/decimalv3/test_arithmetic_expressions.groovy b/regression-test/suites/datatype_p0/decimalv3/test_arithmetic_expressions.groovy new file mode 100644 index 0000000000..44cd313fa0 --- /dev/null +++ b/regression-test/suites/datatype_p0/decimalv3/test_arithmetic_expressions.groovy @@ -0,0 +1,49 @@ +// 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. + +suite("test_arithmetic_expressions") { + + def table1 = "test_arithmetic_expressions" + + sql "drop table if exists ${table1}" + + sql """ + CREATE TABLE IF NOT EXISTS `${table1}` ( + `k1` decimalv3(38, 18) NULL COMMENT "", + `k2` decimalv3(38, 18) NULL COMMENT "", + `k3` decimalv3(38, 18) NULL COMMENT "" + ) ENGINE=OLAP + COMMENT "OLAP" + DISTRIBUTED BY HASH(`k1`, `k2`, `k3`) BUCKETS 8 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1", + "in_memory" = "false", + "storage_format" = "V2" + ) + """ + + sql """insert into ${table1} values(1.1,1.2,1.3), + (1.2,1.2,1.3), + (1.5,1.2,1.3) + """ + qt_select_all "select * from ${table1} order by k1" + + qt_select "select k1 * k2 from ${table1} order by k1" + qt_select "select * from (select k1 * k2 from ${table1} union all select k3 from ${table1}) a order by 1" + + sql "drop table if exists ${table1}" +}