You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by ga...@apache.org on 2023/06/02 07:06:50 UTC
[doris] branch branch-1.2-lts updated: [Bug](DecimalV3) fix decimalv3 functions (#19801) (#20364)
This is an automated email from the ASF dual-hosted git repository.
gabriellee pushed a commit to branch branch-1.2-lts
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-1.2-lts by this push:
new 3314c48cb1 [Bug](DecimalV3) fix decimalv3 functions (#19801) (#20364)
3314c48cb1 is described below
commit 3314c48cb15328112d8450ac52efc0cb0db12972
Author: Gabriel <ga...@gmail.com>
AuthorDate: Fri Jun 2 15:06:43 2023 +0800
[Bug](DecimalV3) fix decimalv3 functions (#19801) (#20364)
---
.../aggregate_functions/aggregate_function_topn.h | 9 +-
.../main/java/org/apache/doris/analysis/Expr.java | 15 ++++
.../apache/doris/analysis/FunctionCallExpr.java | 95 +++++++++++++++++++---
3 files changed, 102 insertions(+), 17 deletions(-)
diff --git a/be/src/vec/aggregate_functions/aggregate_function_topn.h b/be/src/vec/aggregate_functions/aggregate_function_topn.h
index cc5d3f6d3d..c4ccbbe1ba 100644
--- a/be/src/vec/aggregate_functions/aggregate_function_topn.h
+++ b/be/src/vec/aggregate_functions/aggregate_function_topn.h
@@ -39,8 +39,7 @@ namespace doris::vectorized {
// space-saving algorithm
template <typename T>
struct AggregateFunctionTopNData {
- using ColVecType =
- std::conditional_t<IsDecimalNumber<T>, ColumnDecimal<Decimal128>, ColumnVector<T>>;
+ using ColVecType = std::conditional_t<IsDecimalNumber<T>, ColumnDecimal<T>, ColumnVector<T>>;
void set_paramenters(int input_top_num, int space_expand_rate = 50) {
top_num = input_top_num;
capacity = (uint64_t)top_num * space_expand_rate;
@@ -206,8 +205,7 @@ struct AggregateFunctionTopNImplIntInt {
//for topn_array agg
template <typename T, bool has_default_param>
struct AggregateFunctionTopNImplArray {
- using ColVecType =
- std::conditional_t<IsDecimalNumber<T>, ColumnDecimal<Decimal128>, ColumnVector<T>>;
+ using ColVecType = std::conditional_t<IsDecimalNumber<T>, ColumnDecimal<T>, ColumnVector<T>>;
static void add(AggregateFunctionTopNData<T>& __restrict place, const IColumn** columns,
size_t row_num) {
if constexpr (has_default_param) {
@@ -231,8 +229,7 @@ struct AggregateFunctionTopNImplArray {
//for topn_weighted agg
template <typename T, bool has_default_param>
struct AggregateFunctionTopNImplWeight {
- using ColVecType =
- std::conditional_t<IsDecimalNumber<T>, ColumnDecimal<Decimal128>, ColumnVector<T>>;
+ using ColVecType = std::conditional_t<IsDecimalNumber<T>, ColumnDecimal<T>, ColumnVector<T>>;
static void add(AggregateFunctionTopNData<T>& __restrict place, const IColumn** columns,
size_t row_num) {
if constexpr (has_default_param) {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java
index 4c76d1bade..abed221866 100755
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java
@@ -965,6 +965,21 @@ public abstract class Expr extends TreeNode<Expr> implements ParseNode, Cloneabl
}
}
+ public static Type getAssignmentCompatibleType(List<Expr> children) {
+ Type assignmentCompatibleType = Type.INVALID;
+ for (int i = 0; i < children.size()
+ && (assignmentCompatibleType.isDecimalV3() || assignmentCompatibleType.isDatetimeV2()
+ || assignmentCompatibleType.isInvalid()); i++) {
+ if (children.get(i) instanceof NullLiteral) {
+ continue;
+ }
+ assignmentCompatibleType = assignmentCompatibleType.isInvalid() ? children.get(i).type
+ : ScalarType.getAssignmentCompatibleType(assignmentCompatibleType, children.get(i).type,
+ true);
+ }
+ return assignmentCompatibleType;
+ }
+
// Convert this expr into msg (excluding children), which requires setting
// msg.op as well as the expr-specific field.
protected abstract void toThrift(TExprNode msg);
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java
index 8e3ac7a1f6..e35eec84d2 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java
@@ -140,16 +140,47 @@ public class FunctionCallExpr extends Expr {
PRECISION_INFER_RULE.put("if", (children, returnType) -> {
Preconditions.checkArgument(children != null && children.size() == 3);
if (children.get(1).getType().isDecimalV3() && children.get(2).getType().isDecimalV3()) {
- return ScalarType.createDecimalV3Type(
- Math.max(((ScalarType) children.get(1).getType()).decimalPrecision(),
- ((ScalarType) children.get(2).getType()).decimalPrecision()),
- Math.max(((ScalarType) children.get(1).getType()).decimalScale(),
- ((ScalarType) children.get(2).getType()).decimalScale()));
+ return Expr.getAssignmentCompatibleType(children.subList(1, children.size()));
} else if (children.get(1).getType().isDatetimeV2() && children.get(2).getType().isDatetimeV2()) {
- return ((ScalarType) children.get(1).getType())
- .decimalScale() > ((ScalarType) children.get(2).getType()).decimalScale()
- ? children.get(1).getType()
- : children.get(2).getType();
+ return Expr.getAssignmentCompatibleType(children.subList(1, children.size()));
+ } else {
+ return returnType;
+ }
+ });
+
+ PRECISION_INFER_RULE.put("ifnull", (children, returnType) -> {
+ Preconditions.checkArgument(children != null && children.size() == 2);
+ if (children.get(0).getType().isDecimalV3() && children.get(1).getType().isDecimalV3()) {
+ return Expr.getAssignmentCompatibleType(children);
+ } else if (children.get(0).getType().isDatetimeV2() && children.get(1).getType().isDatetimeV2()) {
+ return Expr.getAssignmentCompatibleType(children);
+ } else {
+ return returnType;
+ }
+ });
+
+ PRECISION_INFER_RULE.put("nvl", (children, returnType) -> {
+ Preconditions.checkArgument(children != null && children.size() == 2);
+ if (children.get(0).getType().isDecimalV3() && children.get(1).getType().isDecimalV3()) {
+ return Expr.getAssignmentCompatibleType(children);
+ } else if (children.get(0).getType().isDatetimeV2() && children.get(1).getType().isDatetimeV2()) {
+ return Expr.getAssignmentCompatibleType(children);
+ } else {
+ return returnType;
+ }
+ });
+
+ PRECISION_INFER_RULE.put("coalesce", (children, returnType) -> {
+ boolean isDecimalV3 = true;
+ boolean isDateTimeV2 = true;
+
+ Type assignmentCompatibleType = Expr.getAssignmentCompatibleType(children);
+ for (Expr child : children) {
+ isDecimalV3 = isDecimalV3 && child.getType().isDecimalV3();
+ isDateTimeV2 = isDateTimeV2 && child.getType().isDatetimeV2();
+ }
+ if ((isDecimalV3 || isDateTimeV2) && assignmentCompatibleType.isValid()) {
+ return assignmentCompatibleType;
} else {
return returnType;
}
@@ -1222,21 +1253,63 @@ public class FunctionCallExpr extends Expr {
Type[] childTypes = collectChildReturnTypes();
Type assignmentCompatibleType = ScalarType.getAssignmentCompatibleType(childTypes[1], childTypes[2], true);
if (assignmentCompatibleType.isDecimalV3()) {
- if (childTypes[1].isDecimalV3() && !((ScalarType) childTypes[1]).equals(assignmentCompatibleType)) {
+ if (assignmentCompatibleType.isDecimalV3() && !childTypes[1].equals(assignmentCompatibleType)) {
uncheckedCastChild(assignmentCompatibleType, 1);
}
- if (childTypes[2].isDecimalV3() && !((ScalarType) childTypes[2]).equals(assignmentCompatibleType)) {
+ if (assignmentCompatibleType.isDecimalV3() && !childTypes[2].equals(assignmentCompatibleType)) {
uncheckedCastChild(assignmentCompatibleType, 2);
}
}
childTypes[1] = assignmentCompatibleType;
childTypes[2] = assignmentCompatibleType;
+
+ if (childTypes[1].isDecimalV3() && childTypes[2].isDecimalV3()) {
+ argTypes[1] = assignmentCompatibleType;
+ argTypes[2] = assignmentCompatibleType;
+ }
fn = getBuiltinFunction(fnName.getFunction(), childTypes,
Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
if (assignmentCompatibleType.isDatetimeV2()) {
fn.setReturnType(assignmentCompatibleType);
}
+ } else if (fnName.getFunction().equalsIgnoreCase("ifnull") || fnName.getFunction().equalsIgnoreCase("nvl")) {
+ Type[] childTypes = collectChildReturnTypes();
+ Type assignmentCompatibleType = ScalarType.getAssignmentCompatibleType(childTypes[0], childTypes[1], true);
+ if (assignmentCompatibleType.isDecimalV3()) {
+ if (assignmentCompatibleType.isDecimalV3() && !childTypes[0].equals(assignmentCompatibleType)) {
+ uncheckedCastChild(assignmentCompatibleType, 0);
+ }
+ if (assignmentCompatibleType.isDecimalV3() && !childTypes[1].equals(assignmentCompatibleType)) {
+ uncheckedCastChild(assignmentCompatibleType, 1);
+ }
+ }
+ childTypes[0] = assignmentCompatibleType;
+ childTypes[1] = assignmentCompatibleType;
+
+ if (childTypes[1].isDecimalV3() && childTypes[0].isDecimalV3()) {
+ argTypes[1] = assignmentCompatibleType;
+ argTypes[0] = assignmentCompatibleType;
+ }
+ fn = getBuiltinFunction(fnName.getFunction(), childTypes,
+ Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
+ } else if (fnName.getFunction().equalsIgnoreCase("coalesce") && children.size() > 1) {
+ Type[] childTypes = collectChildReturnTypes();
+ Type assignmentCompatibleType = childTypes[0];
+ for (int i = 1; i < childTypes.length && assignmentCompatibleType.isDecimalV3(); i++) {
+ assignmentCompatibleType =
+ ScalarType.getAssignmentCompatibleType(assignmentCompatibleType, childTypes[i], true);
+ }
+ if (assignmentCompatibleType.isDecimalV3()) {
+ for (int i = 0; i < childTypes.length; i++) {
+ if (assignmentCompatibleType.isDecimalV3() && !childTypes[i].equals(assignmentCompatibleType)) {
+ uncheckedCastChild(assignmentCompatibleType, i);
+ argTypes[i] = assignmentCompatibleType;
+ }
+ }
+ }
+ fn = getBuiltinFunction(fnName.getFunction(), childTypes,
+ Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
} else if (AggregateFunction.SUPPORT_ORDER_BY_AGGREGATE_FUNCTION_NAME_SET.contains(
fnName.getFunction().toLowerCase())) {
// order by elements add as child like windows function. so if we get the
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org