diff options
author | vvvv <[email protected]> | 2025-10-06 13:26:25 +0300 |
---|---|---|
committer | vvvv <[email protected]> | 2025-10-06 14:06:25 +0300 |
commit | eca8ce9cb1613d5c983185c4e43c20651a9638aa (patch) | |
tree | 61ee5ae779948e61af9a7691d19eaa2c09869121 /yql/essentials/udfs/common/url_base/lib | |
parent | 4adf7eecae16a9b228b28cc5f64c27ef69ad5ec2 (diff) |
YQL-20086 udfs
init
commit_hash:f9684778bf1ea956965f2360b80b91edb7d4ffbe
Diffstat (limited to 'yql/essentials/udfs/common/url_base/lib')
7 files changed, 463 insertions, 451 deletions
diff --git a/yql/essentials/udfs/common/url_base/lib/url_base_udf.cpp b/yql/essentials/udfs/common/url_base/lib/url_base_udf.cpp index 50a3ee8d1f1..778a3088b7f 100644 --- a/yql/essentials/udfs/common/url_base/lib/url_base_udf.cpp +++ b/yql/essentials/udfs/common/url_base/lib/url_base_udf.cpp @@ -1 +1 @@ -#include "url_base_udf.h"
\ No newline at end of file +#include "url_base_udf.h" diff --git a/yql/essentials/udfs/common/url_base/lib/url_base_udf.h b/yql/essentials/udfs/common/url_base/lib/url_base_udf.h index 04ad1b4e469..676d7a802d1 100644 --- a/yql/essentials/udfs/common/url_base/lib/url_base_udf.h +++ b/yql/essentials/udfs/common/url_base/lib/url_base_udf.h @@ -26,28 +26,27 @@ inline bool PrepareUrl(const std::string_view& keyStr, TUri& parser) { return parser.ParseAbs(keyStr, parseFlags) == TUri::ParsedOK; } -#define ARROW_UDF_SINGLE_STRING_FUNCTION_FOR_URL(udfName, functionName) \ - BEGIN_SIMPLE_ARROW_UDF(udfName, TOptional<char*>(TOptional<char*>)) { \ - EMPTY_RESULT_ON_EMPTY_ARG(0); \ - const std::string_view url(args[0].AsStringRef()); \ - const std::string_view res(functionName(url)); \ - return res.empty() ? TUnboxedValue() : \ - valueBuilder->SubString(args[0], std::distance(url.begin(), res.begin()), res.size()); \ - } \ - struct udfName##KernelExec : public TUnaryKernelExec<udfName##KernelExec> { \ - template <typename TSink> \ - static void Process(const IValueBuilder*, TBlockItem arg, const TSink& sink) { \ - if (!arg) { \ - return sink(TBlockItem()); \ - } \ - const std::string_view url(arg.AsStringRef()); \ - const std::string_view res(functionName(url)); \ - if (res.empty()) { \ - return sink(TBlockItem()); \ - } \ - sink(TBlockItem(TStringRef(res))); \ - } \ - }; \ +#define ARROW_UDF_SINGLE_STRING_FUNCTION_FOR_URL(udfName, functionName) \ + BEGIN_SIMPLE_ARROW_UDF(udfName, TOptional<char*>(TOptional<char*>)) { \ + EMPTY_RESULT_ON_EMPTY_ARG(0); \ + const std::string_view url(args[0].AsStringRef()); \ + const std::string_view res(functionName(url)); \ + return res.empty() ? TUnboxedValue() : valueBuilder->SubString(args[0], std::distance(url.begin(), res.begin()), res.size()); \ + } \ + struct udfName##KernelExec: public TUnaryKernelExec<udfName##KernelExec> { \ + template <typename TSink> \ + static void Process(const IValueBuilder*, TBlockItem arg, const TSink& sink) { \ + if (!arg) { \ + return sink(TBlockItem()); \ + } \ + const std::string_view url(arg.AsStringRef()); \ + const std::string_view res(functionName(url)); \ + if (res.empty()) { \ + return sink(TBlockItem()); \ + } \ + sink(TBlockItem(TStringRef(res))); \ + } \ + }; \ END_SIMPLE_ARROW_UDF(udfName, udfName##KernelExec::Do); BEGIN_SIMPLE_ARROW_UDF(TNormalize, TOptional<char*>(TOptional<char*>)) { @@ -55,10 +54,10 @@ BEGIN_SIMPLE_ARROW_UDF(TNormalize, TOptional<char*>(TOptional<char*>)) { TUri url; const bool success = PrepareUrl(args[0].AsStringRef(), url); return success - ? valueBuilder->NewString(url.PrintS(TUri::FlagNoFrag)) - : TUnboxedValue(); + ? valueBuilder->NewString(url.PrintS(TUri::FlagNoFrag)) + : TUnboxedValue(); } -struct TNormalizeKernelExec : public TUnaryKernelExec<TNormalizeKernelExec> { +struct TNormalizeKernelExec: public TUnaryKernelExec<TNormalizeKernelExec> { template <typename TSink> static void Process(const IValueBuilder*, TBlockItem arg, const TSink& sink) { if (!arg) { @@ -79,7 +78,7 @@ BEGIN_SIMPLE_STRICT_ARROW_UDF(TGetScheme, char*(TAutoMap<char*>)) { const std::string_view prefix(GetSchemePrefix(url)); return valueBuilder->SubString(args[0], std::distance(url.begin(), prefix.begin()), prefix.size()); } -struct TGetSchemeKernelExec : public TUnaryKernelExec<TGetSchemeKernelExec> { +struct TGetSchemeKernelExec: public TUnaryKernelExec<TGetSchemeKernelExec> { template <typename TSink> static void Process(const IValueBuilder*, TBlockItem arg, const TSink& sink) { const std::string_view url(arg.AsStringRef()); @@ -117,12 +116,12 @@ BEGIN_SIMPLE_ARROW_UDF(TGetPort, TOptional<ui64>(TOptional<char*>)) { TStringBuf scheme, host; TString lowerUri(args[0].AsStringRef()); std::transform(lowerUri.cbegin(), lowerUri.cbegin() + GetSchemePrefixSize(lowerUri), - lowerUri.begin(), [](unsigned char c){ return std::tolower(c); }); + lowerUri.begin(), [](unsigned char c) { return std::tolower(c); }); return TryGetSchemeHostAndPort(lowerUri, scheme, host, port) && port - ? TUnboxedValuePod(port) - : TUnboxedValuePod(); + ? TUnboxedValuePod(port) + : TUnboxedValuePod(); } -struct TGetPortKernelExec : public TUnaryKernelExec<TGetPortKernelExec> { +struct TGetPortKernelExec: public TUnaryKernelExec<TGetPortKernelExec> { template <typename TSink> static void Process(const IValueBuilder*, TBlockItem arg, const TSink& sink) { if (!arg) { @@ -132,7 +131,7 @@ struct TGetPortKernelExec : public TUnaryKernelExec<TGetPortKernelExec> { TStringBuf scheme, host; TString lowerUri(arg.AsStringRef()); std::transform(lowerUri.cbegin(), lowerUri.cbegin() + GetSchemePrefixSize(lowerUri), - lowerUri.begin(), [](unsigned char c){ return std::tolower(c); }); + lowerUri.begin(), [](unsigned char c) { return std::tolower(c); }); if (TryGetSchemeHostAndPort(lowerUri, scheme, host, port) && port) { return sink(TBlockItem(port)); } @@ -147,10 +146,10 @@ BEGIN_SIMPLE_ARROW_UDF(TGetTail, TOptional<char*>(TOptional<char*>)) { TStringBuf host, tail; SplitUrlToHostAndPath(url, host, tail); return tail.StartsWith('/') - ? valueBuilder->NewString(tail) - : valueBuilder->NewString(TString('/').append(tail)); + ? valueBuilder->NewString(tail) + : valueBuilder->NewString(TString('/').append(tail)); } -struct TGetTailKernelExec : public TUnaryKernelExec<TGetTailKernelExec> { +struct TGetTailKernelExec: public TUnaryKernelExec<TGetTailKernelExec> { template <typename TSink> static void Process(const IValueBuilder*, TBlockItem arg, const TSink& sink) { if (!arg) { @@ -184,7 +183,7 @@ BEGIN_SIMPLE_ARROW_UDF(TGetPath, TOptional<char*>(TOptional<char*>)) { return valueBuilder->SubString(args[0], std::distance(url.begin(), cut.begin()), cut.length()); } -struct TGetPathKernelExec : public TUnaryKernelExec<TGetPathKernelExec> { +struct TGetPathKernelExec: public TUnaryKernelExec<TGetPathKernelExec> { template <typename TSink> static void Process(const IValueBuilder*, TBlockItem arg, const TSink& sink) { if (!arg) { @@ -211,10 +210,9 @@ BEGIN_SIMPLE_ARROW_UDF(TGetFragment, TOptional<char*>(TOptional<char*>)) { EMPTY_RESULT_ON_EMPTY_ARG(0); const std::string_view url(args[0].AsStringRef()); const auto pos = url.find('#'); - return pos == std::string_view::npos ? TUnboxedValue() : - valueBuilder->SubString(args[0], pos + 1U, url.length() - pos - 1U); + return pos == std::string_view::npos ? TUnboxedValue() : valueBuilder->SubString(args[0], pos + 1U, url.length() - pos - 1U); } -struct TGetFragmentKernelExec : public TUnaryKernelExec<TGetFragmentKernelExec> { +struct TGetFragmentKernelExec: public TUnaryKernelExec<TGetFragmentKernelExec> { template <typename TSink> static void Process(const IValueBuilder*, TBlockItem arg, const TSink& sink) { if (!arg) { @@ -254,7 +252,7 @@ BEGIN_SIMPLE_ARROW_UDF(TGetDomain, TOptional<char*>(TOptional<char*>, ui8)) { const std::pair<ui32, ui32> result = *resultOpt; return valueBuilder->SubString(args[0], result.first, result.second); } -struct TGetDomainKernelExec : public TBinaryKernelExec<TGetDomainKernelExec> { +struct TGetDomainKernelExec: public TBinaryKernelExec<TGetDomainKernelExec> { template <typename TSink> static void Process(const IValueBuilder*, TBlockItem arg1, TBlockItem arg2, const TSink& sink) { if (!arg1) { @@ -274,7 +272,7 @@ BEGIN_SIMPLE_ARROW_UDF(TGetTLD, char*(TAutoMap<char*>)) { const TStringBuf url(args[0].AsStringRef()); return valueBuilder->NewString(GetZone(GetOnlyHost(url))); } -struct TGetTLDKernelExec : public TUnaryKernelExec<TGetTLDKernelExec> { +struct TGetTLDKernelExec: public TUnaryKernelExec<TGetTLDKernelExec> { template <typename TSink> static void Process(const IValueBuilder*, TBlockItem arg, const TSink& sink) { const TStringBuf url(arg.AsStringRef()); @@ -289,7 +287,7 @@ BEGIN_SIMPLE_ARROW_UDF(TGetDomainLevel, ui64(TAutoMap<char*>)) { StringSplitter(GetOnlyHost(args[0].AsStringRef())).Split('.').AddTo(&parts); return TUnboxedValuePod(ui64(parts.size())); } -struct TGetDomainLevelKernelExec : public TUnaryKernelExec<TGetDomainLevelKernelExec> { +struct TGetDomainLevelKernelExec: public TUnaryKernelExec<TGetDomainLevelKernelExec> { template <typename TSink> static void Process(const IValueBuilder*, TBlockItem arg, const TSink& sink) { std::vector<std::string_view> parts; @@ -358,7 +356,7 @@ BEGIN_SIMPLE_ARROW_UDF(TGetCGIParam, TOptional<char*>(TOptional<char*>, char*)) const std::pair<ui32, ui32> result = *resultOpt; return valueBuilder->SubString(args[0], result.first, result.second); } -struct TGetCGIParamKernelExec : public TBinaryKernelExec<TGetCGIParamKernelExec> { +struct TGetCGIParamKernelExec: public TBinaryKernelExec<TGetCGIParamKernelExec> { template <typename TSink> static void Process(const IValueBuilder*, TBlockItem arg1, TBlockItem arg2, const TSink& sink) { if (!arg1) { @@ -385,7 +383,7 @@ BEGIN_SIMPLE_ARROW_UDF(TCutQueryStringAndFragment, char*(TAutoMap<char*>)) { const auto cut = input.find_first_of("?#"); return std::string_view::npos == cut ? NUdf::TUnboxedValue(args[0]) : valueBuilder->SubString(args[0], 0U, cut); } -struct TCutQueryStringAndFragmentKernelExec : public TUnaryKernelExec<TCutQueryStringAndFragmentKernelExec> { +struct TCutQueryStringAndFragmentKernelExec: public TUnaryKernelExec<TCutQueryStringAndFragmentKernelExec> { template <typename TSink> static void Process(const IValueBuilder*, TBlockItem arg, const TSink& sink) { const std::string_view input(arg.AsStringRef()); @@ -405,7 +403,7 @@ BEGIN_SIMPLE_ARROW_UDF(TEncode, TOptional<char*>(TOptional<char*>)) { UrlEscape(url); return input == url ? NUdf::TUnboxedValue(args[0]) : valueBuilder->NewString(url); } -struct TEncodeKernelExec : public TUnaryKernelExec<TEncodeKernelExec> { +struct TEncodeKernelExec: public TUnaryKernelExec<TEncodeKernelExec> { template <typename TSink> static void Process(const IValueBuilder*, TBlockItem arg, const TSink& sink) { if (!arg) { @@ -433,7 +431,7 @@ BEGIN_SIMPLE_ARROW_UDF(TDecode, TOptional<char*>(TOptional<char*>)) { UrlUnescape(url); return input == url ? NUdf::TUnboxedValue(args[0]) : valueBuilder->NewString(url); } -struct TDecodeKernelExec : public TUnaryKernelExec<TDecodeKernelExec> { +struct TDecodeKernelExec: public TUnaryKernelExec<TDecodeKernelExec> { template <typename TSink> static void Process(const IValueBuilder*, TBlockItem arg, const TSink& sink) { if (!arg) { @@ -455,7 +453,7 @@ BEGIN_SIMPLE_ARROW_UDF(TIsKnownTLD, bool(TAutoMap<char*>)) { Y_UNUSED(valueBuilder); return TUnboxedValuePod(IsTld(args[0].AsStringRef())); } -struct TIsKnownTLDKernelExec : public TUnaryKernelExec<TIsKnownTLDKernelExec> { +struct TIsKnownTLDKernelExec: public TUnaryKernelExec<TIsKnownTLDKernelExec> { template <typename TSink> static void Process(const IValueBuilder*, TBlockItem arg, const TSink& sink) { sink(TBlockItem(static_cast<ui8>(IsTld(arg.AsStringRef())))); @@ -467,7 +465,7 @@ BEGIN_SIMPLE_ARROW_UDF(TIsWellKnownTLD, bool(TAutoMap<char*>)) { Y_UNUSED(valueBuilder); return TUnboxedValuePod(IsVeryGoodTld(args[0].AsStringRef())); } -struct TIsWellKnownTLDKernelExec : public TUnaryKernelExec<TIsWellKnownTLDKernelExec> { +struct TIsWellKnownTLDKernelExec: public TUnaryKernelExec<TIsWellKnownTLDKernelExec> { template <typename TSink> static void Process(const IValueBuilder*, TBlockItem arg, const TSink& sink) { sink(TBlockItem(static_cast<ui8>(IsVeryGoodTld(arg.AsStringRef())))); @@ -475,13 +473,14 @@ struct TIsWellKnownTLDKernelExec : public TUnaryKernelExec<TIsWellKnownTLDKernel }; END_SIMPLE_ARROW_UDF(TIsWellKnownTLD, TIsWellKnownTLDKernelExec::Do); -BEGIN_SIMPLE_ARROW_UDF(THostNameToPunycode, TOptional<char*>(TAutoMap<char*>)) try { +BEGIN_SIMPLE_ARROW_UDF(THostNameToPunycode, TOptional<char*>(TAutoMap<char*>)) +try { const TUtf16String& input = UTF8ToWide(args[0].AsStringRef()); return valueBuilder->NewString(HostNameToPunycode(input)); } catch (TPunycodeError&) { return TUnboxedValue(); } -struct THostNameToPunycodeKernelExec : public TUnaryKernelExec<THostNameToPunycodeKernelExec> { +struct THostNameToPunycodeKernelExec: public TUnaryKernelExec<THostNameToPunycodeKernelExec> { template <typename TSink> static void Process(const IValueBuilder*, TBlockItem arg, const TSink& sink) try { const TUtf16String& input = UTF8ToWide(arg.AsStringRef()); @@ -496,7 +495,7 @@ BEGIN_SIMPLE_ARROW_UDF(TForceHostNameToPunycode, char*(TAutoMap<char*>)) { const TUtf16String& input = UTF8ToWide(args[0].AsStringRef()); return valueBuilder->NewString(ForceHostNameToPunycode(input)); } -struct TForceHostNameToPunycodeKernelExec : public TUnaryKernelExec<TForceHostNameToPunycodeKernelExec> { +struct TForceHostNameToPunycodeKernelExec: public TUnaryKernelExec<TForceHostNameToPunycodeKernelExec> { template <typename TSink> static void Process(const IValueBuilder*, TBlockItem arg, const TSink& sink) { const TUtf16String& input = UTF8ToWide(arg.AsStringRef()); @@ -505,14 +504,15 @@ struct TForceHostNameToPunycodeKernelExec : public TUnaryKernelExec<TForceHostNa }; END_SIMPLE_ARROW_UDF(TForceHostNameToPunycode, TForceHostNameToPunycodeKernelExec::Do); -BEGIN_SIMPLE_ARROW_UDF(TPunycodeToHostName, TOptional<char*>(TAutoMap<char*>)) try { +BEGIN_SIMPLE_ARROW_UDF(TPunycodeToHostName, TOptional<char*>(TAutoMap<char*>)) +try { const TStringRef& input = args[0].AsStringRef(); const auto& result = WideToUTF8(PunycodeToHostName(input)); return valueBuilder->NewString(result); } catch (TPunycodeError&) { return TUnboxedValue(); } -struct TPunycodeToHostNameKernelExec : public TUnaryKernelExec<TPunycodeToHostNameKernelExec> { +struct TPunycodeToHostNameKernelExec: public TUnaryKernelExec<TPunycodeToHostNameKernelExec> { template <typename TSink> static void Process(const IValueBuilder*, TBlockItem arg, const TSink& sink) try { const TStringRef& input = arg.AsStringRef(); @@ -529,7 +529,7 @@ BEGIN_SIMPLE_ARROW_UDF(TForcePunycodeToHostName, char*(TAutoMap<char*>)) { const auto& result = WideToUTF8(ForcePunycodeToHostName(input)); return valueBuilder->NewString(result); } -struct TForcePunycodeToHostNameKernelExec : public TUnaryKernelExec<TForcePunycodeToHostNameKernelExec> { +struct TForcePunycodeToHostNameKernelExec: public TUnaryKernelExec<TForcePunycodeToHostNameKernelExec> { template <typename TSink> static void Process(const IValueBuilder*, TBlockItem arg, const TSink& sink) { const TStringRef& input = arg.AsStringRef(); @@ -543,7 +543,7 @@ BEGIN_SIMPLE_ARROW_UDF(TCanBePunycodeHostName, bool(TAutoMap<char*>)) { Y_UNUSED(valueBuilder); return TUnboxedValuePod(CanBePunycodeHostName(args[0].AsStringRef())); } -struct TCanBePunycodeHostNameKernelExec : public TUnaryKernelExec<TCanBePunycodeHostNameKernelExec> { +struct TCanBePunycodeHostNameKernelExec: public TUnaryKernelExec<TCanBePunycodeHostNameKernelExec> { template <typename TSink> static void Process(const IValueBuilder*, TBlockItem arg, const TSink& sink) { sink(TBlockItem(static_cast<ui8>(CanBePunycodeHostName(arg.AsStringRef())))); @@ -551,36 +551,36 @@ struct TCanBePunycodeHostNameKernelExec : public TUnaryKernelExec<TCanBePunycode }; END_SIMPLE_ARROW_UDF(TCanBePunycodeHostName, TCanBePunycodeHostNameKernelExec::Do); -#define EXPORTED_URL_BASE_UDF \ - TNormalize, \ - TParse, \ - TGetScheme, \ - TGetHost, \ - TGetHostPort, \ - TGetSchemeHost, \ - TGetSchemeHostPort, \ - TGetPort, \ - TGetTail, \ - TGetPath, \ - TGetFragment, \ - TGetDomain, \ - TGetTLD, \ - TGetDomainLevel, \ - TGetSignificantDomain, \ - TGetCGIParam, \ - TCutScheme, \ - TCutWWW, \ - TCutWWW2, \ - TCutQueryStringAndFragment, \ - TEncode, \ - TDecode, \ - TIsKnownTLD, \ - TIsWellKnownTLD, \ - THostNameToPunycode, \ - TForceHostNameToPunycode, \ - TPunycodeToHostName, \ - TForcePunycodeToHostName, \ - TCanBePunycodeHostName, \ - TQueryStringToList, \ - TQueryStringToDict, \ - TBuildQueryString +#define EXPORTED_URL_BASE_UDF \ + TNormalize, \ + TParse, \ + TGetScheme, \ + TGetHost, \ + TGetHostPort, \ + TGetSchemeHost, \ + TGetSchemeHostPort, \ + TGetPort, \ + TGetTail, \ + TGetPath, \ + TGetFragment, \ + TGetDomain, \ + TGetTLD, \ + TGetDomainLevel, \ + TGetSignificantDomain, \ + TGetCGIParam, \ + TCutScheme, \ + TCutWWW, \ + TCutWWW2, \ + TCutQueryStringAndFragment, \ + TEncode, \ + TDecode, \ + TIsKnownTLD, \ + TIsWellKnownTLD, \ + THostNameToPunycode, \ + TForceHostNameToPunycode, \ + TPunycodeToHostName, \ + TForcePunycodeToHostName, \ + TCanBePunycodeHostName, \ + TQueryStringToList, \ + TQueryStringToDict, \ + TBuildQueryString diff --git a/yql/essentials/udfs/common/url_base/lib/url_parse.cpp b/yql/essentials/udfs/common/url_base/lib/url_parse.cpp index 34485970ee0..c892bf25f6f 100644 --- a/yql/essentials/udfs/common/url_base/lib/url_parse.cpp +++ b/yql/essentials/udfs/common/url_base/lib/url_parse.cpp @@ -1,53 +1,53 @@ #include "url_parse.h" #define FIELD_ADD(name) structBuilder->AddField(#name, optionalStringType, &urlParseIndexes.name); -#define FIELD_FILL(name) \ - if (value.FldIsSet(TUri::Field##name)) { \ +#define FIELD_FILL(name) \ + if (value.FldIsSet(TUri::Field##name)) { \ fields[UrlParseIndexes_.name] = valueBuilder->NewString(value.GetField(TUri::Field##name)); \ } namespace NUrlUdf { - using namespace NUri; - using namespace NKikimr; - using namespace NUdf; +using namespace NUri; +using namespace NKikimr; +using namespace NUdf; - TUnboxedValue TParse::Run( - const IValueBuilder* valueBuilder, - const TUnboxedValuePod* args) const { - TUri value; - const auto ParseError = value.ParseAbs(args[0].AsStringRef(), ParseFlags_); - TUnboxedValue* fields = nullptr; - const auto result = valueBuilder->NewArray(FieldsCount, fields); - if (ParseError == TUri::ParsedOK) { - FIELD_MAP(FIELD_FILL) - } else { - fields[UrlParseIndexes_.ParseError] = valueBuilder->NewString(TStringBuilder() << ParseError); - } - return result; +TUnboxedValue TParse::Run( + const IValueBuilder* valueBuilder, + const TUnboxedValuePod* args) const { + TUri value; + const auto ParseError = value.ParseAbs(args[0].AsStringRef(), ParseFlags_); + TUnboxedValue* fields = nullptr; + const auto result = valueBuilder->NewArray(FieldsCount, fields); + if (ParseError == TUri::ParsedOK) { + FIELD_MAP(FIELD_FILL) + } else { + fields[UrlParseIndexes_.ParseError] = valueBuilder->NewString(TStringBuilder() << ParseError); } + return result; +} - bool TParse::DeclareSignature( - const TStringRef& name, - TType* userType, - IFunctionTypeInfoBuilder& builder, - bool typesOnly) { - Y_UNUSED(userType); - if (Name() == name) { - TUrlParseIndexes urlParseIndexes; +bool TParse::DeclareSignature( + const TStringRef& name, + TType* userType, + IFunctionTypeInfoBuilder& builder, + bool typesOnly) { + Y_UNUSED(userType); + if (Name() == name) { + TUrlParseIndexes urlParseIndexes; - builder.Args(1)->Add<TAutoMap<char*>>(); - const auto optionalStringType = builder.Optional()->Item<char*>().Build(); - const auto structBuilder = builder.Struct(FieldsCount); - structBuilder->AddField("ParseError", optionalStringType, &urlParseIndexes.ParseError); - FIELD_MAP(FIELD_ADD) - builder.Returns(structBuilder->Build()); + builder.Args(1)->Add<TAutoMap<char*>>(); + const auto optionalStringType = builder.Optional()->Item<char*>().Build(); + const auto structBuilder = builder.Struct(FieldsCount); + structBuilder->AddField("ParseError", optionalStringType, &urlParseIndexes.ParseError); + FIELD_MAP(FIELD_ADD) + builder.Returns(structBuilder->Build()); - if (!typesOnly) { - builder.Implementation(new TParse(urlParseIndexes)); - } - return true; - } else { - return false; + if (!typesOnly) { + builder.Implementation(new TParse(urlParseIndexes)); } + return true; + } else { + return false; } } +} // namespace NUrlUdf diff --git a/yql/essentials/udfs/common/url_base/lib/url_parse.h b/yql/essentials/udfs/common/url_base/lib/url_parse.h index e25e79c5196..8dab6ac7f47 100644 --- a/yql/essentials/udfs/common/url_base/lib/url_parse.h +++ b/yql/essentials/udfs/common/url_base/lib/url_parse.h @@ -16,44 +16,44 @@ #define FIELD_INDEXES(name) ui32 name; namespace NUrlUdf { - using namespace NUri; - using namespace NKikimr; - using namespace NUdf; - - struct TUrlParseIndexes { - ui32 ParseError; - FIELD_MAP(FIELD_INDEXES) - }; - - class TParse: public TBoxedValue { - public: - TParse(const TUrlParseIndexes& UrlParseIndexes) - : UrlParseIndexes_(UrlParseIndexes) - , ParseFlags_(TUri::FeaturesRecommended) - { - } - - static const TStringRef& Name() { - static auto nameRef = TStringRef("Parse"); - return nameRef; - } - - private: - TUnboxedValue Run( - const IValueBuilder* valueBuilder, - const TUnboxedValuePod* args) const override; - - public: - static bool DeclareSignature( - const TStringRef& name, - TType* userType, - IFunctionTypeInfoBuilder& builder, - bool typesOnly); - - private: - const TUrlParseIndexes UrlParseIndexes_; - const NUri::TParseFlags ParseFlags_; - - static constexpr ui32 FieldsCount = sizeof(TUrlParseIndexes) / sizeof(ui32); - }; -} +using namespace NUri; +using namespace NKikimr; +using namespace NUdf; + +struct TUrlParseIndexes { + ui32 ParseError; + FIELD_MAP(FIELD_INDEXES) +}; + +class TParse: public TBoxedValue { +public: + TParse(const TUrlParseIndexes& UrlParseIndexes) + : UrlParseIndexes_(UrlParseIndexes) + , ParseFlags_(TUri::FeaturesRecommended) + { + } + + static const TStringRef& Name() { + static auto nameRef = TStringRef("Parse"); + return nameRef; + } + +private: + TUnboxedValue Run( + const IValueBuilder* valueBuilder, + const TUnboxedValuePod* args) const override; + +public: + static bool DeclareSignature( + const TStringRef& name, + TType* userType, + IFunctionTypeInfoBuilder& builder, + bool typesOnly); + +private: + const TUrlParseIndexes UrlParseIndexes_; + const NUri::TParseFlags ParseFlags_; + + static constexpr ui32 FieldsCount = sizeof(TUrlParseIndexes) / sizeof(ui32); +}; +} // namespace NUrlUdf diff --git a/yql/essentials/udfs/common/url_base/lib/url_query.cpp b/yql/essentials/udfs/common/url_base/lib/url_query.cpp index 885dc3b16e9..32dc2e34806 100644 --- a/yql/essentials/udfs/common/url_base/lib/url_query.cpp +++ b/yql/essentials/udfs/common/url_base/lib/url_query.cpp @@ -7,122 +7,125 @@ #include <library/cpp/string_utils/quote/quote.h> namespace NUrlUdf { - void TQueryStringParse::MakeSignature(IFunctionTypeInfoBuilder& builder, - const TType* retType) - { - builder.Returns(retType).OptionalArgs(4); - auto args = builder.Args(); - args->Add<TAutoMap<TQueryStr>>(); - args->Add<TKeepBlankValuesNArg>(); - args->Add<TStrictNArg>(); - args->Add<TMaxFieldsNArg>(); - args->Add<TSeparatorNArg>().Done(); +void TQueryStringParse::MakeSignature(IFunctionTypeInfoBuilder& builder, + const TType* retType) +{ + builder.Returns(retType).OptionalArgs(4); + auto args = builder.Args(); + args->Add<TAutoMap<TQueryStr>>(); + args->Add<TKeepBlankValuesNArg>(); + args->Add<TStrictNArg>(); + args->Add<TMaxFieldsNArg>(); + args->Add<TSeparatorNArg>().Done(); +} + +std::vector<std::pair<TString, TString>> +TQueryStringParse::RunImpl(const TUnboxedValuePod* args) const { + const std::string_view query(args[0].AsStringRef()); + if (query.empty()) { + return {}; } + const bool keepBlankValues = args[1].GetOrDefault(false); + const bool strict = args[2].GetOrDefault(true); + const ui32 maxFieldCnt = args[3].GetOrDefault(Max<ui32>()); + const std::string_view sep(args[4] ? args[4].AsStringRef() : "&"); - std::vector<std::pair<TString, TString>> - TQueryStringParse::RunImpl(const TUnboxedValuePod* args) const { - const std::string_view query(args[0].AsStringRef()); - if (query.empty()) - return {}; - const bool keepBlankValues = args[1].GetOrDefault(false); - const bool strict = args[2].GetOrDefault(true); - const ui32 maxFieldCnt = args[3].GetOrDefault(Max<ui32>()); - const std::string_view sep(args[4] ? args[4].AsStringRef() : "&"); + std::vector<TStringBuf> parts; + StringSplitter(query).SplitByString(sep).Collect(&parts); + if (parts.size() > maxFieldCnt) { + UdfTerminate((TStringBuilder() << Pos_ << "Max number of fields (" << maxFieldCnt + << ") exceeded: got " << parts.size()) + .c_str()); + } - std::vector<TStringBuf> parts; - StringSplitter(query).SplitByString(sep).Collect(&parts); - if (parts.size() > maxFieldCnt) { - UdfTerminate((TStringBuilder() << Pos_ << "Max number of fields (" << maxFieldCnt - << ") exceeded: got " << parts.size()).c_str()); + std::vector<std::pair<TString, TString>> pairs; + for (const TStringBuf& part : parts) { + if (part.empty() && !strict) { + continue; } - - std::vector<std::pair<TString, TString>> pairs; - for (const TStringBuf& part: parts) { - if (part.empty() && !strict) { - continue; - } - TVector<TString> nvPair = StringSplitter(part).Split('=').Limit(2); - if (nvPair.size() != 2) { - if (strict) { - UdfTerminate((TStringBuilder() << Pos_ << "Bad query field: \"" - << nvPair[0] << "\"").c_str()); - } - if (keepBlankValues) { - nvPair.emplace_back(""); - } else { - continue; - } + TVector<TString> nvPair = StringSplitter(part).Split('=').Limit(2); + if (nvPair.size() != 2) { + if (strict) { + UdfTerminate((TStringBuilder() << Pos_ << "Bad query field: \"" + << nvPair[0] << "\"") + .c_str()); } - if (!nvPair[1].empty() || keepBlankValues) { - CGIUnescape(nvPair[0]); - CGIUnescape(nvPair[1]); - pairs.emplace_back(nvPair[0], nvPair[1]); + if (keepBlankValues) { + nvPair.emplace_back(""); + } else { + continue; } } - return pairs; + if (!nvPair[1].empty() || keepBlankValues) { + CGIUnescape(nvPair[0]); + CGIUnescape(nvPair[1]); + pairs.emplace_back(nvPair[0], nvPair[1]); + } } + return pairs; +} - bool TQueryStringToList::DeclareSignature(const TStringRef& name, - TType*, - IFunctionTypeInfoBuilder& builder, - bool typesOnly) { - if (Name() == name) { - MakeSignature(builder, GetListType(builder)); - if (!typesOnly) { - builder.Implementation(new TQueryStringToList(builder.GetSourcePosition())); - } - return true; +bool TQueryStringToList::DeclareSignature(const TStringRef& name, + TType*, + IFunctionTypeInfoBuilder& builder, + bool typesOnly) { + if (Name() == name) { + MakeSignature(builder, GetListType(builder)); + if (!typesOnly) { + builder.Implementation(new TQueryStringToList(builder.GetSourcePosition())); } - return false; + return true; } + return false; +} - TUnboxedValue TQueryStringToList::Run(const IValueBuilder* valueBuilder, - const TUnboxedValuePod* args) const { - const auto pairs = RunImpl(args); - std::vector<TUnboxedValue> ret; - for (const auto& nvPair : pairs) { - TUnboxedValue* pair = nullptr; - auto item = valueBuilder->NewArray(2U, pair); - pair[0] = valueBuilder->NewString(nvPair.first); - pair[1] = valueBuilder->NewString(nvPair.second); - ret.push_back(item); - } - return valueBuilder->NewList(ret.data(), ret.size()); +TUnboxedValue TQueryStringToList::Run(const IValueBuilder* valueBuilder, + const TUnboxedValuePod* args) const { + const auto pairs = RunImpl(args); + std::vector<TUnboxedValue> ret; + for (const auto& nvPair : pairs) { + TUnboxedValue* pair = nullptr; + auto item = valueBuilder->NewArray(2U, pair); + pair[0] = valueBuilder->NewString(nvPair.first); + pair[1] = valueBuilder->NewString(nvPair.second); + ret.push_back(item); } + return valueBuilder->NewList(ret.data(), ret.size()); +} - bool TQueryStringToDict::DeclareSignature(const TStringRef& name, - TType*, - IFunctionTypeInfoBuilder& builder, - bool typesOnly) { - if (Name() == name) { - auto dictType = GetDictType(builder); - MakeSignature(builder, dictType); - if (!typesOnly) { - builder.Implementation(new TQueryStringToDict(dictType, - builder.GetSourcePosition())); - } - return true; +bool TQueryStringToDict::DeclareSignature(const TStringRef& name, + TType*, + IFunctionTypeInfoBuilder& builder, + bool typesOnly) { + if (Name() == name) { + auto dictType = GetDictType(builder); + MakeSignature(builder, dictType); + if (!typesOnly) { + builder.Implementation(new TQueryStringToDict(dictType, + builder.GetSourcePosition())); } - return false; + return true; } + return false; +} - TUnboxedValue TQueryStringToDict::Run(const IValueBuilder* valueBuilder, - const TUnboxedValuePod* args) const { - const auto pairs = RunImpl(args); - auto ret = valueBuilder->NewDict(DictType_, TDictFlags::Hashed | TDictFlags::Multi); - for (const auto& nvPair : pairs) { - ret->Add(valueBuilder->NewString(nvPair.first), - valueBuilder->NewString(nvPair.second)); - } - return ret->Build(); +TUnboxedValue TQueryStringToDict::Run(const IValueBuilder* valueBuilder, + const TUnboxedValuePod* args) const { + const auto pairs = RunImpl(args); + auto ret = valueBuilder->NewDict(DictType_, TDictFlags::Hashed | TDictFlags::Multi); + for (const auto& nvPair : pairs) { + ret->Add(valueBuilder->NewString(nvPair.first), + valueBuilder->NewString(nvPair.second)); } + return ret->Build(); +} - TUnboxedValue TBuildQueryString::Run(const IValueBuilder* valueBuilder, - const TUnboxedValuePod* args) const { - const std::string_view sep(args[1] ? args[1].AsStringRef() : "&"); - TStringBuilder ret; +TUnboxedValue TBuildQueryString::Run(const IValueBuilder* valueBuilder, + const TUnboxedValuePod* args) const { + const std::string_view sep(args[1] ? args[1].AsStringRef() : "&"); + TStringBuilder ret; - switch(FirstArgTypeId_) { + switch (FirstArgTypeId_) { case EFirstArgTypeId::Dict: { TUnboxedValue key, value; const auto dictIt = args[0].GetDictIterator(); @@ -132,8 +135,9 @@ namespace NUrlUdf { const auto listIt = value.GetListIterator(); TUnboxedValue item; while (listIt.Next(item)) { - if (wasItem++) + if (wasItem++) { ret << sep; + } if (item) { ret << keyEscaped << '=' << CGIEscapeRet(item.AsStringRef()); } else { @@ -148,8 +152,9 @@ namespace NUrlUdf { const auto dictIt = args[0].GetDictIterator(); ui64 wasKey = 0; while (dictIt.NextPair(key, value)) { - if (wasKey++) + if (wasKey++) { ret << sep; + } if (value) { ret << CGIEscapeRet(key.AsStringRef()) << '=' << CGIEscapeRet(value.AsStringRef()); @@ -164,8 +169,9 @@ namespace NUrlUdf { TUnboxedValue item; const auto listIt = args[0].GetListIterator(); while (listIt.Next(item)) { - if (wasItem++) + if (wasItem++) { ret << sep; + } TUnboxedValue key = item.GetElement(0), val = item.GetElement(1); if (val) { ret << CGIEscapeRet(key.AsStringRef()) << '=' @@ -178,66 +184,66 @@ namespace NUrlUdf { } default: Y_ABORT("Current first parameter type is not yet implemented"); - } - return valueBuilder->NewString(ret); } + return valueBuilder->NewString(ret); +} - bool TBuildQueryString::DeclareSignature(const TStringRef& name, - TType* userType, - IFunctionTypeInfoBuilder& builder, - bool typesOnly) { - if (Name() == name) { - if (!userType) { - builder.SetError("Missing user type"); - return true; - } - builder.UserType(userType); - const auto typeHelper = builder.TypeInfoHelper(); - const auto userTypeInspector = TTupleTypeInspector(*typeHelper, userType); - if (!userTypeInspector || !userTypeInspector.GetElementsCount()) { - builder.SetError("User type is not tuple"); - return true; - } - const auto argsTypeInspector = TTupleTypeInspector(*typeHelper, - userTypeInspector.GetElementType(0)); - if (!argsTypeInspector || !argsTypeInspector.GetElementsCount()) { - builder.SetError("Please provide at least one argument"); - return true; - } - const auto firstArgType = argsTypeInspector.GetElementType(0); - EFirstArgTypeId firstArgTypeId = EFirstArgTypeId::None; +bool TBuildQueryString::DeclareSignature(const TStringRef& name, + TType* userType, + IFunctionTypeInfoBuilder& builder, + bool typesOnly) { + if (Name() == name) { + if (!userType) { + builder.SetError("Missing user type"); + return true; + } + builder.UserType(userType); + const auto typeHelper = builder.TypeInfoHelper(); + const auto userTypeInspector = TTupleTypeInspector(*typeHelper, userType); + if (!userTypeInspector || !userTypeInspector.GetElementsCount()) { + builder.SetError("User type is not tuple"); + return true; + } + const auto argsTypeInspector = TTupleTypeInspector(*typeHelper, + userTypeInspector.GetElementType(0)); + if (!argsTypeInspector || !argsTypeInspector.GetElementsCount()) { + builder.SetError("Please provide at least one argument"); + return true; + } + const auto firstArgType = argsTypeInspector.GetElementType(0); + EFirstArgTypeId firstArgTypeId = EFirstArgTypeId::None; - if (typeHelper->IsSameType(GetDictType(builder), firstArgType) || - typeHelper->IsSameType(GetDictType(builder, true), firstArgType)) { - firstArgTypeId = EFirstArgTypeId::Dict; - } else if (typeHelper->IsSameType(GetListType(builder), firstArgType) || - typeHelper->IsSameType(GetListType(builder, true), firstArgType) || - typeHelper->GetTypeKind(firstArgType) == ETypeKind::EmptyList) - { - firstArgTypeId = EFirstArgTypeId::List; - } else if (typeHelper->IsSameType(GetFlattenDictType(builder), firstArgType) || - typeHelper->IsSameType(GetFlattenDictType(builder, true), firstArgType) || - typeHelper->GetTypeKind(firstArgType) == ETypeKind::EmptyDict) - { - firstArgTypeId = EFirstArgTypeId::FlattenDict; - } - if (firstArgTypeId != EFirstArgTypeId::None) { - builder.Returns<TQueryStr>().OptionalArgs(1); - auto args = builder.Args(); - args->Add(firstArgType).Flags(ICallablePayload::TArgumentFlags::AutoMap); - args->Add<TSeparatorNArg>().Done(); - if (!typesOnly) { - builder.Implementation(new TBuildQueryString(builder.GetSourcePosition(), - firstArgTypeId)); - } - } else { - TStringBuilder sb; - sb << "Unsupported first argument type: "; - TTypePrinter(*typeHelper, firstArgType).Out(sb.Out); - builder.SetError(sb); + if (typeHelper->IsSameType(GetDictType(builder), firstArgType) || + typeHelper->IsSameType(GetDictType(builder, true), firstArgType)) { + firstArgTypeId = EFirstArgTypeId::Dict; + } else if (typeHelper->IsSameType(GetListType(builder), firstArgType) || + typeHelper->IsSameType(GetListType(builder, true), firstArgType) || + typeHelper->GetTypeKind(firstArgType) == ETypeKind::EmptyList) + { + firstArgTypeId = EFirstArgTypeId::List; + } else if (typeHelper->IsSameType(GetFlattenDictType(builder), firstArgType) || + typeHelper->IsSameType(GetFlattenDictType(builder, true), firstArgType) || + typeHelper->GetTypeKind(firstArgType) == ETypeKind::EmptyDict) + { + firstArgTypeId = EFirstArgTypeId::FlattenDict; + } + if (firstArgTypeId != EFirstArgTypeId::None) { + builder.Returns<TQueryStr>().OptionalArgs(1); + auto args = builder.Args(); + args->Add(firstArgType).Flags(ICallablePayload::TArgumentFlags::AutoMap); + args->Add<TSeparatorNArg>().Done(); + if (!typesOnly) { + builder.Implementation(new TBuildQueryString(builder.GetSourcePosition(), + firstArgTypeId)); } - return true; + } else { + TStringBuilder sb; + sb << "Unsupported first argument type: "; + TTypePrinter(*typeHelper, firstArgType).Out(sb.Out); + builder.SetError(sb); } - return false; + return true; } + return false; } +} // namespace NUrlUdf diff --git a/yql/essentials/udfs/common/url_base/lib/url_query.h b/yql/essentials/udfs/common/url_base/lib/url_query.h index 552b8527823..7ba82241896 100644 --- a/yql/essentials/udfs/common/url_base/lib/url_query.h +++ b/yql/essentials/udfs/common/url_base/lib/url_query.h @@ -3,132 +3,136 @@ #include <yql/essentials/public/udf/udf_helpers.h> namespace NUrlUdf { - using namespace NYql::NUdf; - - struct TQueryStringConv : public TBoxedValue { - protected: - static constexpr char Separator[] = "Separator"; - - using TQueryStr = char*; - using TSeparatorNArg = TNamedArg<TQueryStr, Separator>; - - static inline TType* GetListType(const IFunctionTypeInfoBuilder& builder, - bool optional = false) - { - auto tupleType = optional ? - builder.Tuple()->Add<TQueryStr>().Add(builder.Optional()->Item<TQueryStr>().Build()).Build() - : builder.Tuple()->Add<TQueryStr>().Add<TQueryStr>().Build(); - return builder.List()->Item(tupleType).Build(); - } - - static inline TType* GetDictType(const IFunctionTypeInfoBuilder& builder, - bool optional = false) - { - auto listType = optional ? - builder.List()->Item(builder.Optional()->Item<TQueryStr>().Build()).Build() - : builder.List()->Item<TQueryStr>().Build(); - return builder.Dict()->Key<TQueryStr>().Value(listType).Build(); - } - - static inline TType* GetFlattenDictType(const IFunctionTypeInfoBuilder& builder, - bool optional = false) - { - return optional ? - builder.Dict()->Key<TQueryStr>().Value(builder.Optional()->Item<TQueryStr>().Build()).Build() - : builder.Dict()->Key<TQueryStr>().Value<TQueryStr>().Build(); - } - }; - - struct TQueryStringParse: public TQueryStringConv { - explicit TQueryStringParse(TSourcePosition&& pos) : Pos_(std::move(pos)) {} - - protected: - static constexpr char KeepBlankValues[] = "KeepBlankValues"; - static constexpr char Strict[] = "Strict"; - static constexpr char MaxFields[] = "MaxFields"; - - using TKeepBlankValuesNArg = TNamedArg<bool, KeepBlankValues>; - using TStrictNArg = TNamedArg<bool, Strict>; - using TMaxFieldsNArg = TNamedArg<ui32, MaxFields>; - - static void MakeSignature(IFunctionTypeInfoBuilder& builder, const TType* retType); - - std::vector<std::pair<TString, TString>> - RunImpl(const TUnboxedValuePod* args) const; - - private: - TSourcePosition Pos_; - }; - - struct TQueryStringToList : public TQueryStringParse { - explicit TQueryStringToList(TSourcePosition&& pos) - : TQueryStringParse(std::forward<TSourcePosition>(pos)) {} - - static const TStringRef& Name() { - static const auto name = TStringRef::Of("QueryStringToList"); - return name; - } - - static bool DeclareSignature(const TStringRef& name, - TType*, - IFunctionTypeInfoBuilder& builder, - bool typesOnly); - - TUnboxedValue Run(const IValueBuilder* valueBuilder, - const TUnboxedValuePod* args) const override; - }; - - struct TQueryStringToDict : public TQueryStringParse { - explicit TQueryStringToDict(TType* dictType, TSourcePosition&& pos) - : TQueryStringParse(std::move(pos)) - , DictType_(dictType) - {} - - static const TStringRef& Name() { - static const auto name = TStringRef::Of("QueryStringToDict"); - return name; - } - - static bool DeclareSignature(const TStringRef& name, - TType*, - IFunctionTypeInfoBuilder& builder, - bool typesOnly); - - TUnboxedValue Run(const IValueBuilder* valueBuilder, - const TUnboxedValuePod* args) const override; - - private: - TType* DictType_; - }; - - class TBuildQueryString : public TQueryStringConv { - TSourcePosition Pos_; - enum class EFirstArgTypeId { - None, - Dict, - FlattenDict, - List, - } FirstArgTypeId_; - - public: - typedef bool TTypeAwareMarker; - - explicit TBuildQueryString(TSourcePosition&& pos, EFirstArgTypeId firstArgTypeId) - : Pos_(std::move(pos)) - , FirstArgTypeId_(firstArgTypeId) - {} - - static const TStringRef& Name() { - static const auto name = TStringRef::Of("BuildQueryString"); - return name; - } - - TUnboxedValue Run(const IValueBuilder* valueBuilder, - const TUnboxedValuePod* args) const override; - - static bool DeclareSignature(const TStringRef& name, - TType* userType, - IFunctionTypeInfoBuilder& builder, - bool typesOnly); - }; -} +using namespace NYql::NUdf; + +struct TQueryStringConv: public TBoxedValue { +protected: + static constexpr char Separator[] = "Separator"; + + using TQueryStr = char*; + using TSeparatorNArg = TNamedArg<TQueryStr, Separator>; + + static inline TType* GetListType(const IFunctionTypeInfoBuilder& builder, + bool optional = false) + { + auto tupleType = optional ? builder.Tuple()->Add<TQueryStr>().Add(builder.Optional()->Item<TQueryStr>().Build()).Build() + : builder.Tuple()->Add<TQueryStr>().Add<TQueryStr>().Build(); + return builder.List()->Item(tupleType).Build(); + } + + static inline TType* GetDictType(const IFunctionTypeInfoBuilder& builder, + bool optional = false) + { + auto listType = optional ? builder.List()->Item(builder.Optional()->Item<TQueryStr>().Build()).Build() + : builder.List()->Item<TQueryStr>().Build(); + return builder.Dict()->Key<TQueryStr>().Value(listType).Build(); + } + + static inline TType* GetFlattenDictType(const IFunctionTypeInfoBuilder& builder, + bool optional = false) + { + return optional ? builder.Dict()->Key<TQueryStr>().Value(builder.Optional()->Item<TQueryStr>().Build()).Build() + : builder.Dict()->Key<TQueryStr>().Value<TQueryStr>().Build(); + } +}; + +struct TQueryStringParse: public TQueryStringConv { + explicit TQueryStringParse(TSourcePosition&& pos) + : Pos_(std::move(pos)) + { + } + +protected: + static constexpr char KeepBlankValues[] = "KeepBlankValues"; + static constexpr char Strict[] = "Strict"; + static constexpr char MaxFields[] = "MaxFields"; + + using TKeepBlankValuesNArg = TNamedArg<bool, KeepBlankValues>; + using TStrictNArg = TNamedArg<bool, Strict>; + using TMaxFieldsNArg = TNamedArg<ui32, MaxFields>; + + static void MakeSignature(IFunctionTypeInfoBuilder& builder, const TType* retType); + + std::vector<std::pair<TString, TString>> + RunImpl(const TUnboxedValuePod* args) const; + +private: + TSourcePosition Pos_; +}; + +struct TQueryStringToList: public TQueryStringParse { + explicit TQueryStringToList(TSourcePosition&& pos) + : TQueryStringParse(std::forward<TSourcePosition>(pos)) + { + } + + static const TStringRef& Name() { + static const auto name = TStringRef::Of("QueryStringToList"); + return name; + } + + static bool DeclareSignature(const TStringRef& name, + TType*, + IFunctionTypeInfoBuilder& builder, + bool typesOnly); + + TUnboxedValue Run(const IValueBuilder* valueBuilder, + const TUnboxedValuePod* args) const override; +}; + +struct TQueryStringToDict: public TQueryStringParse { + explicit TQueryStringToDict(TType* dictType, TSourcePosition&& pos) + : TQueryStringParse(std::move(pos)) + , DictType_(dictType) + { + } + + static const TStringRef& Name() { + static const auto name = TStringRef::Of("QueryStringToDict"); + return name; + } + + static bool DeclareSignature(const TStringRef& name, + TType*, + IFunctionTypeInfoBuilder& builder, + bool typesOnly); + + TUnboxedValue Run(const IValueBuilder* valueBuilder, + const TUnboxedValuePod* args) const override; + +private: + TType* DictType_; +}; + +class TBuildQueryString: public TQueryStringConv { + TSourcePosition Pos_; + enum class EFirstArgTypeId { + None, + Dict, + FlattenDict, + List, + } FirstArgTypeId_; + +public: + typedef bool TTypeAwareMarker; + + explicit TBuildQueryString(TSourcePosition&& pos, EFirstArgTypeId firstArgTypeId) + : Pos_(std::move(pos)) + , FirstArgTypeId_(firstArgTypeId) + { + } + + static const TStringRef& Name() { + static const auto name = TStringRef::Of("BuildQueryString"); + return name; + } + + TUnboxedValue Run(const IValueBuilder* valueBuilder, + const TUnboxedValuePod* args) const override; + + static bool DeclareSignature(const TStringRef& name, + TType* userType, + IFunctionTypeInfoBuilder& builder, + bool typesOnly); +}; +} // namespace NUrlUdf diff --git a/yql/essentials/udfs/common/url_base/lib/ya.make b/yql/essentials/udfs/common/url_base/lib/ya.make index 9887842303b..51a55865bd4 100644 --- a/yql/essentials/udfs/common/url_base/lib/ya.make +++ b/yql/essentials/udfs/common/url_base/lib/ya.make @@ -6,6 +6,8 @@ YQL_ABI_VERSION( 0 ) +ENABLE(YQL_STYLE_CPP) + SRCS( url_base_udf.cpp url_parse.cpp |