Files
oceanbase/src/sql/engine/expr/ob_expr_format_bytes.cpp
2023-04-27 11:11:24 +00:00

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