summaryrefslogtreecommitdiffstats
path: root/yql/essentials/udfs/common/json2/as_json_node.h
diff options
context:
space:
mode:
authorimunkin <[email protected]>2024-11-08 10:00:23 +0300
committerimunkin <[email protected]>2024-11-08 10:12:13 +0300
commita784a2f943d6e15caa6241e2e96d80aac6dbf375 (patch)
tree05f1e5366c916b988a8afb75bdab8ddeee0f6e6d /yql/essentials/udfs/common/json2/as_json_node.h
parentd70137a7b530ccaa52834274913bbb5a3d1ca06e (diff)
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/json2/as_json_node.h')
-rw-r--r--yql/essentials/udfs/common/json2/as_json_node.h115
1 files changed, 115 insertions, 0 deletions
diff --git a/yql/essentials/udfs/common/json2/as_json_node.h b/yql/essentials/udfs/common/json2/as_json_node.h
new file mode 100644
index 00000000000..c7463fffa66
--- /dev/null
+++ b/yql/essentials/udfs/common/json2/as_json_node.h
@@ -0,0 +1,115 @@
+#pragma once
+
+#include "resource.h"
+
+#include <yql/essentials/public/udf/udf_value.h>
+#include <yql/essentials/public/udf/udf_helpers.h>
+#include <yql/essentials/minikql/dom/node.h>
+#include <yql/essentials/minikql/dom/json.h>
+
+namespace NJson2Udf {
+ using namespace NKikimr;
+ using namespace NUdf;
+ using namespace NYql;
+ using namespace NDom;
+
+ template <typename TSource>
+ class TAsJsonNode: public TBoxedValue {
+ public:
+ TAsJsonNode(TSourcePosition pos)
+ : Pos_(pos)
+ {
+ }
+
+ static TStringRef Name();
+
+ static bool DeclareSignature(
+ const TStringRef& name,
+ TType* userType,
+ IFunctionTypeInfoBuilder& builder,
+ bool typesOnly) {
+ Y_UNUSED(userType);
+ if (name != Name()) {
+ return false;
+ }
+
+ auto optionalSourceType = builder.Optional()->Item<TSource>().Build();
+ auto resourceType = builder.Resource(JSON_NODE_RESOURCE_NAME);
+ builder.Args()
+ ->Add(optionalSourceType)
+ .Done()
+ .Returns(resourceType);
+
+ if (!typesOnly) {
+ builder.Implementation(new TAsJsonNode<TSource>(builder.GetSourcePosition()));
+ }
+
+ builder.IsStrict();
+ return true;
+ }
+
+ private:
+ const size_t MaxParseErrors = 10;
+
+ static TUnboxedValue Interpret(const TUnboxedValue& sourceValue, const IValueBuilder* valueBuilder);
+
+ TUnboxedValue Run(
+ const IValueBuilder* valueBuilder,
+ const TUnboxedValuePod* args) const final {
+ Y_UNUSED(valueBuilder);
+ try {
+ if (!args[0].HasValue()) {
+ return MakeEntity();
+ }
+ return Interpret(args[0], valueBuilder);
+ } catch (const std::exception& e) {
+ UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
+ }
+ }
+
+ TSourcePosition Pos_;
+ };
+
+ template <>
+ TStringRef TAsJsonNode<TUtf8>::Name() {
+ return TStringRef::Of("Utf8AsJsonNode");
+ }
+
+ template <>
+ TUnboxedValue TAsJsonNode<TUtf8>::Interpret(const TUnboxedValue& sourceValue, const IValueBuilder* valueBuilder) {
+ return MakeString(sourceValue.AsStringRef(), valueBuilder);
+ }
+
+ template <>
+ TStringRef TAsJsonNode<double>::Name() {
+ return TStringRef::Of("DoubleAsJsonNode");
+ }
+
+ template <>
+ TUnboxedValue TAsJsonNode<double>::Interpret(const TUnboxedValue& sourceValue, const IValueBuilder* valueBuilder) {
+ Y_UNUSED(valueBuilder);
+ return MakeDouble(sourceValue.Get<double>());
+ }
+
+ template <>
+ TStringRef TAsJsonNode<bool>::Name() {
+ return TStringRef::Of("BoolAsJsonNode");
+ }
+
+ template <>
+ TUnboxedValue TAsJsonNode<bool>::Interpret(const TUnboxedValue& sourceValue, const IValueBuilder* valueBuilder) {
+ Y_UNUSED(valueBuilder);
+ return MakeBool(sourceValue.Get<bool>());
+ }
+
+ template <>
+ TStringRef TAsJsonNode<TJson>::Name() {
+ return TStringRef::Of("JsonAsJsonNode");
+ }
+
+ template <>
+ TUnboxedValue TAsJsonNode<TJson>::Interpret(const TUnboxedValue& sourceValue, const IValueBuilder* valueBuilder) {
+ return TryParseJsonDom(sourceValue.AsStringRef(), valueBuilder);
+ }
+}
+