diff options
author | kniv <kniv@yandex-team.ru> | 2022-02-14 17:26:38 +0300 |
---|---|---|
committer | kniv <kniv@yandex-team.ru> | 2022-02-14 17:26:38 +0300 |
commit | 44db08c3bf5673e13660f0443ed489eb1763b021 (patch) | |
tree | fa2858179234e2acb2c61048ad6d0a26540993b5 | |
parent | 5fbb62b4ad7d4fe17d10658f398488d4aa4eba23 (diff) | |
download | ydb-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.cpp | 37 | ||||
-rw-r--r-- | ydb/library/yql/udfs/common/url_base/lib/url_query.h | 28 |
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) |