summaryrefslogtreecommitdiffstats
path: root/yql/essentials/udfs/common/url_base/lib
diff options
context:
space:
mode:
authorvvvv <[email protected]>2025-10-06 13:26:25 +0300
committervvvv <[email protected]>2025-10-06 14:06:25 +0300
commiteca8ce9cb1613d5c983185c4e43c20651a9638aa (patch)
tree61ee5ae779948e61af9a7691d19eaa2c09869121 /yql/essentials/udfs/common/url_base/lib
parent4adf7eecae16a9b228b28cc5f64c27ef69ad5ec2 (diff)
YQL-20086 udfs
init commit_hash:f9684778bf1ea956965f2360b80b91edb7d4ffbe
Diffstat (limited to 'yql/essentials/udfs/common/url_base/lib')
-rw-r--r--yql/essentials/udfs/common/url_base/lib/url_base_udf.cpp2
-rw-r--r--yql/essentials/udfs/common/url_base/lib/url_base_udf.h174
-rw-r--r--yql/essentials/udfs/common/url_base/lib/url_parse.cpp76
-rw-r--r--yql/essentials/udfs/common/url_base/lib/url_parse.h82
-rw-r--r--yql/essentials/udfs/common/url_base/lib/url_query.cpp316
-rw-r--r--yql/essentials/udfs/common/url_base/lib/url_query.h262
-rw-r--r--yql/essentials/udfs/common/url_base/lib/ya.make2
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