aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkniv <kniv@yandex-team.ru>2022-02-14 17:26:38 +0300
committerkniv <kniv@yandex-team.ru>2022-02-14 17:26:38 +0300
commit44db08c3bf5673e13660f0443ed489eb1763b021 (patch)
treefa2858179234e2acb2c61048ad6d0a26540993b5
parent5fbb62b4ad7d4fe17d10658f398488d4aa4eba23 (diff)
downloadydb-44db08c3bf5673e13660f0443ed489eb1763b021.tar.gz
YQL-14385: BuildQueryString(): Allow optional values and empty list/dict, enable type awareness
YQL-14385: BuildQueryString(): Allow optional values and empty list/dict, enable type awareness ref:ef10b2c257809eb3e4974869e7f740669602eca6
-rw-r--r--ydb/library/yql/udfs/common/url_base/lib/url_query.cpp37
-rw-r--r--ydb/library/yql/udfs/common/url_base/lib/url_query.h28
2 files changed, 51 insertions, 14 deletions
diff --git a/ydb/library/yql/udfs/common/url_base/lib/url_query.cpp b/ydb/library/yql/udfs/common/url_base/lib/url_query.cpp
index 188f0b0ae5..6bbe3b8969 100644
--- a/ydb/library/yql/udfs/common/url_base/lib/url_query.cpp
+++ b/ydb/library/yql/udfs/common/url_base/lib/url_query.cpp
@@ -7,7 +7,9 @@
#include <library/cpp/string_utils/quote/quote.h>
namespace NUrlUdf {
- void TQueryStringParse::MakeSignature(IFunctionTypeInfoBuilder& builder, TType* retType) {
+ void TQueryStringParse::MakeSignature(IFunctionTypeInfoBuilder& builder,
+ const TType* retType)
+ {
builder.Returns(retType).OptionalArgs(4);
auto args = builder.Args();
args->Add<TAutoMap<TQueryStr>>();
@@ -132,7 +134,11 @@ namespace NUrlUdf {
while (listIt.Next(item)) {
if (wasItem++)
ret << sep;
- ret << keyEscaped << '=' << CGIEscapeRet(item.AsStringRef());
+ if (item) {
+ ret << keyEscaped << '=' << CGIEscapeRet(item.AsStringRef());
+ } else {
+ ret << keyEscaped << '=';
+ }
}
}
break;
@@ -144,7 +150,12 @@ namespace NUrlUdf {
while (dictIt.NextPair(key, value)) {
if (wasKey++)
ret << sep;
- ret << CGIEscapeRet(key.AsStringRef()) << '=' << CGIEscapeRet(value.AsStringRef());
+ if (value) {
+ ret << CGIEscapeRet(key.AsStringRef()) << '='
+ << CGIEscapeRet(value.AsStringRef());
+ } else {
+ ret << CGIEscapeRet(key.AsStringRef()) << '=';
+ }
}
break;
}
@@ -156,7 +167,12 @@ namespace NUrlUdf {
if (wasItem++)
ret << sep;
TUnboxedValue key = item.GetElement(0), val = item.GetElement(1);
- ret << CGIEscapeRet(key.AsStringRef()) << '=' << CGIEscapeRet(val.AsStringRef());
+ if (val) {
+ ret << CGIEscapeRet(key.AsStringRef()) << '='
+ << CGIEscapeRet(val.AsStringRef());
+ } else {
+ ret << CGIEscapeRet(key.AsStringRef()) << '=';
+ }
}
break;
}
@@ -191,11 +207,18 @@ namespace NUrlUdf {
const auto firstArgType = argsTypeInspector.GetElementType(0);
EFirstArgTypeId firstArgTypeId = EFirstArgTypeId::None;
- if (typeHelper->IsSameType(GetDictType(builder), firstArgType)) {
+ if (typeHelper->IsSameType(GetDictType(builder), firstArgType) ||
+ typeHelper->IsSameType(GetDictType(builder, true), firstArgType)) {
firstArgTypeId = EFirstArgTypeId::Dict;
- } else if (typeHelper->IsSameType(GetListType(builder), firstArgType)) {
+ } 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)) {
+ } 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) {
diff --git a/ydb/library/yql/udfs/common/url_base/lib/url_query.h b/ydb/library/yql/udfs/common/url_base/lib/url_query.h
index fe64ca7db8..057615e65a 100644
--- a/ydb/library/yql/udfs/common/url_base/lib/url_query.h
+++ b/ydb/library/yql/udfs/common/url_base/lib/url_query.h
@@ -12,18 +12,30 @@ namespace NUrlUdf {
using TQueryStr = char*;
using TSeparatorNArg = TNamedArg<TQueryStr, Separator>;
- static inline TType* GetListType(const IFunctionTypeInfoBuilder& builder) {
- auto tupleType = builder.Tuple()->Add<TQueryStr>().Add<TQueryStr>().Build();
+ 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) {
- auto listType = builder.List()->Item<TQueryStr>().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) {
- return builder.Dict()->Key<TQueryStr>().Value<TQueryStr>().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();
}
};
@@ -39,7 +51,7 @@ namespace NUrlUdf {
using TStrictNArg = TNamedArg<bool, Strict>;
using TMaxFieldsNArg = TNamedArg<ui32, MaxFields>;
- static void MakeSignature(IFunctionTypeInfoBuilder& builder, TType* retType);
+ static void MakeSignature(IFunctionTypeInfoBuilder& builder, const TType* retType);
std::vector<std::pair<TString, TString>>
RunImpl(const TUnboxedValuePod* args) const;
@@ -99,6 +111,8 @@ namespace NUrlUdf {
} FirstArgTypeId_;
public:
+ typedef bool TTypeAwareMarker;
+
explicit TBuildQueryString(TSourcePosition&& pos, EFirstArgTypeId firstArgTypeId)
: Pos_(std::move(pos))
, FirstArgTypeId_(firstArgTypeId)