Add money_format function (#1064)
This commit is contained in:
@ -69,7 +69,7 @@ const double log_10[] = {
|
||||
|
||||
#define ARRAY_ELEMENTS(A) ((uint64_t) (sizeof(A)/sizeof(A[0])))
|
||||
|
||||
static double my_double_round(double value, int64_t dec, bool dec_unsigned, bool truncate) {
|
||||
double MathFunctions::my_double_round(double value, int64_t dec, bool dec_unsigned, bool truncate) {
|
||||
bool dec_negative = (dec < 0) && !dec_unsigned;
|
||||
uint64_t abs_dec = dec_negative ? -dec : dec;
|
||||
/*
|
||||
|
||||
@ -172,6 +172,9 @@ public:
|
||||
doris_udf::FunctionContext* ctx, int num_args, const doris_udf::DecimalV2Val* val);
|
||||
static doris_udf::DecimalV2Val greatest(
|
||||
doris_udf::FunctionContext* ctx, int num_args, const doris_udf::DecimalV2Val* val);
|
||||
|
||||
static double my_double_round(double value, int64_t dec, bool dec_unsigned, bool truncate);
|
||||
|
||||
private:
|
||||
static const int32_t MIN_BASE = 2;
|
||||
static const int32_t MAX_BASE = 36;
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include "runtime/string_value.hpp"
|
||||
#include "runtime/tuple_row.h"
|
||||
#include "util/url_parser.h"
|
||||
#include "math_functions.h"
|
||||
|
||||
// NOTE: be careful not to use string::append. It is not performant.
|
||||
namespace doris {
|
||||
@ -707,4 +708,57 @@ StringVal StringFunctions::parse_url_key(
|
||||
return result_sv;
|
||||
}
|
||||
|
||||
StringVal StringFunctions::money_format(FunctionContext* context, const DoubleVal& v) {
|
||||
if (v.is_null) {
|
||||
return StringVal::null();
|
||||
}
|
||||
|
||||
double v_cent= MathFunctions::my_double_round(v.val, 2, false, false) * 100;
|
||||
return do_money_format(context, std::to_string(v_cent));
|
||||
}
|
||||
|
||||
StringVal StringFunctions::money_format(FunctionContext *context, const DecimalVal &v) {
|
||||
if (v.is_null) {
|
||||
return StringVal::null();
|
||||
}
|
||||
|
||||
DecimalValue rounded;
|
||||
DecimalValue::from_decimal_val(v).round(&rounded, 2, HALF_UP);
|
||||
DecimalValue tmp(std::string("100"));
|
||||
DecimalValue result = rounded * tmp;
|
||||
return do_money_format(context, result.to_string());
|
||||
}
|
||||
|
||||
StringVal StringFunctions::money_format(FunctionContext *context, const DecimalV2Val &v) {
|
||||
if (v.is_null) {
|
||||
return StringVal::null();
|
||||
}
|
||||
|
||||
DecimalV2Value rounded;
|
||||
DecimalV2Value::from_decimal_val(v).round(&rounded, 2, HALF_UP);
|
||||
DecimalV2Value tmp(std::string("100"));
|
||||
DecimalV2Value result = rounded * tmp;
|
||||
return do_money_format(context, result.to_string());
|
||||
}
|
||||
|
||||
|
||||
StringVal StringFunctions::money_format(FunctionContext *context, const BigIntVal &v) {
|
||||
if (v.is_null) {
|
||||
return StringVal::null();
|
||||
}
|
||||
|
||||
std::string cent_money = std::to_string(v.val) + std::string("00");
|
||||
return do_money_format(context, cent_money);
|
||||
}
|
||||
|
||||
StringVal StringFunctions::money_format(FunctionContext *context, const LargeIntVal &v) {
|
||||
if (v.is_null) {
|
||||
return StringVal::null();
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss << v.val << "00";
|
||||
return do_money_format(context, ss.str());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -22,6 +22,10 @@
|
||||
|
||||
#include "runtime/string_value.h"
|
||||
#include "runtime/string_search.hpp"
|
||||
#include "anyval_util.h"
|
||||
#include <locale>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
namespace doris {
|
||||
|
||||
@ -137,8 +141,40 @@ public:
|
||||
static void parse_url_close(
|
||||
doris_udf::FunctionContext*,
|
||||
doris_udf::FunctionContext::FunctionStateScope);
|
||||
};
|
||||
|
||||
|
||||
static doris_udf::StringVal money_format(doris_udf::FunctionContext* context,
|
||||
const doris_udf::DoubleVal& v);
|
||||
|
||||
static doris_udf::StringVal money_format(doris_udf::FunctionContext* context,
|
||||
const doris_udf::DecimalVal& v);
|
||||
|
||||
static doris_udf::StringVal money_format(doris_udf::FunctionContext* context,
|
||||
const doris_udf::DecimalV2Val& v);
|
||||
|
||||
static doris_udf::StringVal money_format(doris_udf::FunctionContext* context,
|
||||
const doris_udf::BigIntVal& v);
|
||||
|
||||
static doris_udf::StringVal money_format(doris_udf::FunctionContext* context,
|
||||
const doris_udf::LargeIntVal& v);
|
||||
|
||||
struct CommaMoneypunct : std::moneypunct<char> {
|
||||
pattern do_pos_format() const override { return {{none, sign, none, value}}; }
|
||||
pattern do_neg_format() const override { return {{none, sign, none, value}}; }
|
||||
int do_frac_digits() const override { return 2; }
|
||||
char_type do_thousands_sep() const override { return ','; }
|
||||
string_type do_grouping() const override { return "\003"; }
|
||||
string_type do_negative_sign() const override { return "-"; }
|
||||
};
|
||||
|
||||
static StringVal do_money_format(FunctionContext *context, const std::string& v) {
|
||||
std::locale comma_locale(std::locale(), new CommaMoneypunct ());
|
||||
std::stringstream ss;
|
||||
ss.imbue(comma_locale);
|
||||
ss << std::put_money(v);
|
||||
return AnyValUtil::from_string_temp(context, ss.str());
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user