diff options
author | imunkin <imunkin@yandex-team.com> | 2024-11-08 10:00:23 +0300 |
---|---|---|
committer | imunkin <imunkin@yandex-team.com> | 2024-11-08 10:12:13 +0300 |
commit | a784a2f943d6e15caa6241e2e96d80aac6dbf375 (patch) | |
tree | 05f1e5366c916b988a8afb75bdab8ddeee0f6e6d /yql/essentials/udfs/common/python/bindings/py_decimal.cpp | |
parent | d70137a7b530ccaa52834274913bbb5a3d1ca06e (diff) | |
download | ydb-a784a2f943d6e15caa6241e2e96d80aac6dbf375.tar.gz |
Move yql/udfs/common/ to /yql/essentials YQL-19206
Except the following directories:
* clickhouse/client
* datetime
* knn
* roaring
commit_hash:c7da95636144d28db109d6b17ddc762e9bacb59f
Diffstat (limited to 'yql/essentials/udfs/common/python/bindings/py_decimal.cpp')
-rw-r--r-- | yql/essentials/udfs/common/python/bindings/py_decimal.cpp | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/yql/essentials/udfs/common/python/bindings/py_decimal.cpp b/yql/essentials/udfs/common/python/bindings/py_decimal.cpp new file mode 100644 index 0000000000..0070e3420f --- /dev/null +++ b/yql/essentials/udfs/common/python/bindings/py_decimal.cpp @@ -0,0 +1,59 @@ +#include "py_decimal.h" +#include "py_errors.h" +#include "py_utils.h" +#include "py_cast.h" + +#include <util/stream/str.h> + +#include <yql/essentials/public/udf/udf_value.h> + +using namespace NKikimr; + +namespace NPython { + +TPyObjectPtr ToPyDecimal(const TPyCastContext::TPtr& ctx, const NKikimr::NUdf::TUnboxedValuePod& value, ui8 precision, ui8 scale) +{ + const auto str = NYql::NDecimal::ToString(value.GetInt128(), precision, scale); + PY_ENSURE(str, "Bad decimal value."); + + const TPyObjectPtr pyStr(PyRepr(str)); + + const TPyObjectPtr args(PyTuple_Pack(1, pyStr.Get())); + PY_ENSURE(args, "Can't pack args."); + + const TPyObjectPtr dec(PyObject_CallObject(ctx->GetDecimal().Get(), args.Get())); + PY_ENSURE(dec, "Can't create Decimal."); + return dec; +} + +NKikimr::NUdf::TUnboxedValue FromPyDecimal(const TPyCastContext::TPtr& ctx, PyObject* value, ui8 precision, ui8 scale) +{ + const TPyObjectPtr print(PyObject_Str(value)); + PY_ENSURE(print, "Can't print decimal."); + + TString str; + PY_ENSURE(TryPyCast<TString>(print.Get(), str), "Can't get decimal string."); + + if (str.EndsWith("Infinity")) { + str.resize(str.size() - 5U); + } + + const auto dec = NYql::NDecimal::FromStringEx(str.c_str(), precision, scale); + PY_ENSURE(!NYql::NDecimal::IsError(dec), "Can't make Decimal from string."); + + return NKikimr::NUdf::TUnboxedValuePod(dec); +} + +const TPyObjectPtr& TPyCastContext::GetDecimal() { + if (!Decimal) { + const TPyObjectPtr module(PyImport_ImportModule("decimal")); + PY_ENSURE(module, "Can't import decimal."); + + Decimal.ResetSteal(PyObject_GetAttrString(module.Get(), "Decimal")); + PY_ENSURE(Decimal, "Can't get Decimal."); + } + + return Decimal; +} + +} // namespace NPython |