org.h2.expression.function.TruncateValueFunction Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of h2-mvstore Show documentation
Show all versions of h2-mvstore Show documentation
Fork of h2database to maintain Java 8 compatibility
The newest version!
/*
* Copyright 2004-2023 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (https://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.expression.function;
import java.math.BigDecimal;
import java.math.MathContext;
import org.h2.api.ErrorCode;
import org.h2.engine.SessionLocal;
import org.h2.expression.Expression;
import org.h2.expression.TypedValueExpression;
import org.h2.message.DbException;
import org.h2.util.MathUtils;
import org.h2.value.DataType;
import org.h2.value.TypeInfo;
import org.h2.value.Value;
import org.h2.value.ValueDecfloat;
import org.h2.value.ValueNumeric;
/**
* A TRUNCATE_VALUE function.
*/
public final class TruncateValueFunction extends FunctionN {
public TruncateValueFunction(Expression arg1, Expression arg2, Expression arg3) {
super(new Expression[] { arg1, arg2, arg3 });
}
@Override
public Value getValue(SessionLocal session, Value v1, Value v2, Value v3) {
long precision = v2.getLong();
boolean force = v3.getBoolean();
if (precision <= 0) {
throw DbException.get(ErrorCode.INVALID_VALUE_PRECISION, Long.toString(precision), "1",
"" + Integer.MAX_VALUE);
}
TypeInfo t = v1.getType();
int valueType = t.getValueType();
if (DataType.getDataType(valueType).supportsPrecision) {
if (precision < t.getPrecision()) {
switch (valueType) {
case Value.NUMERIC: {
BigDecimal bd = v1.getBigDecimal().round(new MathContext(MathUtils.convertLongToInt(precision)));
if (bd.scale() < 0) {
bd = bd.setScale(0);
}
return ValueNumeric.get(bd);
}
case Value.DECFLOAT:
return ValueDecfloat
.get(v1.getBigDecimal().round(new MathContext(MathUtils.convertLongToInt(precision))));
default:
return v1.castTo(TypeInfo.getTypeInfo(valueType, precision, t.getScale(), t.getExtTypeInfo()),
session);
}
}
} else if (force) {
BigDecimal bd;
switch (valueType) {
case Value.TINYINT:
case Value.SMALLINT:
case Value.INTEGER:
bd = BigDecimal.valueOf(v1.getInt());
break;
case Value.BIGINT:
bd = BigDecimal.valueOf(v1.getLong());
break;
case Value.REAL:
case Value.DOUBLE:
bd = v1.getBigDecimal();
break;
default:
return v1;
}
bd = bd.round(new MathContext(MathUtils.convertLongToInt(precision)));
if (valueType == Value.DECFLOAT) {
return ValueDecfloat.get(bd);
}
if (bd.scale() < 0) {
bd = bd.setScale(0);
}
return ValueNumeric.get(bd).convertTo(valueType);
}
return v1;
}
@Override
public Expression optimize(SessionLocal session) {
boolean allConst = optimizeArguments(session, true);
type = args[0].getType();
if (allConst) {
return TypedValueExpression.getTypedIfNull(getValue(session), type);
}
return this;
}
@Override
public String getName() {
return "TRUNCATE_VALUE";
}
}