summaryrefslogtreecommitdiffstats
path: root/yql/essentials/udfs/common/json/json_udf.cpp
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/json/json_udf.cpp
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/json/json_udf.cpp')
-rw-r--r--yql/essentials/udfs/common/json/json_udf.cpp120
1 files changed, 120 insertions, 0 deletions
diff --git a/yql/essentials/udfs/common/json/json_udf.cpp b/yql/essentials/udfs/common/json/json_udf.cpp
new file mode 100644
index 00000000000..3a7916bed74
--- /dev/null
+++ b/yql/essentials/udfs/common/json/json_udf.cpp
@@ -0,0 +1,120 @@
+#include <yql/essentials/public/udf/udf_helpers.h>
+
+#include <library/cpp/json/easy_parse/json_easy_parser.h>
+
+using namespace NKikimr;
+using namespace NUdf;
+
+namespace {
+ class TGetField: public TBoxedValue {
+ public:
+ typedef bool TTypeAwareMarker;
+
+ public:
+ static TStringRef Name() {
+ return TStringRef::Of("GetField");
+ }
+
+ TUnboxedValue Run(
+ const IValueBuilder* valueBuilder,
+ const TUnboxedValuePod* args) const override {
+ if (!args[0]) {
+ return valueBuilder->NewEmptyList();
+ }
+
+ const TString json(args[0].AsStringRef());
+ const TString field(args[1].AsStringRef());
+
+ if (field.empty()) {
+ return valueBuilder->NewEmptyList();
+ }
+
+ NJson::TJsonParser parser;
+ parser.AddField(field, false);
+
+ TVector<TString> result;
+ parser.Parse(json, &result);
+
+ TUnboxedValue* items = nullptr;
+ const auto list = valueBuilder->NewArray(result.size(), items);
+ for (const TString& item : result) {
+ *items++ = valueBuilder->NewString(item);
+ }
+
+ return list;
+ }
+
+ static bool DeclareSignature(
+ const TStringRef& name,
+ TType* userType,
+ IFunctionTypeInfoBuilder& builder,
+ bool typesOnly) {
+ if (Name() == name) {
+ bool useString = true;
+ bool isOptional = true;
+ if (userType) {
+ // support of an overload with Json/Json? input type
+ auto typeHelper = builder.TypeInfoHelper();
+ auto userTypeInspector = TTupleTypeInspector(*typeHelper, userType);
+ if (!userTypeInspector || userTypeInspector.GetElementsCount() < 1) {
+ builder.SetError("Missing or invalid user type.");
+ return true;
+ }
+
+ auto argsTypeTuple = userTypeInspector.GetElementType(0);
+ auto argsTypeInspector = TTupleTypeInspector(*typeHelper, argsTypeTuple);
+ if (!argsTypeInspector) {
+ builder.SetError("Invalid user type - expected tuple.");
+ return true;
+ }
+
+ if (argsTypeInspector.GetElementsCount() != 2) {
+ builder.SetError("Invalid user type - expected two arguments.");
+ return true;
+ }
+
+ auto inputType = argsTypeInspector.GetElementType(0);
+ auto optInspector = TOptionalTypeInspector(*typeHelper, inputType);
+ auto dataType = inputType;
+ if (optInspector) {
+ dataType = optInspector.GetItemType();
+ } else {
+ isOptional = false;
+ }
+
+ auto dataInspector = TDataTypeInspector(*typeHelper, dataType);
+ if (dataInspector && dataInspector.GetTypeId() == TDataType<TJson>::Id) {
+ useString = false;
+ builder.UserType(userType);
+ }
+ }
+
+ auto retType = builder.List()->Item<char*>().Build();
+ if (useString) {
+ builder.Args()->Add(builder.Optional()->Item<char*>().Build()).Add<char*>().Done().Returns(retType);
+ } else {
+ auto type = builder.SimpleType<TJson>();
+ if (isOptional) {
+ builder.Args()->Add(builder.Optional()->Item(type).Build()).Add<char*>().Done().Returns(retType);
+ } else {
+ builder.Args()->Add(type).Add<char*>().Done().Returns(retType);
+ }
+ }
+
+ if (!typesOnly) {
+ builder.Implementation(new TGetField);
+ }
+
+ builder.IsStrict();
+ return true;
+ } else {
+ return false;
+ }
+ }
+ };
+}
+
+SIMPLE_MODULE(TJsonModule,
+ TGetField)
+
+REGISTER_MODULES(TJsonModule)