This is an automated email from the ASF dual-hosted git repository. yiguolei pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push: new 27be5e8667 [feature-wip](decimalv3) Fix UTs when `decimalv3` is enabled (#11380) 27be5e8667 is described below commit 27be5e8667312d51060526b35371333122555c75 Author: Gabriel <gabrielleeb...@gmail.com> AuthorDate: Mon Aug 1 23:07:38 2022 +0800 [feature-wip](decimalv3) Fix UTs when `decimalv3` is enabled (#11380) --- .../aggregate_function_collect.cpp | 4 + .../aggregate_function_uniq.cpp | 6 +- fe/fe-core/src/main/cup/sql_parser.cup | 14 ++- .../org/apache/doris/analysis/ArithmeticExpr.java | 15 +++- .../java/org/apache/doris/analysis/CastExpr.java | 7 +- .../apache/doris/analysis/ExpressionFunctions.java | 2 + .../apache/doris/analysis/FunctionCallExpr.java | 5 +- .../java/org/apache/doris/analysis/IntLiteral.java | 2 +- .../org/apache/doris/catalog/AggregateType.java | 9 ++ .../org/apache/doris/catalog/AliasFunction.java | 3 + .../java/org/apache/doris/catalog/ScalarType.java | 100 ++++++++++++--------- .../main/java/org/apache/doris/common/Config.java | 6 ++ .../java/org/apache/doris/rewrite/FEFunctions.java | 27 ------ .../doris/rewrite/RewriteBinaryPredicatesRule.java | 3 +- .../RoundLiteralInBinaryPredicatesRule.java | 64 +++++++------ fe/fe-core/src/main/jflex/sql_scanner.flex | 1 + .../apache/doris/analysis/DecimalLiteralTest.java | 5 +- .../org/apache/doris/analysis/QueryStmtTest.java | 6 +- .../org/apache/doris/catalog/ColumnTypeTest.java | 21 ++++- .../apache/doris/catalog/CreateFunctionTest.java | 7 +- .../rewrite/RewriteBinaryPredicatesRuleTest.java | 13 ++- .../doris/rewrite/RewriteDateLiteralRuleTest.java | 24 ++++- 22 files changed, 229 insertions(+), 115 deletions(-) diff --git a/be/src/vec/aggregate_functions/aggregate_function_collect.cpp b/be/src/vec/aggregate_functions/aggregate_function_collect.cpp index 9f58b8ee17..34b7c7e777 100644 --- a/be/src/vec/aggregate_functions/aggregate_function_collect.cpp +++ b/be/src/vec/aggregate_functions/aggregate_function_collect.cpp @@ -64,6 +64,10 @@ AggregateFunctionPtr create_aggregate_function_collect(const std::string& name, return create_agg_function_collect<Float32>(distinct, argument_types); } else if (type.is_float64()) { return create_agg_function_collect<Float64>(distinct, argument_types); + } else if (type.is_decimal32()) { + return create_agg_function_collect<Decimal32>(distinct, argument_types); + } else if (type.is_decimal64()) { + return create_agg_function_collect<Decimal64>(distinct, argument_types); } else if (type.is_decimal128()) { return create_agg_function_collect<Decimal128>(distinct, argument_types); } else if (type.is_date()) { diff --git a/be/src/vec/aggregate_functions/aggregate_function_uniq.cpp b/be/src/vec/aggregate_functions/aggregate_function_uniq.cpp index f90b4ba4d9..e9a66901b6 100644 --- a/be/src/vec/aggregate_functions/aggregate_function_uniq.cpp +++ b/be/src/vec/aggregate_functions/aggregate_function_uniq.cpp @@ -50,7 +50,11 @@ AggregateFunctionPtr create_aggregate_function_uniq(const std::string& name, // TODO: DateType if (res) { return res; - } else if (which.is_decimal()) { + } else if (which.is_decimal32()) { + return std::make_shared<AggregateFunctionUniq<Decimal32, Data<Int32>>>(argument_types); + } else if (which.is_decimal64()) { + return std::make_shared<AggregateFunctionUniq<Decimal64, Data<Int64>>>(argument_types); + } else if (which.is_decimal128()) { return std::make_shared<AggregateFunctionUniq<Decimal128, Data<Int128>>>( argument_types); } else if (which.is_string_or_fixed_string()) { diff --git a/fe/fe-core/src/main/cup/sql_parser.cup b/fe/fe-core/src/main/cup/sql_parser.cup index d938b10201..131a337e7a 100644 --- a/fe/fe-core/src/main/cup/sql_parser.cup +++ b/fe/fe-core/src/main/cup/sql_parser.cup @@ -244,7 +244,7 @@ terminal String KW_ADD, KW_ADMIN, KW_AFTER, KW_AGGREGATE, KW_ALIAS, KW_ALL, KW_A KW_CANCEL, KW_CASE, KW_CAST, KW_CHAIN, KW_CHAR, KW_CHARSET, KW_CHECK, KW_CLUSTER, KW_CLUSTERS, KW_CLEAN, KW_CURRENT_TIMESTAMP, KW_COLLATE, KW_COLLATION, KW_COLUMN, KW_COLUMNS, KW_COMMENT, KW_COMMIT, KW_COMMITTED, KW_COMPACT, KW_CONFIG, KW_CONNECTION, KW_CONNECTION_ID, KW_CONSISTENT, KW_CONVERT, KW_COUNT, KW_CREATE, KW_CREATION, KW_CROSS, KW_CUBE, KW_CURRENT, KW_CURRENT_USER, - KW_DATA, KW_DATABASE, KW_DATABASES, KW_DATE, KW_DATETIME, KW_DATEV2, KW_DATETIMEV2, KW_DAY, KW_DECIMAL, KW_DECOMMISSION, KW_DEFAULT, KW_DESC, KW_DESCRIBE, + KW_DATA, KW_DATABASE, KW_DATABASES, KW_DATE, KW_DATETIME, KW_DATEV2, KW_DATETIMEV2, KW_DAY, KW_DECIMAL, KW_DECIMALV3, KW_DECOMMISSION, KW_DEFAULT, KW_DESC, KW_DESCRIBE, KW_DELETE, KW_UPDATE, KW_DIAGNOSE, KW_DISK, KW_DISTINCT, KW_DISTINCTPC, KW_DISTINCTPCSA, KW_DISTRIBUTED, KW_DISTRIBUTION, KW_DYNAMIC, KW_BUCKETS, KW_DIV, KW_DOUBLE, KW_DROP, KW_DROPP, KW_DUPLICATE, KW_ELSE, KW_ENABLE, KW_ENCRYPTKEY, KW_ENCRYPTKEYS, KW_END, KW_ENGINE, KW_ENGINES, KW_ENTER, KW_ERRORS, KW_EVENTS, KW_EXCEPT, KW_EXCLUDE, KW_EXISTS, KW_EXPORT, KW_EXTENDED, KW_EXTERNAL, KW_EXTRACT, @@ -4757,6 +4757,16 @@ type ::= {: RESULT = ScalarType.createDecimalType(precision); :} | KW_DECIMAL LPAREN ident_or_text:precision COMMA ident_or_text:scale RPAREN {: RESULT = ScalarType.createDecimalType(precision, scale); :} + | KW_DECIMALV3 LPAREN INTEGER_LITERAL:precision RPAREN + {: RESULT = ScalarType.createDecimalV3Type(precision.intValue()); :} + | KW_DECIMALV3 LPAREN INTEGER_LITERAL:precision COMMA INTEGER_LITERAL:scale RPAREN + {: RESULT = ScalarType.createDecimalV3Type(precision.intValue(), scale.intValue()); :} + | KW_DECIMALV3 + {: RESULT = ScalarType.createDecimalV3Type(); :} + | KW_DECIMALV3 LPAREN ident_or_text:precision RPAREN + {: RESULT = ScalarType.createDecimalV3Type(precision); :} + | KW_DECIMALV3 LPAREN ident_or_text:precision COMMA ident_or_text:scale RPAREN + {: RESULT = ScalarType.createDecimalV3Type(precision, scale); :} | KW_HLL {: ScalarType type = ScalarType.createHllType(); type.setAssignedStrLenInColDefinition(); @@ -5677,6 +5687,8 @@ keyword ::= {: RESULT = id; :} | KW_DECIMAL:id {: RESULT = id; :} + | KW_DECIMALV3:id + {: RESULT = id; :} | KW_DIAGNOSE:id {: RESULT = id; :} | KW_DISTINCTPC:id diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/ArithmeticExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/ArithmeticExpr.java index ca0342a4bd..0e8619b827 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/ArithmeticExpr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ArithmeticExpr.java @@ -37,6 +37,7 @@ import com.google.common.collect.Lists; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -528,7 +529,19 @@ public class ArithmeticExpr extends Expr { } else { analyzeNoneDecimalOp(t1, t2); } - fn = getBuiltinFunction(op.name, collectChildReturnTypes(), Function.CompareMode.IS_IDENTICAL); + fn = getBuiltinFunction(op.name, Arrays.stream(collectChildReturnTypes()).map( + (Type type) -> { + if (type.getPrimitiveType() == PrimitiveType.DECIMAL32) { + return Type.DECIMAL32; + } else if (type.getPrimitiveType() == PrimitiveType.DECIMAL64) { + return Type.DECIMAL64; + } else if (type.getPrimitiveType() == PrimitiveType.DECIMAL128) { + return Type.DECIMAL128; + } else if (type.getPrimitiveType() == PrimitiveType.DATETIMEV2) { + return Type.DATETIMEV2; + } + return type; + }).toArray(Type[]::new), Function.CompareMode.IS_IDENTICAL); if (fn == null) { Preconditions.checkState(false, String.format( "No match for vec function '%s' with operand types %s and %s", toSql(), t1, t2)); 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 523c239cc6..bb1f8f4ef6 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 @@ -311,7 +311,12 @@ public class CastExpr extends Expr { + " from " + childType + " to " + type); } - Preconditions.checkState(type.matchesType(fn.getReturnType()), type + " != " + fn.getReturnType()); + if (PrimitiveType.typeWithPrecision.contains(type.getPrimitiveType())) { + Preconditions.checkState(type.getPrimitiveType() == fn.getReturnType().getPrimitiveType(), + type + " != " + fn.getReturnType()); + } else { + Preconditions.checkState(type.matchesType(fn.getReturnType()), type + " != " + fn.getReturnType()); + } } @Override diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/ExpressionFunctions.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/ExpressionFunctions.java index cf48861964..1162827784 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/ExpressionFunctions.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ExpressionFunctions.java @@ -119,6 +119,7 @@ public enum ExpressionFunctions { // Make functions for date/datetime applicable to datev2/datetimev2 if (!(invoker.getSignature().returnType.isDate() && signature.getReturnType().isDateV2()) && !(invoker.getSignature().returnType.isDatetime() && signature.getReturnType().isDatetimeV2()) + && !(invoker.getSignature().returnType.isDecimalV2() && signature.getReturnType().isDecimalV3()) && !invoker.getSignature().returnType.equals(signature.getReturnType())) { continue; } @@ -133,6 +134,7 @@ public enum ExpressionFunctions { for (int i = 0; i < argTypes1.length; i++) { if (!(argTypes1[i].isDate() && argTypes2[i].isDateV2()) && !(argTypes1[i].isDatetime() && argTypes2[i].isDatetimeV2()) + && !(argTypes1[i].isDecimalV2() && argTypes2[i].isDecimalV3()) && !argTypes1[i].equals(argTypes2[i])) { match = false; break; 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 07cd36f260..ad9b2feb7a 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 @@ -1137,11 +1137,12 @@ public class FunctionCallExpr extends Expr { if (DECIMAL_SAME_TYPE_SET.contains(fnName.getFunction())) { this.type = argTypes[0]; } else if (DECIMAL_WIDER_TYPE_SET.contains(fnName.getFunction())) { - this.type = ScalarType.createDecimalType(ScalarType.MAX_DECIMAL128_PRECISION, + this.type = ScalarType.createDecimalV3Type(ScalarType.MAX_DECIMAL128_PRECISION, ((ScalarType) argTypes[0]).getScalarScale()); } else if (STDDEV_FUNCTION_SET.contains(fnName.getFunction())) { // for all stddev function, use decimal(38,9) as computing result - this.type = ScalarType.createDecimalType(ScalarType.MAX_DECIMAL128_PRECISION, STDDEV_DECIMAL_SCALE); + this.type = ScalarType.createDecimalV3Type(ScalarType.MAX_DECIMAL128_PRECISION, + STDDEV_DECIMAL_SCALE); } } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/IntLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/IntLiteral.java index 4d4f673822..6a66f9d2c4 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/IntLiteral.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/IntLiteral.java @@ -305,7 +305,7 @@ public class IntLiteral extends LiteralExpr { } } else if (targetType.isFloatingPointType()) { return new FloatLiteral(new Double(value), targetType); - } else if (targetType.isDecimalV2()) { + } else if (targetType.isDecimalV2() || targetType.isDecimalV3()) { return new DecimalLiteral(new BigDecimal(value)); } return this; diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/AggregateType.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/AggregateType.java index fca359d149..d3fd46e923 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/AggregateType.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/AggregateType.java @@ -51,6 +51,9 @@ public enum AggregateType { primitiveTypeList.add(PrimitiveType.FLOAT); primitiveTypeList.add(PrimitiveType.DOUBLE); primitiveTypeList.add(PrimitiveType.DECIMALV2); + primitiveTypeList.add(PrimitiveType.DECIMAL32); + primitiveTypeList.add(PrimitiveType.DECIMAL64); + primitiveTypeList.add(PrimitiveType.DECIMAL128); compatibilityMap.put(SUM, EnumSet.copyOf(primitiveTypeList)); primitiveTypeList.clear(); @@ -62,6 +65,9 @@ public enum AggregateType { primitiveTypeList.add(PrimitiveType.FLOAT); primitiveTypeList.add(PrimitiveType.DOUBLE); primitiveTypeList.add(PrimitiveType.DECIMALV2); + primitiveTypeList.add(PrimitiveType.DECIMAL32); + primitiveTypeList.add(PrimitiveType.DECIMAL64); + primitiveTypeList.add(PrimitiveType.DECIMAL128); primitiveTypeList.add(PrimitiveType.DATE); primitiveTypeList.add(PrimitiveType.DATETIME); primitiveTypeList.add(PrimitiveType.DATEV2); @@ -80,6 +86,9 @@ public enum AggregateType { primitiveTypeList.add(PrimitiveType.FLOAT); primitiveTypeList.add(PrimitiveType.DOUBLE); primitiveTypeList.add(PrimitiveType.DECIMALV2); + primitiveTypeList.add(PrimitiveType.DECIMAL32); + primitiveTypeList.add(PrimitiveType.DECIMAL64); + primitiveTypeList.add(PrimitiveType.DECIMAL128); primitiveTypeList.add(PrimitiveType.DATE); primitiveTypeList.add(PrimitiveType.DATETIME); primitiveTypeList.add(PrimitiveType.DATEV2); diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/AliasFunction.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/AliasFunction.java index 447cd705ba..710c59c47d 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/AliasFunction.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/AliasFunction.java @@ -171,6 +171,9 @@ public class AliasFunction extends Function { ScalarType scalarType = (ScalarType) targetTypeDef.getType(); PrimitiveType primitiveType = scalarType.getPrimitiveType(); switch (primitiveType) { + case DECIMAL32: + case DECIMAL64: + case DECIMAL128: case DECIMALV2: if (!Strings.isNullOrEmpty(scalarType.getScalarPrecisionStr())) { typeDefParams.add(scalarType.getScalarPrecisionStr()); 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 8b20a8f074..5421e51b03 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 @@ -240,10 +240,9 @@ public class ScalarType extends Type { return TIME; case "DECIMAL": case "DECIMALV2": - case "DECIMAL32": - case "DECIMAL64": - case "DECIMAL128": return (ScalarType) createDecimalType(); + case "DECIMALV3": + return (ScalarType) createDecimalV3Type(); case "LARGEINT": return LARGEINT; default: @@ -272,7 +271,7 @@ public class ScalarType extends Type { } public static ScalarType createDecimalType() { - if (Config.enable_decimalv3) { + if (Config.enable_decimalv3 && Config.enable_decimal_conversion) { return DEFAULT_DECIMALV3; } else { return DEFAULT_DECIMALV2; @@ -284,7 +283,7 @@ public class ScalarType extends Type { } public static ScalarType createDecimalType(int precision, int scale) { - ScalarType type = new ScalarType(getSuitableDecimalType(precision)); + ScalarType type = new ScalarType(getSuitableDecimalType(precision, true)); type.precision = precision; type.scale = scale; return type; @@ -299,7 +298,7 @@ public class ScalarType extends Type { public static ScalarType createDecimalType(String precisionStr) { int precision = Integer.parseInt(precisionStr); - ScalarType type = new ScalarType(getSuitableDecimalType(precision)); + ScalarType type = new ScalarType(getSuitableDecimalType(precision, true)); type.precisionStr = precisionStr; type.scaleStr = null; return type; @@ -312,22 +311,51 @@ public class ScalarType extends Type { return type; } - public static PrimitiveType getSuitableDecimalType(int precision) { - if (Config.enable_decimalv3) { - if (precision <= MAX_DECIMAL32_PRECISION) { - return PrimitiveType.DECIMAL32; - } else if (precision <= MAX_DECIMAL64_PRECISION) { - return PrimitiveType.DECIMAL64; - } else { - return PrimitiveType.DECIMAL128; - } - } else { + public static ScalarType createDecimalV3Type() { + return DEFAULT_DECIMALV3; + } + + public static ScalarType createDecimalV3Type(int precision) { + return createDecimalV3Type(precision, DEFAULT_SCALE); + } + + public static ScalarType createDecimalV3Type(int precision, int scale) { + ScalarType type = new ScalarType(getSuitableDecimalType(precision, false)); + type.precision = precision; + type.scale = scale; + return type; + } + + public static ScalarType createDecimalV3Type(String precisionStr) { + int precision = Integer.parseInt(precisionStr); + ScalarType type = new ScalarType(getSuitableDecimalType(precision, false)); + type.precisionStr = precisionStr; + type.scaleStr = null; + return type; + } + + public static ScalarType createDecimalV3Type(String precisionStr, String scaleStr) { + ScalarType type = new ScalarType(getSuitableDecimalType(Integer.parseInt(precisionStr), false)); + type.precisionStr = precisionStr; + type.scaleStr = scaleStr; + return type; + } + + public static PrimitiveType getSuitableDecimalType(int precision, boolean decimalV2) { + if ((decimalV2 && !Config.enable_decimal_conversion) || !Config.enable_decimalv3) { return PrimitiveType.DECIMALV2; } + if (precision <= MAX_DECIMAL32_PRECISION) { + return PrimitiveType.DECIMAL32; + } else if (precision <= MAX_DECIMAL64_PRECISION) { + return PrimitiveType.DECIMAL64; + } else { + return PrimitiveType.DECIMAL128; + } } - public static ScalarType createDecimalTypeInternal(int precision, int scale) { - ScalarType type = new ScalarType(getSuitableDecimalType(precision)); + public static ScalarType createDecimalTypeInternal(int precision, int scale, boolean decimalV2) { + ScalarType type = new ScalarType(getSuitableDecimalType(precision, decimalV2)); type.precision = Math.min(precision, MAX_PRECISION); type.scale = Math.min(type.precision, scale); return type; @@ -471,21 +499,11 @@ public class ScalarType extends Type { return "DECIMAL(*,*)"; } return "DECIMAL(" + precision + "," + scale + ")"; - } else if (type == PrimitiveType.DECIMAL32) { - if (isWildcardDecimal()) { - return "DECIMAL32(*,*)"; - } - return "DECIMAL32(" + precision + "," + scale + ")"; - } else if (type == PrimitiveType.DECIMAL64) { - if (isWildcardDecimal()) { - return "DECIMAL64(*,*)"; - } - return "DECIMAL64(" + precision + "," + scale + ")"; - } else if (type == PrimitiveType.DECIMAL128) { + } else if (type.isDecimalV3Type()) { if (isWildcardDecimal()) { - return "DECIMAL128(*,*)"; + return "DECIMALV3(*,*)"; } - return "DECIMAL128(" + precision + "," + scale + ")"; + return "DECIMALV3(" + precision + "," + scale + ")"; } else if (type == PrimitiveType.DATETIMEV2) { return "DATETIMEV2(" + scale + ")"; } else if (type == PrimitiveType.TIMEV2) { @@ -805,13 +823,13 @@ public class ScalarType extends Type { } else if (isNull()) { return ScalarType.NULL; } else if (isDecimalV2()) { - return createDecimalTypeInternal(MAX_PRECISION, scale); + return createDecimalTypeInternal(MAX_PRECISION, scale, true); } else if (getPrimitiveType() == PrimitiveType.DECIMAL32) { - return createDecimalTypeInternal(MAX_DECIMAL32_PRECISION, scale); + return createDecimalTypeInternal(MAX_DECIMAL32_PRECISION, scale, false); } else if (getPrimitiveType() == PrimitiveType.DECIMAL64) { - return createDecimalTypeInternal(MAX_DECIMAL64_PRECISION, scale); + return createDecimalTypeInternal(MAX_DECIMAL64_PRECISION, scale, false); } else if (getPrimitiveType() == PrimitiveType.DECIMAL128) { - return createDecimalTypeInternal(MAX_DECIMAL128_PRECISION, scale); + return createDecimalTypeInternal(MAX_DECIMAL128_PRECISION, scale, false); } else if (isLargeIntType()) { return ScalarType.LARGEINT; } else if (isDatetimeV2()) { @@ -828,13 +846,13 @@ public class ScalarType extends Type { if (type == PrimitiveType.DOUBLE || type == PrimitiveType.BIGINT || isNull()) { return this; } else if (type == PrimitiveType.DECIMALV2) { - return createDecimalTypeInternal(MAX_PRECISION, scale); + return createDecimalTypeInternal(MAX_PRECISION, scale, true); } else if (type == PrimitiveType.DECIMAL32) { - return createDecimalTypeInternal(MAX_DECIMAL64_PRECISION, scale); + return createDecimalTypeInternal(MAX_DECIMAL64_PRECISION, scale, false); } else if (type == PrimitiveType.DECIMAL64) { - return createDecimalTypeInternal(MAX_DECIMAL128_PRECISION, scale); + return createDecimalTypeInternal(MAX_DECIMAL128_PRECISION, scale, false); } else if (type == PrimitiveType.DECIMAL128) { - return createDecimalTypeInternal(MAX_DECIMAL128_PRECISION, scale); + return createDecimalTypeInternal(MAX_DECIMAL128_PRECISION, scale, false); } else if (type == PrimitiveType.DATETIMEV2) { return createDatetimeV2Type(6); } else if (type == PrimitiveType.TIMEV2) { @@ -862,9 +880,9 @@ public class ScalarType extends Type { case BIGINT: return createDecimalType(19); case FLOAT: - return createDecimalTypeInternal(MAX_PRECISION, 9); + return createDecimalTypeInternal(MAX_PRECISION, 9, false); case DOUBLE: - return createDecimalTypeInternal(MAX_PRECISION, 17); + return createDecimalTypeInternal(MAX_PRECISION, 17, false); default: return ScalarType.INVALID; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/common/Config.java b/fe/fe-core/src/main/java/org/apache/doris/common/Config.java index 0a6cceb157..db65ad2f19 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/common/Config.java +++ b/fe/fe-core/src/main/java/org/apache/doris/common/Config.java @@ -1714,4 +1714,10 @@ public class Config extends ConfigBase { @ConfField(mutable = false, masterOnly = true) public static boolean enable_multi_tags = false; + + /** + * If set to TRUE, FE will convert DecimalV2 to DecimalV3 automatically. + */ + @ConfField(mutable = true, masterOnly = true) + public static boolean enable_decimal_conversion = false; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/rewrite/FEFunctions.java b/fe/fe-core/src/main/java/org/apache/doris/rewrite/FEFunctions.java index c3da65f9e2..cde27855cf 100755 --- a/fe/fe-core/src/main/java/org/apache/doris/rewrite/FEFunctions.java +++ b/fe/fe-core/src/main/java/org/apache/doris/rewrite/FEFunctions.java @@ -398,33 +398,6 @@ public class FEFunctions { return new DecimalLiteral(result); } - @FEFunction(name = "add", argTypes = { "DECIMAL32", "DECIMAL32" }, returnType = "DECIMAL32") - public static DecimalLiteral addDecimal32(LiteralExpr first, LiteralExpr second) throws AnalysisException { - BigDecimal left = new BigDecimal(first.getStringValue()); - BigDecimal right = new BigDecimal(second.getStringValue()); - - BigDecimal result = left.add(right); - return new DecimalLiteral(result); - } - - @FEFunction(name = "add", argTypes = { "DECIMAL64", "DECIMAL64" }, returnType = "DECIMAL64") - public static DecimalLiteral addDecimal64(LiteralExpr first, LiteralExpr second) throws AnalysisException { - BigDecimal left = new BigDecimal(first.getStringValue()); - BigDecimal right = new BigDecimal(second.getStringValue()); - - BigDecimal result = left.add(right); - return new DecimalLiteral(result); - } - - @FEFunction(name = "add", argTypes = { "DECIMAL128", "DECIMAL128" }, returnType = "DECIMAL128") - public static DecimalLiteral addDecimal128(LiteralExpr first, LiteralExpr second) throws AnalysisException { - BigDecimal left = new BigDecimal(first.getStringValue()); - BigDecimal right = new BigDecimal(second.getStringValue()); - - BigDecimal result = left.add(right); - return new DecimalLiteral(result); - } - @FEFunction(name = "add", argTypes = { "LARGEINT", "LARGEINT" }, returnType = "LARGEINT") public static LargeIntLiteral addBigInt(LiteralExpr first, LiteralExpr second) throws AnalysisException { BigInteger left = new BigInteger(first.getStringValue()); diff --git a/fe/fe-core/src/main/java/org/apache/doris/rewrite/RewriteBinaryPredicatesRule.java b/fe/fe-core/src/main/java/org/apache/doris/rewrite/RewriteBinaryPredicatesRule.java index a18797b657..32c4e3597b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/rewrite/RewriteBinaryPredicatesRule.java +++ b/fe/fe-core/src/main/java/org/apache/doris/rewrite/RewriteBinaryPredicatesRule.java @@ -121,7 +121,8 @@ public class RewriteBinaryPredicatesRule implements ExprRewriteRule { BinaryPredicate.Operator op = ((BinaryPredicate) expr).getOp(); Expr expr0 = expr.getChild(0); Expr expr1 = expr.getChild(1); - if (expr0 instanceof CastExpr && expr0.getType() == Type.DECIMALV2 && expr0.getChild(0) instanceof SlotRef + if (expr0 instanceof CastExpr && (expr0.getType() == Type.DECIMALV2 || expr0.getType().isDecimalV3()) + && expr0.getChild(0) instanceof SlotRef && expr0.getChild(0).getType().getResultType() == Type.BIGINT && expr1 instanceof DecimalLiteral) { return rewriteBigintSlotRefCompareDecimalLiteral(expr0, (DecimalLiteral) expr1, op); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/rewrite/RoundLiteralInBinaryPredicatesRule.java b/fe/fe-core/src/main/java/org/apache/doris/rewrite/RoundLiteralInBinaryPredicatesRule.java index 8c0306f8e6..76e9081b79 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/rewrite/RoundLiteralInBinaryPredicatesRule.java +++ b/fe/fe-core/src/main/java/org/apache/doris/rewrite/RoundLiteralInBinaryPredicatesRule.java @@ -44,41 +44,46 @@ public class RoundLiteralInBinaryPredicatesRule implements ExprRewriteRule { if (expr0.getType().isDecimalV3() && ((ScalarType) expr0.getType()).getScalarScale() < ((ScalarType) expr1.getType()).getScalarScale()) { - switch (op) { - case EQ: { - BigDecimal originValue = literal.getValue(); - literal.roundCeiling(((ScalarType) expr0.getType()).getScalarScale()); - if (literal.getValue().equals(originValue)) { + int toScale = ((ScalarType) expr0.getType()).getScalarScale(); + try { + switch (op) { + case EQ: { + BigDecimal originValue = literal.getValue(); + literal.roundCeiling(); + if (literal.getValue().equals(originValue.setScale(toScale))) { + expr.setChild(1, literal); + return expr; + } else { + return new BoolLiteral(false); + } + } + case NE: { + BigDecimal originValue = literal.getValue(); + literal.roundCeiling(toScale); + if (literal.getValue().equals(originValue.setScale(toScale))) { + expr.setChild(1, literal); + return expr; + } else { + return new BoolLiteral(true); + } + } + case GT: + case LE: { + literal.roundFloor(toScale); expr.setChild(1, literal); return expr; - } else { - return new BoolLiteral(false); } - } - case NE: { - BigDecimal originValue = literal.getValue(); - literal.roundCeiling(((ScalarType) expr0.getType()).getScalarScale()); - if (literal.getValue().equals(originValue)) { + case LT: + case GE: { + literal.roundCeiling(toScale); expr.setChild(1, literal); return expr; - } else { - return new BoolLiteral(true); } + default: + return expr; } - case GT: - case LE: { - literal.roundFloor(((ScalarType) expr0.getType()).getScalarScale()); - expr.setChild(1, literal); - return expr; - } - case LT: - case GE: { - literal.roundCeiling(((ScalarType) expr0.getType()).getScalarScale()); - expr.setChild(1, literal); - return expr; - } - default: - return expr; + } catch (ArithmeticException e) { + return new BoolLiteral(false); } } } @@ -86,6 +91,9 @@ public class RoundLiteralInBinaryPredicatesRule implements ExprRewriteRule { } private Expr rewriteDateLiteral(Expr expr) { + if (!(expr instanceof BinaryPredicate)) { + return expr; + } Operator op = ((BinaryPredicate) expr).getOp(); Expr expr0 = expr.getChild(0); Expr expr1 = expr.getChild(1); diff --git a/fe/fe-core/src/main/jflex/sql_scanner.flex b/fe/fe-core/src/main/jflex/sql_scanner.flex index 9b80841ef9..b2f7b9ae3d 100644 --- a/fe/fe-core/src/main/jflex/sql_scanner.flex +++ b/fe/fe-core/src/main/jflex/sql_scanner.flex @@ -165,6 +165,7 @@ import org.apache.doris.qe.SqlModeHelper; keywordMap.put("time", new Integer(SqlParserSymbols.KW_TIME)); keywordMap.put("day", new Integer(SqlParserSymbols.KW_DAY)); keywordMap.put("decimal", new Integer(SqlParserSymbols.KW_DECIMAL)); + keywordMap.put("decimalv3", new Integer(SqlParserSymbols.KW_DECIMALV3)); keywordMap.put("decommission", new Integer(SqlParserSymbols.KW_DECOMMISSION)); keywordMap.put("default", new Integer(SqlParserSymbols.KW_DEFAULT)); keywordMap.put("delete", new Integer(SqlParserSymbols.KW_DELETE)); diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/DecimalLiteralTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/DecimalLiteralTest.java index 3fa2dfe4d1..a643588a6f 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/analysis/DecimalLiteralTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/DecimalLiteralTest.java @@ -21,6 +21,7 @@ import org.apache.doris.catalog.PrimitiveType; import org.apache.doris.catalog.ScalarType; import org.apache.doris.catalog.Type; import org.apache.doris.common.AnalysisException; +import org.apache.doris.common.Config; import org.junit.Assert; import org.junit.Test; @@ -45,7 +46,9 @@ public class DecimalLiteralTest { // if DecimalLiteral need to cast to Decimal and Decimalv2, need to cast // to themselves - Assert.assertEquals(literal, literal.uncheckedCastTo(Type.DECIMALV2)); + if (!(Config.enable_decimalv3 && Config.enable_decimal_conversion)) { + Assert.assertEquals(literal, literal.uncheckedCastTo(Type.DECIMALV2)); + } Assert.assertEquals(1, literal.compareLiteral(new NullLiteral())); } diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/QueryStmtTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/QueryStmtTest.java index 130c23d427..8132926ad0 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/analysis/QueryStmtTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/QueryStmtTest.java @@ -190,7 +190,11 @@ public class QueryStmtTest { Assert.assertEquals(2, exprsMap.size()); constMap.clear(); constMap = getConstantExprMap(exprsMap, analyzer); - Assert.assertEquals(0, constMap.size()); + if (Config.enable_decimalv3 && Config.enable_decimal_conversion) { + Assert.assertEquals(6, constMap.size()); + } else { + Assert.assertEquals(0, constMap.size()); + } sql = "SELECT k1 FROM db1.baseall GROUP BY k1 HAVING EXISTS(SELECT k4 FROM db1.tbl1 GROUP BY k4 " + "HAVING SUM(k4) = k4);"; diff --git a/fe/fe-core/src/test/java/org/apache/doris/catalog/ColumnTypeTest.java b/fe/fe-core/src/test/java/org/apache/doris/catalog/ColumnTypeTest.java index 3c5041cfbd..490be91a2c 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/catalog/ColumnTypeTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/catalog/ColumnTypeTest.java @@ -19,6 +19,7 @@ package org.apache.doris.catalog; import org.apache.doris.analysis.TypeDef; import org.apache.doris.common.AnalysisException; +import org.apache.doris.common.Config; import org.apache.doris.common.FeConstants; import org.junit.Assert; @@ -97,7 +98,11 @@ public class ColumnTypeTest { TypeDef type = TypeDef.createDecimal(12, 5); type.analyze(null); Assert.assertEquals("decimal(12, 5)", type.toString()); - Assert.assertEquals(PrimitiveType.DECIMALV2, type.getType().getPrimitiveType()); + if (Config.enable_decimalv3 && Config.enable_decimal_conversion) { + Assert.assertEquals(PrimitiveType.DECIMAL64, type.getType().getPrimitiveType()); + } else { + Assert.assertEquals(PrimitiveType.DECIMALV2, type.getType().getPrimitiveType()); + } Assert.assertEquals(12, ((ScalarType) type.getType()).getScalarPrecision()); Assert.assertEquals(5, ((ScalarType) type.getType()).getScalarScale()); @@ -188,13 +193,23 @@ public class ColumnTypeTest { @Test(expected = AnalysisException.class) public void testDecimalPreFail() throws AnalysisException { - TypeDef type = TypeDef.createDecimal(28, 3); + TypeDef type; + if (Config.enable_decimalv3 && Config.enable_decimal_conversion) { + type = TypeDef.createDecimal(39, 3); + } else { + type = TypeDef.createDecimal(28, 3); + } type.analyze(null); } @Test(expected = AnalysisException.class) public void testDecimalScaleFail() throws AnalysisException { - TypeDef type = TypeDef.createDecimal(27, 10); + TypeDef type; + if (Config.enable_decimalv3 && Config.enable_decimal_conversion) { + type = TypeDef.createDecimal(27, 28); + } else { + type = TypeDef.createDecimal(27, 10); + } type.analyze(null); } diff --git a/fe/fe-core/src/test/java/org/apache/doris/catalog/CreateFunctionTest.java b/fe/fe-core/src/test/java/org/apache/doris/catalog/CreateFunctionTest.java index 8ff60f91af..37289acfc1 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/catalog/CreateFunctionTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/catalog/CreateFunctionTest.java @@ -23,6 +23,7 @@ import org.apache.doris.analysis.CreateTableStmt; import org.apache.doris.analysis.Expr; import org.apache.doris.analysis.FunctionCallExpr; import org.apache.doris.analysis.StringLiteral; +import org.apache.doris.common.Config; import org.apache.doris.common.FeConstants; import org.apache.doris.common.jmockit.Deencapsulation; import org.apache.doris.planner.PlanFragment; @@ -170,7 +171,11 @@ public class CreateFunctionTest { Assert.assertTrue(constExprLists.get(0).get(0) instanceof StringLiteral); queryStr = "select db1.decimal(k3, 4, 1) from db1.tbl1;"; - Assert.assertTrue(dorisAssert.query(queryStr).explainQuery().contains("CAST(`k3` AS DECIMAL(4,1))")); + if (Config.enable_decimalv3 && Config.enable_decimal_conversion) { + Assert.assertTrue(dorisAssert.query(queryStr).explainQuery().contains("CAST(`k3` AS DECIMALV3(4,1))")); + } else { + Assert.assertTrue(dorisAssert.query(queryStr).explainQuery().contains("CAST(`k3` AS DECIMAL(4,1))")); + } // cast any type to varchar with fixed length createFuncStr = "create alias function db1.varchar(all, int) with parameter(text, length) as " diff --git a/fe/fe-core/src/test/java/org/apache/doris/rewrite/RewriteBinaryPredicatesRuleTest.java b/fe/fe-core/src/test/java/org/apache/doris/rewrite/RewriteBinaryPredicatesRuleTest.java index 0b06502e11..7ce654d046 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/rewrite/RewriteBinaryPredicatesRuleTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/rewrite/RewriteBinaryPredicatesRuleTest.java @@ -44,7 +44,7 @@ public class RewriteBinaryPredicatesRuleTest extends TestWithFeService { @Test public void testNormal() throws Exception { - testBase(Operator.EQ, "2.0", Operator.EQ, 2L); + testRewrite(Operator.EQ, "2.0", Operator.EQ, 2L, true); testBoolean(Operator.EQ, "2.5", false); testBase(Operator.NE, "2.0", Operator.NE, 2L); @@ -92,6 +92,17 @@ public class RewriteBinaryPredicatesRuleTest extends TestWithFeService { testBase(Operator.GT, "32767.0", Operator.GT, 32767L); } + private void testRewrite(Operator operator, String queryLiteral, Operator expectedOperator, long expectedChild1, + boolean expectedResultAfterRewritten) + throws Exception { + Expr expr1 = getExpr(operator, queryLiteral); + if (expr1 instanceof BoolLiteral) { + Assertions.assertEquals(((BoolLiteral) expr1).getValue(), expectedResultAfterRewritten); + } else { + testBase(operator, queryLiteral, expectedOperator, expectedChild1); + } + } + private void testBase(Operator operator, String queryLiteral, Operator expectedOperator, long expectedChild1) throws Exception { Expr expr1 = getExpr(operator, queryLiteral); diff --git a/fe/fe-core/src/test/java/org/apache/doris/rewrite/RewriteDateLiteralRuleTest.java b/fe/fe-core/src/test/java/org/apache/doris/rewrite/RewriteDateLiteralRuleTest.java index 6306073e75..8a5b56866b 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/rewrite/RewriteDateLiteralRuleTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/rewrite/RewriteDateLiteralRuleTest.java @@ -177,21 +177,37 @@ public class RewriteDateLiteralRuleTest { public void testWithDoubleFormatDate() throws Exception { String query = "select * from " + DB_NAME + ".tb1 where k1 > 20210301.22"; String planString = dorisAssert.query(query).explainQuery(); - Assert.assertTrue(planString.contains("`k1` > 2.021030122E7")); + if (Config.enable_decimalv3 && Config.enable_decimal_conversion) { + Assert.assertTrue(planString.contains("`k1` > 20210301")); + } else { + Assert.assertTrue(planString.contains("`k1` > 2.021030122E7")); + } query = "select k1 > 20210331.22 from " + DB_NAME + ".tb1"; planString = dorisAssert.query(query).explainQuery(); - Assert.assertTrue(planString.contains("`k1` > 2.021033122E7")); + if (Config.enable_decimalv3 && Config.enable_decimal_conversion) { + Assert.assertTrue(planString.contains("`k1` > 20210331")); + } else { + Assert.assertTrue(planString.contains("`k1` > 2.021033122E7")); + } } public void testWithDoubleFormatDateV2() throws Exception { String query = "select * from " + DB_NAME + ".tb2 where k1 > 20210301.22"; String planString = dorisAssert.query(query).explainQuery(); - Assert.assertTrue(planString.contains("`k1` > 2.021030122E7")); + if (Config.enable_decimalv3 && Config.enable_decimal_conversion) { + Assert.assertTrue(planString.contains("`k1` > 20210301")); + } else { + Assert.assertTrue(planString.contains("`k1` > 2.021030122E7")); + } query = "select k1 > 20210331.22 from " + DB_NAME + ".tb2"; planString = dorisAssert.query(query).explainQuery(); - Assert.assertTrue(planString.contains("`k1` > 2.021033122E7")); + if (Config.enable_decimalv3 && Config.enable_decimal_conversion) { + Assert.assertTrue(planString.contains("`k1` > 20210331")); + } else { + Assert.assertTrue(planString.contains("`k1` > 2.021033122E7")); + } } public void testWithInvalidFormatDate() throws Exception { --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org