154 lines
4.6 KiB
C++
154 lines
4.6 KiB
C++
// (C) Copyright 2010-2016 Alibaba Inc. All Rights Reserved.
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License
|
|
// version 2 as published by the Free Software Foundation.
|
|
// Version: $Id$
|
|
// Authors:
|
|
// yaojing <>
|
|
// This file is for implementation of func expr_format_bytes
|
|
#define USING_LOG_PREFIX SQL_ENG
|
|
#include "sql/engine/expr/ob_expr_format_bytes.h"
|
|
#include "sql/engine/expr/ob_expr_operator.h"
|
|
#include <math.h>
|
|
|
|
namespace oceanbase
|
|
{
|
|
using namespace common;
|
|
namespace sql
|
|
{
|
|
|
|
ObExprFormatBytes::ObExprFormatBytes(ObIAllocator &alloc)
|
|
: ObFuncExprOperator(alloc, T_FUN_SYS_FORMAT_BYTES, N_FORMAT_BYTES, 1, VALID_FOR_GENERATED_COL, NOT_ROW_DIMENSION)
|
|
{
|
|
}
|
|
|
|
ObExprFormatBytes::~ObExprFormatBytes()
|
|
{}
|
|
|
|
int ObExprFormatBytes::calc_result_type1(ObExprResType &type,
|
|
ObExprResType &type1,
|
|
ObExprTypeCtx &type_ctx) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
UNUSED(type_ctx);
|
|
type.set_varchar();
|
|
type.set_length(LENGTH_FORMAT_BYTES);
|
|
type.set_collation_level(common::CS_LEVEL_IMPLICIT);
|
|
type.set_collation_type(common::CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
type1.set_calc_type(common::ObDoubleType);
|
|
return ret;
|
|
}
|
|
|
|
int ObExprFormatBytes::eval_format_bytes(const ObExpr &expr, ObEvalCtx &ctx,
|
|
ObDatum &res_datum)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObDatum *datum = NULL;
|
|
if (OB_FAIL(expr.args_[0]->eval(ctx, datum))) {
|
|
LOG_WARN("eval arg0 failed", K(ret));
|
|
} else {
|
|
if (OB_FAIL(eval_format_bytes_util(expr, res_datum, datum, ctx))){
|
|
LOG_WARN("eval format_bytes unexpect error", K(ret));
|
|
} else {
|
|
// do nothing
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObExprFormatBytes::eval_format_bytes_batch(const ObExpr &expr,
|
|
ObEvalCtx &ctx,
|
|
const ObBitVector &skip,
|
|
const int64_t batch_size) {
|
|
LOG_DEBUG("eval format bytes batch mode", K(batch_size));
|
|
int ret = OB_SUCCESS;
|
|
if (OB_FAIL(expr.args_[0]->eval_batch(ctx, skip, batch_size))) {
|
|
LOG_WARN("eval arg0 failed", K(ret));
|
|
} else {
|
|
ObDatum *res_datum = expr.locate_batch_datums(ctx);
|
|
ObBitVector &eval_flags = expr.get_evaluated_flags(ctx);
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < batch_size; ++i) {
|
|
if (skip.at(i) || eval_flags.at(i)) {
|
|
continue;
|
|
}
|
|
ObDatum *datum= &expr.args_[0]->locate_expr_datum(ctx, i);
|
|
if (OB_FAIL(eval_format_bytes_util(expr, res_datum[i], datum, ctx, i))){
|
|
LOG_WARN("eval format_bytes unexpect error", K(ret));
|
|
} else {
|
|
// do nothing
|
|
}
|
|
eval_flags.set(i);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObExprFormatBytes::eval_format_bytes_util(const ObExpr &expr, ObDatum &res_datum,
|
|
ObDatum *param1, ObEvalCtx &ctx, int64_t index)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (param1->is_null()) {
|
|
res_datum.set_null();
|
|
} else {
|
|
double bytes = param1->get_double();
|
|
double bytes_abs = std::abs(bytes);
|
|
uint64_t divisor;
|
|
int len;
|
|
const char *unit;
|
|
char *res_buf = NULL;
|
|
if (OB_ISNULL(res_buf = expr.get_str_res_mem(ctx, VALUE_BUF_LEN, index))) {
|
|
ret = OB_ALLOCATE_MEMORY_FAILED;
|
|
LOG_WARN("allocate memory failed", K(ret));
|
|
} else {
|
|
if (bytes_abs >= eib) {
|
|
divisor = eib;
|
|
unit = "EiB";
|
|
} else if (bytes_abs >= pib) {
|
|
divisor = pib;
|
|
unit = "PiB";
|
|
} else if (bytes_abs >= tib) {
|
|
divisor = tib;
|
|
unit = "TiB";
|
|
} else if (bytes_abs >= gib) {
|
|
divisor = gib;
|
|
unit = "GiB";
|
|
} else if (bytes_abs >= mib) {
|
|
divisor = mib;
|
|
unit = "MiB";
|
|
} else if (bytes_abs >= kib) {
|
|
divisor = kib;
|
|
unit = "KiB";
|
|
} else {
|
|
divisor = 1;
|
|
unit = "bytes";
|
|
}
|
|
if (divisor == 1) {
|
|
len = sprintf(res_buf, "%4d %s", (int)bytes, unit);
|
|
} else {
|
|
double value = bytes / divisor;
|
|
if (std::abs(value) >= 100000.0) {
|
|
len = sprintf(res_buf, "%4.2e %s", value, unit);
|
|
} else {
|
|
len = sprintf(res_buf, "%4.2f %s", value, unit);
|
|
}
|
|
}
|
|
res_datum.set_string(res_buf, len);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
int ObExprFormatBytes::cg_expr(ObExprCGCtx &expr_cg_ctx, const ObRawExpr &raw_expr,
|
|
ObExpr &rt_expr) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
UNUSED(expr_cg_ctx);
|
|
UNUSED(raw_expr);
|
|
rt_expr.eval_func_ = ObExprFormatBytes::eval_format_bytes;
|
|
rt_expr.eval_batch_func_ = ObExprFormatBytes::eval_format_bytes_batch;
|
|
return ret;
|
|
}
|
|
}//namespace sql
|
|
}//namespace oceanbase
|