blob: 015a518a2844c7c2f43832985c4b0035c0ed1b20 [file] [log] [blame]
// 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.
#include "exprs/decimal-functions.h"
#include "codegen/impala-ir.h"
#include "exprs/anyval-util.h"
#include <ctype.h>
#include <math.h>
#include "common/names.h"
namespace impala {
IntVal DecimalFunctions::Precision(FunctionContext* ctx, const DecimalVal& val) {
return IntVal(ctx->impl()->GetConstFnAttr(FunctionContextImpl::ARG_TYPE_PRECISION, 0));
}
IntVal DecimalFunctions::Scale(FunctionContext* ctx, const DecimalVal& val) {
return IntVal(ctx->impl()->GetConstFnAttr(FunctionContextImpl::ARG_TYPE_SCALE, 0));
}
DecimalVal DecimalFunctions::Abs(FunctionContext* ctx, const DecimalVal& val) {
if (val.is_null) return DecimalVal::null();
int type_byte_size = ctx->impl()->GetConstFnAttr(FunctionContextImpl::ARG_TYPE_SIZE, 0);
switch (type_byte_size) {
case 4:
return DecimalVal(abs(val.val4));
case 8:
return DecimalVal(abs(val.val8));
case 16:
return DecimalVal(abs(val.val16));
default:
DCHECK(false);
return DecimalVal::null();
}
}
DecimalVal DecimalFunctions::Ceil(FunctionContext* ctx, const DecimalVal& val) {
return DecimalOperators::RoundDecimal(ctx, val, DecimalOperators::CEIL);
}
DecimalVal DecimalFunctions::Floor(FunctionContext* ctx, const DecimalVal& val) {
return DecimalOperators::RoundDecimal(ctx, val, DecimalOperators::FLOOR);
}
DecimalVal DecimalFunctions::Round(FunctionContext* ctx, const DecimalVal& val) {
return DecimalOperators::RoundDecimal(ctx, val, DecimalOperators::ROUND);
}
/// Always inline in IR module so that constants can be replaced.
IR_ALWAYS_INLINE DecimalVal DecimalFunctions::RoundTo(
FunctionContext* ctx, const DecimalVal& val, int scale,
DecimalOperators::DecimalRoundOp op) {
int val_precision =
ctx->impl()->GetConstFnAttr(FunctionContextImpl::ARG_TYPE_PRECISION, 0);
int val_scale =
ctx->impl()->GetConstFnAttr(FunctionContextImpl::ARG_TYPE_SCALE, 0);
int return_precision =
ctx->impl()->GetConstFnAttr(FunctionContextImpl::RETURN_TYPE_PRECISION);
int return_scale =
ctx->impl()->GetConstFnAttr(FunctionContextImpl::RETURN_TYPE_SCALE);
if (scale < 0) {
return DecimalOperators::RoundDecimalNegativeScale(ctx,
val, val_precision, val_scale, return_precision, return_scale, op, -scale);
} else {
return DecimalOperators::RoundDecimal(ctx,
val, val_precision, val_scale, return_precision, return_scale, op);
}
}
DecimalVal DecimalFunctions::RoundTo(
FunctionContext* ctx, const DecimalVal& val, const TinyIntVal& scale) {
DCHECK(!scale.is_null);
return RoundTo(ctx, val, scale.val, DecimalOperators::ROUND);
}
DecimalVal DecimalFunctions::RoundTo(
FunctionContext* ctx, const DecimalVal& val, const SmallIntVal& scale) {
DCHECK(!scale.is_null);
return RoundTo(ctx, val, scale.val, DecimalOperators::ROUND);
}
DecimalVal DecimalFunctions::RoundTo(
FunctionContext* ctx, const DecimalVal& val, const IntVal& scale) {
DCHECK(!scale.is_null);
return RoundTo(ctx, val, scale.val, DecimalOperators::ROUND);
}
DecimalVal DecimalFunctions::RoundTo(
FunctionContext* ctx, const DecimalVal& val, const BigIntVal& scale) {
DCHECK(!scale.is_null);
return RoundTo(ctx, val, scale.val, DecimalOperators::ROUND);
}
DecimalVal DecimalFunctions::Truncate(FunctionContext* ctx, const DecimalVal& val) {
return DecimalOperators::RoundDecimal(ctx, val, DecimalOperators::TRUNCATE);
}
DecimalVal DecimalFunctions::TruncateTo(
FunctionContext* ctx, const DecimalVal& val, const TinyIntVal& scale) {
DCHECK(!scale.is_null);
return RoundTo(ctx, val, scale.val, DecimalOperators::TRUNCATE);
}
DecimalVal DecimalFunctions::TruncateTo(
FunctionContext* ctx, const DecimalVal& val, const SmallIntVal& scale) {
DCHECK(!scale.is_null);
return RoundTo(ctx, val, scale.val, DecimalOperators::TRUNCATE);
}
DecimalVal DecimalFunctions::TruncateTo(
FunctionContext* ctx, const DecimalVal& val, const IntVal& scale) {
DCHECK(!scale.is_null);
return RoundTo(ctx, val, scale.val, DecimalOperators::TRUNCATE);
}
DecimalVal DecimalFunctions::TruncateTo(
FunctionContext* ctx, const DecimalVal& val, const BigIntVal& scale) {
DCHECK(!scale.is_null);
return RoundTo(ctx, val, scale.val, DecimalOperators::TRUNCATE);
}
}