[feature](decimal) support decimal256 (#25386)
This commit is contained in:
@ -514,6 +514,7 @@ public class CastExpr extends Expr {
|
||||
case DECIMAL32:
|
||||
case DECIMAL64:
|
||||
case DECIMAL128:
|
||||
case DECIMAL256:
|
||||
// normal decimal
|
||||
if (targetType.getPrecision() != 0) {
|
||||
newTargetType = targetType;
|
||||
|
||||
@ -484,6 +484,7 @@ public class ColumnDef {
|
||||
case DECIMAL32:
|
||||
case DECIMAL64:
|
||||
case DECIMAL128:
|
||||
case DECIMAL256:
|
||||
DecimalLiteral decimalLiteral = new DecimalLiteral(defaultValue);
|
||||
decimalLiteral.checkPrecisionAndScale(scalarType.getScalarPrecision(), scalarType.getScalarScale());
|
||||
break;
|
||||
|
||||
@ -2528,6 +2528,8 @@ public abstract class Expr extends TreeNode<Expr> implements ParseNode, Cloneabl
|
||||
return Type.DECIMAL64;
|
||||
} else if (originType.getPrimitiveType() == PrimitiveType.DECIMAL128) {
|
||||
return Type.DECIMAL128;
|
||||
} else if (originType.getPrimitiveType() == PrimitiveType.DECIMAL256) {
|
||||
return Type.DECIMAL256;
|
||||
} else if (originType.getPrimitiveType() == PrimitiveType.DATETIMEV2) {
|
||||
return Type.DATETIMEV2;
|
||||
} else if (originType.getPrimitiveType() == PrimitiveType.DATEV2) {
|
||||
|
||||
@ -75,6 +75,7 @@ public abstract class LiteralExpr extends Expr implements Comparable<LiteralExpr
|
||||
case DECIMAL32:
|
||||
case DECIMAL64:
|
||||
case DECIMAL128:
|
||||
case DECIMAL256:
|
||||
literalExpr = new DecimalLiteral(value);
|
||||
break;
|
||||
case CHAR:
|
||||
|
||||
@ -245,6 +245,7 @@ public class StringLiteral extends LiteralExpr {
|
||||
case DECIMAL32:
|
||||
case DECIMAL64:
|
||||
case DECIMAL128:
|
||||
case DECIMAL256:
|
||||
try {
|
||||
DecimalLiteral res = new DecimalLiteral(new BigDecimal(value).stripTrailingZeros());
|
||||
res.setType(targetType);
|
||||
|
||||
@ -29,6 +29,8 @@ import org.apache.doris.catalog.StructType;
|
||||
import org.apache.doris.catalog.Type;
|
||||
import org.apache.doris.common.AnalysisException;
|
||||
import org.apache.doris.common.Config;
|
||||
import org.apache.doris.qe.ConnectContext;
|
||||
import org.apache.doris.qe.SessionVariable;
|
||||
import org.apache.doris.thrift.TColumnDesc;
|
||||
import org.apache.doris.thrift.TPrimitiveType;
|
||||
|
||||
@ -301,6 +303,34 @@ public class TypeDef implements ParseNode {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DECIMAL256: {
|
||||
SessionVariable sessionVariable = ConnectContext.get().getSessionVariable();
|
||||
boolean enableDecimal256 = sessionVariable.enableDecimal256();
|
||||
boolean enableNereidsPlanner = sessionVariable.isEnableNereidsPlanner();
|
||||
if (enableNereidsPlanner && enableDecimal256) {
|
||||
int precision = scalarType.decimalPrecision();
|
||||
int scale = scalarType.decimalScale();
|
||||
if (precision < 1 || precision > ScalarType.MAX_DECIMAL256_PRECISION) {
|
||||
throw new AnalysisException("Precision of decimal256 must between 1 and 76."
|
||||
+ " Precision was set to: " + precision + ".");
|
||||
}
|
||||
// scale >= 0
|
||||
if (scale < 0) {
|
||||
throw new AnalysisException("Scale of decimal must not be less than 0." + " Scale was set to: "
|
||||
+ scale + ".");
|
||||
}
|
||||
// scale < precision
|
||||
if (scale > precision) {
|
||||
throw new AnalysisException("Scale of decimal must be smaller than precision."
|
||||
+ " Scale is " + scale + " and precision is " + precision);
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
int precision = scalarType.decimalPrecision();
|
||||
throw new AnalysisException(
|
||||
"Column of type Decimal256 with precision " + precision + " in not supported.");
|
||||
}
|
||||
}
|
||||
case TIMEV2:
|
||||
case DATETIMEV2: {
|
||||
int precision = scalarType.decimalPrecision();
|
||||
|
||||
@ -173,6 +173,7 @@ public class AliasFunction extends Function {
|
||||
case DECIMAL32:
|
||||
case DECIMAL64:
|
||||
case DECIMAL128:
|
||||
case DECIMAL256:
|
||||
case DECIMALV2:
|
||||
if (!Strings.isNullOrEmpty(scalarType.getScalarPrecisionStr())) {
|
||||
typeDefParams.add(scalarType.getScalarPrecisionStr());
|
||||
|
||||
@ -898,6 +898,7 @@ public class Column implements Writable, GsonPostProcessable {
|
||||
case DECIMAL32:
|
||||
case DECIMAL64:
|
||||
case DECIMAL128:
|
||||
case DECIMAL256:
|
||||
sb.append(String.format(typeStringMap.get(dataType), getPrecision(), getScale()));
|
||||
break;
|
||||
case ARRAY:
|
||||
|
||||
@ -87,6 +87,7 @@ public class Util {
|
||||
TYPE_STRING_MAP.put(PrimitiveType.DECIMAL32, "decimal(%d, %d)");
|
||||
TYPE_STRING_MAP.put(PrimitiveType.DECIMAL64, "decimal(%d, %d)");
|
||||
TYPE_STRING_MAP.put(PrimitiveType.DECIMAL128, "decimal(%d, %d)");
|
||||
TYPE_STRING_MAP.put(PrimitiveType.DECIMAL256, "decimal(%d, %d)");
|
||||
TYPE_STRING_MAP.put(PrimitiveType.HLL, "varchar(%d)");
|
||||
TYPE_STRING_MAP.put(PrimitiveType.BOOLEAN, "bool");
|
||||
TYPE_STRING_MAP.put(PrimitiveType.BITMAP, "bitmap");
|
||||
|
||||
@ -265,7 +265,8 @@ public class MysqlSerializer {
|
||||
case DECIMALV2:
|
||||
case DECIMAL32:
|
||||
case DECIMAL64:
|
||||
case DECIMAL128: {
|
||||
case DECIMAL128:
|
||||
case DECIMAL256: {
|
||||
// https://github.com/mysql/mysql-connector-j/blob/release/5.1/src/com/mysql/jdbc/ResultSetMetaData.java
|
||||
// in function: int getPrecision(int column)
|
||||
// f.getDecimals() > 0 ? clampedGetLength(f) - 1 + f.getPrecisionAdjustFactor()
|
||||
@ -296,6 +297,7 @@ public class MysqlSerializer {
|
||||
case DECIMAL32:
|
||||
case DECIMAL64:
|
||||
case DECIMAL128:
|
||||
case DECIMAL256:
|
||||
return ((ScalarType) type).decimalScale();
|
||||
case FLOAT:
|
||||
case DOUBLE:
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.doris.nereids.exceptions;
|
||||
|
||||
/**
|
||||
* Exception for calling function only implement in bound expression or plan.
|
||||
*/
|
||||
public class NotSupportedException extends RuntimeException {
|
||||
public NotSupportedException(String msg) {
|
||||
super(String.format("Not Supported: %s", msg));
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,8 +209,9 @@ public class FoldConstantRuleOnBE extends AbstractExpressionRewriteRule {
|
||||
type = DateTimeV2Type.of(pScalarType.getScale());
|
||||
} else if (primitiveType == PrimitiveType.DECIMAL32
|
||||
|| primitiveType == PrimitiveType.DECIMAL64
|
||||
|| primitiveType == PrimitiveType.DECIMAL128) {
|
||||
type = DecimalV3Type.createDecimalV3Type(
|
||||
|| primitiveType == PrimitiveType.DECIMAL128
|
||||
|| primitiveType == PrimitiveType.DECIMAL256) {
|
||||
type = DecimalV3Type.createDecimalV3TypeLooseCheck(
|
||||
pScalarType.getPrecision(), pScalarType.getScale());
|
||||
} else {
|
||||
type = DataType.fromCatalogType(ScalarType.createType(
|
||||
|
||||
@ -71,7 +71,7 @@ public class SimplifyDecimalV3Comparison extends AbstractExpressionRewriteRule {
|
||||
if (scale <= leftType.getScale() && precision - scale <= leftType.getPrecision() - leftType.getScale()) {
|
||||
// precision and scale of literal all smaller than left, we don't need the cast
|
||||
DecimalV3Literal newRight = new DecimalV3Literal(
|
||||
DecimalV3Type.createDecimalV3Type(leftType.getPrecision(), leftType.getScale()),
|
||||
DecimalV3Type.createDecimalV3TypeLooseCheck(leftType.getPrecision(), leftType.getScale()),
|
||||
trailingZerosValue);
|
||||
return cp.withChildren(castChild, newRight);
|
||||
} else {
|
||||
|
||||
@ -68,9 +68,9 @@ public class Divide extends BinaryArithmetic implements AlwaysNullable {
|
||||
@Override
|
||||
public DecimalV3Type getDataTypeForDecimalV3(DecimalV3Type t1, DecimalV3Type t2) {
|
||||
int retPercision = t1.getPrecision() + t2.getScale() + Config.div_precision_increment;
|
||||
Preconditions.checkState(retPercision <= DecimalV3Type.MAX_DECIMAL128_PRECISION,
|
||||
Preconditions.checkState(retPercision <= DecimalV3Type.MAX_DECIMAL256_PRECISION,
|
||||
"target precision " + retPercision + " larger than precision "
|
||||
+ DecimalV3Type.MAX_DECIMAL128_PRECISION + " in Divide return type");
|
||||
+ DecimalV3Type.MAX_DECIMAL256_PRECISION + " in Divide return type");
|
||||
int retScale = t1.getScale() + t2.getScale()
|
||||
+ Config.div_precision_increment;
|
||||
int targetPercision = retPercision;
|
||||
|
||||
@ -22,6 +22,7 @@ import org.apache.doris.nereids.trees.expressions.functions.CheckOverflowNullabl
|
||||
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
|
||||
import org.apache.doris.nereids.types.DataType;
|
||||
import org.apache.doris.nereids.types.DecimalV3Type;
|
||||
import org.apache.doris.qe.ConnectContext;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
@ -52,7 +53,14 @@ public class Multiply extends BinaryArithmetic implements CheckOverflowNullable
|
||||
int retPercision = t1.getPrecision() + t2.getPrecision();
|
||||
int retScale = t1.getScale() + t2.getScale();
|
||||
if (retPercision > DecimalV3Type.MAX_DECIMAL128_PRECISION) {
|
||||
retPercision = DecimalV3Type.MAX_DECIMAL128_PRECISION;
|
||||
boolean enableDecimal256 = ConnectContext.get().getSessionVariable().enableDecimal256();
|
||||
if (enableDecimal256) {
|
||||
if (retPercision > DecimalV3Type.MAX_DECIMAL256_PRECISION) {
|
||||
retPercision = DecimalV3Type.MAX_DECIMAL256_PRECISION;
|
||||
}
|
||||
} else {
|
||||
retPercision = DecimalV3Type.MAX_DECIMAL128_PRECISION;
|
||||
}
|
||||
}
|
||||
Preconditions.checkState(retPercision >= retScale,
|
||||
"scale " + retScale + " larger than precision " + retPercision
|
||||
|
||||
@ -20,6 +20,7 @@ package org.apache.doris.nereids.trees.expressions.functions;
|
||||
import org.apache.doris.catalog.FunctionSignature;
|
||||
import org.apache.doris.nereids.types.DataType;
|
||||
import org.apache.doris.nereids.types.DecimalV3Type;
|
||||
import org.apache.doris.qe.ConnectContext;
|
||||
|
||||
/** ComputePrecisionForSum */
|
||||
public interface ComputePrecisionForSum extends ComputePrecision {
|
||||
@ -28,9 +29,12 @@ public interface ComputePrecisionForSum extends ComputePrecision {
|
||||
DataType argumentType = getArgumentType(0);
|
||||
if (signature.getArgType(0) instanceof DecimalV3Type) {
|
||||
DecimalV3Type decimalV3Type = DecimalV3Type.forType(argumentType);
|
||||
boolean enableDecimal256 = ConnectContext.get().getSessionVariable().enableDecimal256();
|
||||
return signature.withArgumentType(0, decimalV3Type)
|
||||
.withReturnType(DecimalV3Type.createDecimalV3Type(
|
||||
DecimalV3Type.MAX_DECIMAL128_PRECISION, decimalV3Type.getScale()));
|
||||
enableDecimal256 ? DecimalV3Type.MAX_DECIMAL256_PRECISION
|
||||
: DecimalV3Type.MAX_DECIMAL128_PRECISION,
|
||||
decimalV3Type.getScale()));
|
||||
} else {
|
||||
return signature;
|
||||
}
|
||||
|
||||
@ -35,6 +35,7 @@ import org.apache.doris.nereids.types.IntegerType;
|
||||
import org.apache.doris.nereids.types.LargeIntType;
|
||||
import org.apache.doris.nereids.types.SmallIntType;
|
||||
import org.apache.doris.nereids.types.TinyIntType;
|
||||
import org.apache.doris.qe.ConnectContext;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
@ -88,6 +89,7 @@ public class Avg extends NullableAggregateFunction
|
||||
public FunctionSignature computePrecision(FunctionSignature signature) {
|
||||
DataType argumentType = getArgumentType(0);
|
||||
if (signature.getArgType(0) instanceof DecimalV3Type) {
|
||||
boolean enableDecimal256 = ConnectContext.get().getSessionVariable().enableDecimal256();
|
||||
DecimalV3Type decimalV3Type = DecimalV3Type.forType(argumentType);
|
||||
// DecimalV3 scale lower than DEFAULT_MIN_AVG_DECIMAL128_SCALE should do cast
|
||||
int precision = decimalV3Type.getPrecision();
|
||||
@ -95,14 +97,22 @@ public class Avg extends NullableAggregateFunction
|
||||
if (decimalV3Type.getScale() < ScalarType.DEFAULT_MIN_AVG_DECIMAL128_SCALE) {
|
||||
scale = ScalarType.DEFAULT_MIN_AVG_DECIMAL128_SCALE;
|
||||
precision = precision - decimalV3Type.getScale() + scale;
|
||||
if (precision > DecimalV3Type.MAX_DECIMAL128_PRECISION) {
|
||||
precision = DecimalV3Type.MAX_DECIMAL128_PRECISION;
|
||||
if (enableDecimal256) {
|
||||
if (precision > DecimalV3Type.MAX_DECIMAL256_PRECISION) {
|
||||
precision = DecimalV3Type.MAX_DECIMAL256_PRECISION;
|
||||
}
|
||||
} else {
|
||||
if (precision > DecimalV3Type.MAX_DECIMAL128_PRECISION) {
|
||||
precision = DecimalV3Type.MAX_DECIMAL128_PRECISION;
|
||||
}
|
||||
}
|
||||
}
|
||||
decimalV3Type = DecimalV3Type.createDecimalV3Type(precision, scale);
|
||||
return signature.withArgumentType(0, decimalV3Type)
|
||||
.withReturnType(DecimalV3Type.createDecimalV3Type(
|
||||
DecimalV3Type.MAX_DECIMAL128_PRECISION, decimalV3Type.getScale()
|
||||
enableDecimal256 ? DecimalV3Type.MAX_DECIMAL256_PRECISION
|
||||
: DecimalV3Type.MAX_DECIMAL128_PRECISION,
|
||||
decimalV3Type.getScale()
|
||||
));
|
||||
} else {
|
||||
return signature;
|
||||
|
||||
@ -555,7 +555,7 @@ public class NumericArithmetic {
|
||||
DecimalV3Type t2 = (DecimalV3Type) second.getDataType();
|
||||
int precision = t1.getPrecision() + t2.getPrecision();
|
||||
int scale = t1.getScale() + t2.getScale();
|
||||
return new DecimalV3Literal(DecimalV3Type.createDecimalV3Type(precision, scale), result);
|
||||
return new DecimalV3Literal(DecimalV3Type.createDecimalV3TypeLooseCheck(precision, scale), result);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -590,7 +590,7 @@ public class NumericArithmetic {
|
||||
DecimalV3Type t1 = (DecimalV3Type) first.getDataType();
|
||||
DecimalV3Type t2 = (DecimalV3Type) second.getDataType();
|
||||
BigDecimal result = first.getValue().divide(second.getValue());
|
||||
return new DecimalV3Literal(DecimalV3Type.createDecimalV3Type(
|
||||
return new DecimalV3Literal(DecimalV3Type.createDecimalV3TypeLooseCheck(
|
||||
t1.getPrecision(), t1.getScale() - t2.getScale()), result);
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@ public class DecimalV3Literal extends Literal {
|
||||
* Constructor for DecimalV3Literal
|
||||
*/
|
||||
public DecimalV3Literal(DecimalV3Type dataType, BigDecimal value) {
|
||||
super(DecimalV3Type.createDecimalV3Type(dataType.getPrecision(), dataType.getScale()));
|
||||
super(DecimalV3Type.createDecimalV3TypeLooseCheck(dataType.getPrecision(), dataType.getScale()));
|
||||
Objects.requireNonNull(value, "value not be null");
|
||||
DecimalLiteral.checkPrecisionAndScale(dataType.getPrecision(), dataType.getScale(), value);
|
||||
BigDecimal adjustedValue = value.scale() < 0 ? value
|
||||
|
||||
@ -333,7 +333,7 @@ public abstract class DataType {
|
||||
ScalarType scalarType = (ScalarType) type;
|
||||
int precision = scalarType.getScalarPrecision();
|
||||
int scale = scalarType.getScalarScale();
|
||||
return DecimalV3Type.createDecimalV3Type(precision, scale);
|
||||
return DecimalV3Type.createDecimalV3TypeNoCheck(precision, scale);
|
||||
} else if (type.isDecimalV2()) {
|
||||
ScalarType scalarType = (ScalarType) type;
|
||||
int precision = scalarType.getScalarPrecision();
|
||||
|
||||
@ -20,7 +20,9 @@ package org.apache.doris.nereids.types;
|
||||
import org.apache.doris.catalog.ScalarType;
|
||||
import org.apache.doris.catalog.Type;
|
||||
import org.apache.doris.nereids.annotation.Developing;
|
||||
import org.apache.doris.nereids.exceptions.NotSupportedException;
|
||||
import org.apache.doris.nereids.types.coercion.FractionalType;
|
||||
import org.apache.doris.qe.ConnectContext;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
@ -37,6 +39,7 @@ public class DecimalV3Type extends FractionalType {
|
||||
public static final int MAX_DECIMAL32_PRECISION = 9;
|
||||
public static final int MAX_DECIMAL64_PRECISION = 18;
|
||||
public static final int MAX_DECIMAL128_PRECISION = 38;
|
||||
public static final int MAX_DECIMAL256_PRECISION = 76;
|
||||
|
||||
public static final DecimalV3Type WILDCARD = new DecimalV3Type(-1, -1);
|
||||
public static final DecimalV3Type SYSTEM_DEFAULT = new DecimalV3Type(MAX_DECIMAL128_PRECISION, DEFAULT_SCALE);
|
||||
@ -99,18 +102,49 @@ public class DecimalV3Type extends FractionalType {
|
||||
|
||||
/** createDecimalV3Type. */
|
||||
public static DecimalV3Type createDecimalV3Type(int precision, int scale) {
|
||||
Preconditions.checkArgument(precision > 0 && precision <= MAX_DECIMAL128_PRECISION,
|
||||
"precision should in (0, " + MAX_DECIMAL128_PRECISION + "], but real precision is " + precision);
|
||||
Preconditions.checkArgument(precision > 0 && precision <= MAX_DECIMAL256_PRECISION,
|
||||
"precision should in (0, " + MAX_DECIMAL256_PRECISION + "], but real precision is " + precision);
|
||||
Preconditions.checkArgument(scale >= 0, "scale should not smaller than 0, but real scale is " + scale);
|
||||
Preconditions.checkArgument(precision >= scale, "precision should not smaller than scale,"
|
||||
+ " but precision is " + precision, ", scale is " + scale);
|
||||
boolean enableDecimal256 = ConnectContext.get().getSessionVariable().enableDecimal256();
|
||||
if (precision > MAX_DECIMAL128_PRECISION && !enableDecimal256) {
|
||||
throw new NotSupportedException("Datatype DecimalV3 with precision " + precision
|
||||
+ ", which is greater than 38 is disabled by default. set enable_decimal256 = true to enable it.");
|
||||
} else {
|
||||
return new DecimalV3Type(precision, scale);
|
||||
}
|
||||
}
|
||||
|
||||
public static DecimalV3Type createDecimalV3Type(BigDecimal bigDecimal) {
|
||||
int precision = org.apache.doris.analysis.DecimalLiteral.getBigDecimalPrecision(bigDecimal);
|
||||
int scale = org.apache.doris.analysis.DecimalLiteral.getBigDecimalScale(bigDecimal);
|
||||
return createDecimalV3TypeLooseCheck(precision, scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* create DecimalV3Type, not throwing NotSupportedException.
|
||||
*/
|
||||
public static DecimalV3Type createDecimalV3TypeLooseCheck(int precision, int scale) {
|
||||
boolean enableDecimal256 = ConnectContext.get().getSessionVariable().enableDecimal256();
|
||||
if (enableDecimal256) {
|
||||
Preconditions.checkArgument(precision > 0 && precision <= MAX_DECIMAL256_PRECISION,
|
||||
"precision should in (0, " + MAX_DECIMAL256_PRECISION + "], but real precision is " + precision);
|
||||
} else {
|
||||
Preconditions.checkArgument(precision > 0 && precision <= MAX_DECIMAL128_PRECISION,
|
||||
"precision should in (0, " + MAX_DECIMAL128_PRECISION + "], but real precision is " + precision);
|
||||
}
|
||||
Preconditions.checkArgument(scale >= 0, "scale should not smaller than 0, but real scale is " + scale);
|
||||
Preconditions.checkArgument(precision >= scale, "precision should not smaller than scale,"
|
||||
+ " but precision is " + precision, ", scale is " + scale);
|
||||
return new DecimalV3Type(precision, scale);
|
||||
}
|
||||
|
||||
public static DecimalV3Type createDecimalV3Type(BigDecimal bigDecimal) {
|
||||
int precision = org.apache.doris.analysis.DecimalLiteral.getBigDecimalPrecision(bigDecimal);
|
||||
int scale = org.apache.doris.analysis.DecimalLiteral.getBigDecimalScale(bigDecimal);
|
||||
return createDecimalV3Type(precision, scale);
|
||||
/**
|
||||
* create DecimalV3Type, without checking precision and scale, e.g. for DataType.fromCatalogType
|
||||
*/
|
||||
public static DecimalV3Type createDecimalV3TypeNoCheck(int precision, int scale) {
|
||||
return new DecimalV3Type(precision, scale);
|
||||
}
|
||||
|
||||
public static DataType widerDecimalV3Type(DecimalV3Type left, DecimalV3Type right, boolean overflowToDouble) {
|
||||
@ -124,7 +158,9 @@ public class DecimalV3Type extends FractionalType {
|
||||
boolean overflowToDouble) {
|
||||
int scale = Math.max(leftScale, rightScale);
|
||||
int range = Math.max(leftPrecision - leftScale, rightPrecision - rightScale);
|
||||
if (range + scale > MAX_DECIMAL128_PRECISION && overflowToDouble) {
|
||||
boolean enableDecimal256 = ConnectContext.get().getSessionVariable().enableDecimal256();
|
||||
if (range + scale > (enableDecimal256 ? MAX_DECIMAL256_PRECISION : MAX_DECIMAL128_PRECISION)
|
||||
&& overflowToDouble) {
|
||||
return DoubleType.INSTANCE;
|
||||
}
|
||||
return DecimalV3Type.createDecimalV3Type(range + scale, scale);
|
||||
@ -193,8 +229,15 @@ public class DecimalV3Type extends FractionalType {
|
||||
return 4;
|
||||
} else if (precision <= MAX_DECIMAL64_PRECISION) {
|
||||
return 8;
|
||||
} else {
|
||||
} else if (precision <= MAX_DECIMAL128_PRECISION) {
|
||||
return 16;
|
||||
} else {
|
||||
boolean enableDecimal256 = ConnectContext.get().getSessionVariable().enableDecimal256();
|
||||
if (enableDecimal256) {
|
||||
return 32;
|
||||
} else {
|
||||
return 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,6 +50,7 @@ import org.apache.doris.mysql.MysqlPacket;
|
||||
import org.apache.doris.mysql.MysqlProto;
|
||||
import org.apache.doris.mysql.MysqlSerializer;
|
||||
import org.apache.doris.mysql.MysqlServerStatusFlag;
|
||||
import org.apache.doris.nereids.exceptions.NotSupportedException;
|
||||
import org.apache.doris.nereids.glue.LogicalPlanAdapter;
|
||||
import org.apache.doris.nereids.minidump.MinidumpUtils;
|
||||
import org.apache.doris.nereids.parser.NereidsParser;
|
||||
@ -306,6 +307,10 @@ public class ConnectProcessor {
|
||||
if (mysqlCommand == MysqlCommand.COM_QUERY && ctx.getSessionVariable().isEnableNereidsPlanner()) {
|
||||
try {
|
||||
stmts = new NereidsParser().parseSQL(originStmt);
|
||||
} catch (NotSupportedException e) {
|
||||
// Parse sql failed, audit it and return
|
||||
handleQueryException(e, originStmt, null, null);
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
// TODO: We should catch all exception here until we support all query syntax.
|
||||
LOG.debug("Nereids parse sql failed. Reason: {}. Statement: \"{}\".",
|
||||
@ -390,6 +395,11 @@ public class ConnectProcessor {
|
||||
ctx.getState().setError(((UserException) throwable).getMysqlErrorCode(), throwable.getMessage());
|
||||
// set it as ANALYSIS_ERR so that it won't be treated as a query failure.
|
||||
ctx.getState().setErrType(QueryState.ErrType.ANALYSIS_ERR);
|
||||
} else if (throwable instanceof NotSupportedException) {
|
||||
LOG.warn("Process one query failed because.", throwable);
|
||||
ctx.getState().setError(ErrorCode.ERR_NOT_SUPPORTED_YET, throwable.getMessage());
|
||||
// set it as ANALYSIS_ERR so that it won't be treated as a query failure.
|
||||
ctx.getState().setErrType(QueryState.ErrType.ANALYSIS_ERR);
|
||||
} else {
|
||||
// Catch all throwable.
|
||||
// If reach here, maybe palo bug.
|
||||
|
||||
@ -423,6 +423,8 @@ public class SessionVariable implements Serializable, Writable {
|
||||
|
||||
public static final String FASTER_FLOAT_CONVERT = "faster_float_convert";
|
||||
|
||||
public static final String ENABLE_DECIMAL256 = "enable_decimal256";
|
||||
|
||||
public static final List<String> DEBUG_VARIABLES = ImmutableList.of(
|
||||
SKIP_DELETE_PREDICATE,
|
||||
SKIP_DELETE_BITMAP,
|
||||
@ -1261,6 +1263,10 @@ public class SessionVariable implements Serializable, Writable {
|
||||
"the plan node type which is ignored in 'explain shape plan' command"})
|
||||
public String ignoreShapePlanNodes = "";
|
||||
|
||||
@VariableMgr.VarAttr(name = ENABLE_DECIMAL256, needForward = true, description = { "控制是否在计算过程中使用Decimal256类型",
|
||||
"Set to true to enable Decimal256 type" })
|
||||
public boolean enableDecimal256 = false;
|
||||
|
||||
// If this fe is in fuzzy mode, then will use initFuzzyModeVariables to generate some variables,
|
||||
// not the default value set in the code.
|
||||
public void initFuzzyModeVariables() {
|
||||
@ -2395,6 +2401,8 @@ public class SessionVariable implements Serializable, Writable {
|
||||
|
||||
tResult.setFasterFloatConvert(fasterFloatConvert);
|
||||
|
||||
tResult.setEnableDecimal256(enableNereidsPlanner && enableDecimal256);
|
||||
|
||||
return tResult;
|
||||
}
|
||||
|
||||
@ -2724,6 +2732,10 @@ public class SessionVariable implements Serializable, Writable {
|
||||
return connectContext.getSessionVariable().enableAggState;
|
||||
}
|
||||
|
||||
public boolean enableDecimal256() {
|
||||
return enableDecimal256;
|
||||
}
|
||||
|
||||
public void checkAnalyzeTimeFormat(String time) {
|
||||
try {
|
||||
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
|
||||
|
||||
@ -189,6 +189,7 @@ public class PartitionRange {
|
||||
case DECIMAL32:
|
||||
case DECIMAL64:
|
||||
case DECIMAL128:
|
||||
case DECIMAL256:
|
||||
case CHAR:
|
||||
case VARCHAR:
|
||||
case STRING:
|
||||
|
||||
@ -404,7 +404,8 @@ public class FoldConstantsRule implements ExprRewriteRule {
|
||||
type = ScalarType.createDatetimeV2Type(scalarType.getScale());
|
||||
} else if (ttype == TPrimitiveType.DECIMAL32
|
||||
|| ttype == TPrimitiveType.DECIMAL64
|
||||
|| ttype == TPrimitiveType.DECIMAL128I) {
|
||||
|| ttype == TPrimitiveType.DECIMAL128I
|
||||
|| ttype == TPrimitiveType.DECIMAL256) {
|
||||
type = ScalarType.createDecimalV3Type(scalarType.getPrecision(),
|
||||
scalarType.getScale());
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user