aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/udfs/common/python/bindings/py_decimal.cpp
diff options
context:
space:
mode:
authorimunkin <imunkin@yandex-team.com>2024-11-08 10:00:23 +0300
committerimunkin <imunkin@yandex-team.com>2024-11-08 10:12:13 +0300
commita784a2f943d6e15caa6241e2e96d80aac6dbf375 (patch)
tree05f1e5366c916b988a8afb75bdab8ddeee0f6e6d /yql/essentials/udfs/common/python/bindings/py_decimal.cpp
parentd70137a7b530ccaa52834274913bbb5a3d1ca06e (diff)
downloadydb-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.cpp59
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