diff options
| author | vvvv <[email protected]> | 2025-09-18 12:35:25 +0300 |
|---|---|---|
| committer | vvvv <[email protected]> | 2025-09-18 12:48:14 +0300 |
| commit | f5a6d6cdfb9d7c44659f134a53c2fa273ec85599 (patch) | |
| tree | 5cc206b17db5fa8f976ea922c997095a1d133687 | |
| parent | e2dc5e15bc02bff63e44ed9c74ff1093d87d845b (diff) | |
YQL-20339 expr types & reflection
init
commit_hash:1c72053b3785a26cfde418f28a9d054b5a624627
29 files changed, 685 insertions, 83 deletions
diff --git a/yql/essentials/ast/yql_expr.cpp b/yql/essentials/ast/yql_expr.cpp index 25a888be53f..1ecb5191e77 100644 --- a/yql/essentials/ast/yql_expr.cpp +++ b/yql/essentials/ast/yql_expr.cpp @@ -606,6 +606,28 @@ namespace { return nullptr; return Expr.MakeType<TScalarExprType>(r); + } else if (content == TStringBuf("Linear")) { + if (node.GetChildrenCount() != 2) { + AddError(node, "Bad linear type annotation"); + return nullptr; + } + + auto r = CompileTypeAnnotationNode(*node.GetChild(1)); + if (!r) + return nullptr; + + return Expr.MakeType<TLinearExprType>(r); + } else if (content == TStringBuf("DynamicLinear")) { + if (node.GetChildrenCount() != 2) { + AddError(node, "Bad dynamic linear type annotation"); + return nullptr; + } + + auto r = CompileTypeAnnotationNode(*node.GetChild(1)); + if (!r) + return nullptr; + + return Expr.MakeType<TDynamicLinearExprType>(r); } else { AddError(node, TStringBuilder() << "Unknown type annotation"); return nullptr; @@ -870,6 +892,22 @@ namespace { return TAstNode::NewList(TPosition(), pool, self, itemType); } + case ETypeAnnotationKind::Linear: + { + auto type = annotation.Cast<TLinearExprType>(); + auto self = TAstNode::NewLiteralAtom(TPosition(), TStringBuf("Linear"), pool); + auto itemType = ConvertTypeAnnotationToAst(*type->GetItemType(), pool, refAtoms); + return TAstNode::NewList(TPosition(), pool, self, itemType); + } + + case ETypeAnnotationKind::DynamicLinear: + { + auto type = annotation.Cast<TDynamicLinearExprType>(); + auto self = TAstNode::NewLiteralAtom(TPosition(), TStringBuf("DynamicLinear"), pool); + auto itemType = ConvertTypeAnnotationToAst(*type->GetItemType(), pool, refAtoms); + return TAstNode::NewList(TPosition(), pool, self, itemType); + } + case ETypeAnnotationKind::LastType: YQL_ENSURE(false, "Unknown kind: " << annotation.GetKind()); @@ -3610,6 +3648,24 @@ const TScalarExprType* TMakeTypeImpl<TScalarExprType>::Make(TExprContext& ctx, c return AddType<TScalarExprType>(ctx, hash, itemType); } +const TLinearExprType* TMakeTypeImpl<TLinearExprType>::Make(TExprContext& ctx, const TTypeAnnotationNode* itemType) { + const auto hash = TLinearExprType::MakeHash(itemType); + TLinearExprType sample(hash, itemType); + if (const auto found = FindType(sample, ctx)) + return found; + + return AddType<TLinearExprType>(ctx, hash, itemType); +} + +const TDynamicLinearExprType* TMakeTypeImpl<TDynamicLinearExprType>::Make(TExprContext& ctx, const TTypeAnnotationNode* itemType) { + const auto hash = TDynamicLinearExprType::MakeHash(itemType); + TDynamicLinearExprType sample(hash, itemType); + if (const auto found = FindType(sample, ctx)) + return found; + + return AddType<TDynamicLinearExprType>(ctx, hash, itemType); +} + bool CompareExprTrees(const TExprNode*& one, const TExprNode*& two) { TArgumentsMap map; ui32 level = 0; @@ -3892,6 +3948,14 @@ void TDefaultTypeAnnotationVisitor::Visit(const TScalarExprType& type) { type.GetItemType()->Accept(*this); } +void TDefaultTypeAnnotationVisitor::Visit(const TLinearExprType& type) { + type.GetItemType()->Accept(*this); +} + +void TDefaultTypeAnnotationVisitor::Visit(const TDynamicLinearExprType& type) { + type.GetItemType()->Accept(*this); +} + TErrorTypeVisitor::TErrorTypeVisitor(TExprContext& ctx) : Ctx_(ctx) {} diff --git a/yql/essentials/ast/yql_expr.h b/yql/essentials/ast/yql_expr.h index 936de9bcdbb..2441717ea85 100644 --- a/yql/essentials/ast/yql_expr.h +++ b/yql/essentials/ast/yql_expr.h @@ -85,6 +85,8 @@ class TEmptyListExprType; class TEmptyDictExprType; class TBlockExprType; class TScalarExprType; +class TLinearExprType; +class TDynamicLinearExprType; const size_t DefaultMistypeDistance = 3; const TString YqlVirtualPrefix = "_yql_virtual_"; @@ -120,6 +122,8 @@ struct TTypeAnnotationVisitor { virtual void Visit(const TEmptyDictExprType& type) = 0; virtual void Visit(const TBlockExprType& type) = 0; virtual void Visit(const TScalarExprType& type) = 0; + virtual void Visit(const TLinearExprType& type) = 0; + virtual void Visit(const TDynamicLinearExprType& type) = 0; }; struct TDefaultTypeAnnotationVisitor : public TTypeAnnotationVisitor { @@ -149,6 +153,8 @@ struct TDefaultTypeAnnotationVisitor : public TTypeAnnotationVisitor { void Visit(const TEmptyDictExprType& type) override; void Visit(const TBlockExprType& type) override; void Visit(const TScalarExprType& type) override; + void Visit(const TLinearExprType& type) override; + void Visit(const TDynamicLinearExprType& type) override; }; class TErrorTypeVisitor : public TDefaultTypeAnnotationVisitor @@ -180,9 +186,10 @@ enum ETypeAnnotationFlags : ui32 { TypeHasDynamicSize = 0x2000, TypeNonComparableInternal = 0x4000, TypeHasError = 0x8000, + TypeHasStaticLinear = 0x10000, }; -const ui64 TypeHashMagic = 0x10000; +const ui64 TypeHashMagic = 0x1000000; inline ui64 StreamHash(const void* buffer, size_t size, ui64 seed) { return MurmurHash(buffer, size, seed); @@ -821,6 +828,60 @@ private: const TTypeAnnotationNode* ItemType_; }; +class TLinearExprType : public TTypeAnnotationNode { +public: + static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Linear; + + TLinearExprType(ui64 hash, const TTypeAnnotationNode* itemType) + : TTypeAnnotationNode(KindValue, itemType->GetFlags() | TypeHasStaticLinear | TypeNonPersistable, hash, itemType->GetUsedPgExtensions()) + , ItemType_(itemType) + { + } + + static ui64 MakeHash(const TTypeAnnotationNode* itemType) { + ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Linear; + return StreamHash(itemType->GetHash(), hash); + } + + const TTypeAnnotationNode* GetItemType() const { + return ItemType_; + } + + bool operator==(const TLinearExprType& other) const { + return GetItemType() == other.GetItemType(); + } + +private: + const TTypeAnnotationNode* ItemType_; +}; + +class TDynamicLinearExprType : public TTypeAnnotationNode { +public: + static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::DynamicLinear; + + TDynamicLinearExprType(ui64 hash, const TTypeAnnotationNode* itemType) + : TTypeAnnotationNode(KindValue, itemType->GetFlags() | TypeNonPersistable, hash, itemType->GetUsedPgExtensions()) + , ItemType_(itemType) + { + } + + static ui64 MakeHash(const TTypeAnnotationNode* itemType) { + ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::DynamicLinear; + return StreamHash(itemType->GetHash(), hash); + } + + const TTypeAnnotationNode* GetItemType() const { + return ItemType_; + } + + bool operator==(const TDynamicLinearExprType& other) const { + return GetItemType() == other.GetItemType(); + } + +private: + const TTypeAnnotationNode* ItemType_; +}; + class TDataExprType : public TTypeAnnotationNode { public: static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Data; @@ -1525,6 +1586,12 @@ inline bool TTypeAnnotationNode::Equals(const TTypeAnnotationNode& node) const { case ETypeAnnotationKind::Scalar: return static_cast<const TScalarExprType&>(*this) == static_cast<const TScalarExprType&>(node); + case ETypeAnnotationKind::Linear: + return static_cast<const TLinearExprType&>(*this) == static_cast<const TLinearExprType&>(node); + + case ETypeAnnotationKind::DynamicLinear: + return static_cast<const TDynamicLinearExprType&>(*this) == static_cast<const TDynamicLinearExprType&>(node); + case ETypeAnnotationKind::LastType: YQL_ENSURE(false, "Incorrect type"); @@ -1586,6 +1653,10 @@ inline void TTypeAnnotationNode::Accept(TTypeAnnotationVisitor& visitor) const { return visitor.Visit(static_cast<const TBlockExprType&>(*this)); case ETypeAnnotationKind::Scalar: return visitor.Visit(static_cast<const TScalarExprType&>(*this)); + case ETypeAnnotationKind::Linear: + return visitor.Visit(static_cast<const TLinearExprType&>(*this)); + case ETypeAnnotationKind::DynamicLinear: + return visitor.Visit(static_cast<const TDynamicLinearExprType&>(*this)); case ETypeAnnotationKind::LastType: YQL_ENSURE(false, "Incorrect type"); } @@ -2616,6 +2687,16 @@ struct TMakeTypeImpl<TScalarExprType> { static const TScalarExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType); }; +template <> +struct TMakeTypeImpl<TLinearExprType> { + static const TLinearExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType); +}; + +template <> +struct TMakeTypeImpl<TDynamicLinearExprType> { + static const TDynamicLinearExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType); +}; + using TSingletonTypeCache = std::tuple< const TVoidExprType*, const TNullExprType*, diff --git a/yql/essentials/ast/yql_expr_types.h b/yql/essentials/ast/yql_expr_types.h index bb628af2725..1a262f7147d 100644 --- a/yql/essentials/ast/yql_expr_types.h +++ b/yql/essentials/ast/yql_expr_types.h @@ -30,7 +30,9 @@ namespace NYql { xx(Multi, 23) \ xx(Pg, 24) \ xx(Block, 25) \ - xx(Scalar, 26) + xx(Scalar, 26) \ + xx(Linear, 27) \ + xx(DynamicLinear, 28) enum class ETypeAnnotationKind : ui64 { YQL_TYPE_ANN_KIND_MAP(ENUM_VALUE_GEN) diff --git a/yql/essentials/ast/yql_type_string.cpp b/yql/essentials/ast/yql_type_string.cpp index cfb144ce62c..12004051644 100644 --- a/yql/essentials/ast/yql_type_string.cpp +++ b/yql/essentials/ast/yql_type_string.cpp @@ -93,6 +93,8 @@ enum EToken TOKEN_TZTIMESTAMP64 = -58, TOKEN_MULTI = -59, TOKEN_ERROR = -60, + TOKEN_LINEAR = -61, + TOKEN_DYNAMICLINEAR = -62, // identifiers TOKEN_IDENTIFIER = -100, @@ -166,6 +168,8 @@ EToken TokenTypeFromStr(TStringBuf str) { TStringBuf("TzDatetime64"), TOKEN_TZDATETIME64}, { TStringBuf("TzTimestamp64"), TOKEN_TZTIMESTAMP64 }, { TStringBuf("Error"), TOKEN_ERROR}, + { TStringBuf("Linear"), TOKEN_LINEAR}, + { TStringBuf("DynamicLinear"), TOKEN_DYNAMICLINEAR}, }; auto it = map.find(str); @@ -349,6 +353,14 @@ private: type = ParseErrorType(); break; + case TOKEN_LINEAR: + type = ParseLinearType(false); + break; + + case TOKEN_DYNAMICLINEAR: + type = ParseLinearType(true); + break; + default: if (Identifier_.empty()) { return AddError("Expected type"); @@ -754,6 +766,17 @@ private: return MakeErrorType(file, line, column, message); } + TAstNode* ParseLinearType(bool isDynamic) { + GetNextToken(); // eat keyword + EXPECT_AND_SKIP_TOKEN('<', nullptr); + + auto itemType = ParseType(); + if (!itemType) return nullptr; + + EXPECT_AND_SKIP_TOKEN('>', nullptr); + return MakeLinearType(itemType, isDynamic); + } + TAstNode* ParseDecimalType() { GetNextToken(); // eat keyword EXPECT_AND_SKIP_TOKEN('(', nullptr); @@ -1213,6 +1236,16 @@ private: return MakeList(items, Y_ARRAY_SIZE(items)); } + TAstNode* MakeLinearType(TAstNode* type, bool isDynamic) { + TAstNode* items[] = { + MakeLiteralAtom(isDynamic ? + TStringBuf("DynamicLinearType") : + TStringBuf("LinearType")), + type, + }; + return MakeList(items, Y_ARRAY_SIZE(items)); + } + TAstNode* MakeAtom(TStringBuf content, ui32 flags = TNodeFlags::Default) { return TAstNode::NewAtom(Position_, content, Pool_, flags); } @@ -1376,6 +1409,20 @@ private: Out_ << '>'; } + void Visit(const TLinearExprType& type) final { + TopLevel_ = false; + Out_ << TStringBuf("Linear<"); + type.GetItemType()->Accept(*this); + Out_ << '>'; + } + + void Visit(const TDynamicLinearExprType& type) final { + TopLevel_ = false; + Out_ << TStringBuf("DynamicLinear<"); + type.GetItemType()->Accept(*this); + Out_ << '>'; + } + void Visit(const TDataExprType& type) final { TopLevel_ = false; Out_ << type.GetName(); diff --git a/yql/essentials/core/type_ann/type_ann_core.cpp b/yql/essentials/core/type_ann/type_ann_core.cpp index b28daa84271..4d90448f452 100644 --- a/yql/essentials/core/type_ann/type_ann_core.cpp +++ b/yql/essentials/core/type_ann/type_ann_core.cpp @@ -211,6 +211,8 @@ namespace NTypeAnnImpl { case ETypeAnnotationKind::Pg: case ETypeAnnotationKind::Block: case ETypeAnnotationKind::Scalar: + case ETypeAnnotationKind::Linear: + case ETypeAnnotationKind::DynamicLinear: return { input, type }; case ETypeAnnotationKind::Optional: { @@ -12898,25 +12900,27 @@ template <NKikimr::NUdf::EDataSlot DataSlot> Functions["Zip"] = &ZipWrapper; Functions["ZipAll"] = &ZipAllWrapper; ExtFunctions["Enumerate"] = &EnumerateWrapper; - Functions["GenericType"] = &TypeWrapper<ETypeAnnotationKind::Generic>; - Functions["ResourceType"] = &TypeWrapper<ETypeAnnotationKind::Resource>; - Functions["ErrorType"] = &TypeWrapper<ETypeAnnotationKind::Error>; - Functions["DataType"] = &TypeWrapper<ETypeAnnotationKind::Data>; - Functions["ListType"] = &TypeWrapper<ETypeAnnotationKind::List>; - Functions["TupleType"] = &TypeWrapper<ETypeAnnotationKind::Tuple>; - Functions["MultiType"] = &TypeWrapper<ETypeAnnotationKind::Multi>; - Functions["StructType"] = &TypeWrapper<ETypeAnnotationKind::Struct>; - Functions["OptionalType"] = &TypeWrapper<ETypeAnnotationKind::Optional>; - Functions["TaggedType"] = &TypeWrapper<ETypeAnnotationKind::Tagged>; - Functions["VariantType"] = &TypeWrapper<ETypeAnnotationKind::Variant>; - Functions["StreamType"] = &TypeWrapper<ETypeAnnotationKind::Stream>; - Functions["FlowType"] = &TypeWrapper<ETypeAnnotationKind::Flow>; - Functions["BlockType"] = &TypeWrapper<ETypeAnnotationKind::Block>; - Functions["ScalarType"] = &TypeWrapper<ETypeAnnotationKind::Scalar>; + ExtFunctions["GenericType"] = &TypeWrapper<ETypeAnnotationKind::Generic>; + ExtFunctions["ResourceType"] = &TypeWrapper<ETypeAnnotationKind::Resource>; + ExtFunctions["ErrorType"] = &TypeWrapper<ETypeAnnotationKind::Error>; + ExtFunctions["DataType"] = &TypeWrapper<ETypeAnnotationKind::Data>; + ExtFunctions["ListType"] = &TypeWrapper<ETypeAnnotationKind::List>; + ExtFunctions["TupleType"] = &TypeWrapper<ETypeAnnotationKind::Tuple>; + ExtFunctions["MultiType"] = &TypeWrapper<ETypeAnnotationKind::Multi>; + ExtFunctions["StructType"] = &TypeWrapper<ETypeAnnotationKind::Struct>; + ExtFunctions["OptionalType"] = &TypeWrapper<ETypeAnnotationKind::Optional>; + ExtFunctions["TaggedType"] = &TypeWrapper<ETypeAnnotationKind::Tagged>; + ExtFunctions["VariantType"] = &TypeWrapper<ETypeAnnotationKind::Variant>; + ExtFunctions["StreamType"] = &TypeWrapper<ETypeAnnotationKind::Stream>; + ExtFunctions["FlowType"] = &TypeWrapper<ETypeAnnotationKind::Flow>; + ExtFunctions["BlockType"] = &TypeWrapper<ETypeAnnotationKind::Block>; + ExtFunctions["ScalarType"] = &TypeWrapper<ETypeAnnotationKind::Scalar>; + ExtFunctions["LinearType"] = &TypeWrapper<ETypeAnnotationKind::Linear>; + ExtFunctions["DynamicLinearType"] = &TypeWrapper<ETypeAnnotationKind::DynamicLinear>; Functions["Nothing"] = &NothingWrapper; Functions["AsOptionalType"] = &AsOptionalTypeWrapper; Functions["List"] = &ListWrapper; - Functions["DictType"] = &TypeWrapper<ETypeAnnotationKind::Dict>; + ExtFunctions["DictType"] = &TypeWrapper<ETypeAnnotationKind::Dict>; Functions["Dict"] = &DictWrapper; ExtFunctions["Variant"] = &VariantWrapper; Functions["Enum"] = &EnumWrapper; @@ -12978,11 +12982,11 @@ template <NKikimr::NUdf::EDataSlot DataSlot> Functions["EmptyList"] = &EmptyListWrapper; Functions["EmptyDict"] = &EmptyDictWrapper; Functions["Error"] = &ErrorWrapper; - Functions["VoidType"] = &TypeWrapper<ETypeAnnotationKind::Void>; - Functions["UnitType"] = &TypeWrapper<ETypeAnnotationKind::Unit>; - Functions["NullType"] = &TypeWrapper<ETypeAnnotationKind::Null>; - Functions["EmptyListType"] = &TypeWrapper<ETypeAnnotationKind::EmptyList>; - Functions["EmptyDictType"] = &TypeWrapper<ETypeAnnotationKind::EmptyDict>; + ExtFunctions["VoidType"] = &TypeWrapper<ETypeAnnotationKind::Void>; + ExtFunctions["UnitType"] = &TypeWrapper<ETypeAnnotationKind::Unit>; + ExtFunctions["NullType"] = &TypeWrapper<ETypeAnnotationKind::Null>; + ExtFunctions["EmptyListType"] = &TypeWrapper<ETypeAnnotationKind::EmptyList>; + ExtFunctions["EmptyDictType"] = &TypeWrapper<ETypeAnnotationKind::EmptyDict>; Functions["Join"] = &JoinWrapper; Functions["JoinDict"] = &JoinDictWrapper; Functions["MapJoinCore"] = &MapJoinCoreWrapper; @@ -12996,21 +13000,22 @@ template <NKikimr::NUdf::EDataSlot DataSlot> Functions["MultiHoppingCore"] = &MultiHoppingCoreWrapper; Functions["EquiJoin"] = &EquiJoinWrapper; Functions["OptionalReduce"] = &OptionalReduceWrapper; - Functions["OptionalItemType"] = &TypeArgWrapper<ETypeArgument::OptionalItem>; - Functions["ListItemType"] = &TypeArgWrapper<ETypeArgument::ListItem>; - Functions["StreamItemType"] = &TypeArgWrapper<ETypeArgument::StreamItem>; - Functions["TupleElementType"] = &TypeArgWrapper<ETypeArgument::TupleElement>; - Functions["StructMemberType"] = &TypeArgWrapper<ETypeArgument::StructMember>; - Functions["DictKeyType"] = &TypeArgWrapper<ETypeArgument::DictKey>; - Functions["DictPayloadType"] = &TypeArgWrapper<ETypeArgument::DictPayload>; + ExtFunctions["OptionalItemType"] = &TypeArgWrapper<ETypeArgument::OptionalItem>; + ExtFunctions["LinearItemType"] = &TypeArgWrapper<ETypeArgument::LinearItem>; + ExtFunctions["ListItemType"] = &TypeArgWrapper<ETypeArgument::ListItem>; + ExtFunctions["StreamItemType"] = &TypeArgWrapper<ETypeArgument::StreamItem>; + ExtFunctions["TupleElementType"] = &TypeArgWrapper<ETypeArgument::TupleElement>; + ExtFunctions["StructMemberType"] = &TypeArgWrapper<ETypeArgument::StructMember>; + ExtFunctions["DictKeyType"] = &TypeArgWrapper<ETypeArgument::DictKey>; + ExtFunctions["DictPayloadType"] = &TypeArgWrapper<ETypeArgument::DictPayload>; ExtFunctions["Apply"] = &ApplyWrapper; ExtFunctions["NamedApply"] = &NamedApplyWrapper; Functions["PositionalArgs"] = &PositionalArgsWrapper; ExtFunctions["SqlCall"] = &SqlCallWrapper; Functions["Callable"] = &CallableWrapper; - Functions["CallableType"] = &TypeWrapper<ETypeAnnotationKind::Callable>; - Functions["CallableResultType"] = &TypeArgWrapper<ETypeArgument::CallableResult>; - Functions["CallableArgumentType"] = &TypeArgWrapper<ETypeArgument::CallableArgument>; + ExtFunctions["CallableType"] = &TypeWrapper<ETypeAnnotationKind::Callable>; + ExtFunctions["CallableResultType"] = &TypeArgWrapper<ETypeArgument::CallableResult>; + ExtFunctions["CallableArgumentType"] = &TypeArgWrapper<ETypeArgument::CallableArgument>; Functions["CombineByKey"] = &CombineByKeyWrapper; Functions["FinalizeByKey"] = &CombineByKeyWrapper; ExtFunctions["NewMTRand"] = &NewMTRandWrapper; @@ -13052,11 +13057,11 @@ template <NKikimr::NUdf::EDataSlot DataSlot> Functions["SkipNullMembers"] = &SkipNullMembersWrapper; Functions["FilterNullElements"] = &FilterNullElementsWrapper; Functions["SkipNullElements"] = &SkipNullElementsWrapper; - Functions["AddMemberType"] = &TypeArgWrapper<ETypeArgument::AddMember>; - Functions["RemoveMemberType"] = &TypeArgWrapper<ETypeArgument::RemoveMember>; - Functions["ForceRemoveMemberType"] = &TypeArgWrapper<ETypeArgument::ForceRemoveMember>; - Functions["FlattenMembersType"] = &TypeArgWrapper<ETypeArgument::FlattenMembers>; - Functions["VariantUnderlyingType"] = &TypeArgWrapper<ETypeArgument::VariantUnderlying>; + ExtFunctions["AddMemberType"] = &TypeArgWrapper<ETypeArgument::AddMember>; + ExtFunctions["RemoveMemberType"] = &TypeArgWrapper<ETypeArgument::RemoveMember>; + ExtFunctions["ForceRemoveMemberType"] = &TypeArgWrapper<ETypeArgument::ForceRemoveMember>; + ExtFunctions["FlattenMembersType"] = &TypeArgWrapper<ETypeArgument::FlattenMembers>; + ExtFunctions["VariantUnderlyingType"] = &TypeArgWrapper<ETypeArgument::VariantUnderlying>; Functions["Guess"] = &GuessWrapper; Functions["SqlVariantItem"] = &SqlVariantItemWrapper; Functions["VariantItem"] = &VariantItemWrapper; @@ -13150,6 +13155,8 @@ template <NKikimr::NUdf::EDataSlot DataSlot> Functions["DataTypeComponents"] = &SplitTypeHandleWrapper<ETypeAnnotationKind::Data>; ExtFunctions["DataTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Data>; ExtFunctions["OptionalTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Optional>; + ExtFunctions["LinearTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Linear>; + ExtFunctions["DynamicLinearTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::DynamicLinear>; ExtFunctions["ListTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::List>; ExtFunctions["StreamTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Stream>; Functions["TupleTypeComponents"] = &SplitTypeHandleWrapper<ETypeAnnotationKind::Tuple>; diff --git a/yql/essentials/core/type_ann/type_ann_types.cpp b/yql/essentials/core/type_ann/type_ann_types.cpp index 20149a9a73b..77c1cfaee7e 100644 --- a/yql/essentials/core/type_ann/type_ann_types.cpp +++ b/yql/essentials/core/type_ann/type_ann_types.cpp @@ -6,6 +6,15 @@ namespace NYql { namespace NTypeAnnImpl { + bool CheckLinearLangver(TPositionHandle pos, TLangVersion langver, TExprContext& ctx) { + if (!IsAvailableLangVersion(MakeLangVersion(2025, 4), langver)) { + ctx.AddError(TIssue(ctx.GetPosition(pos), "Linear types are not available before version 2025.04")); + return false; + } + + return true; + } + const TTypeAnnotationNode* MakeItemDescriptorType(TExprContext& ctx) { TVector<const TItemExprType*> items = { ctx.MakeType<TItemExprType>("Name", ctx.MakeType<TDataExprType>(EDataSlot::String)), @@ -83,7 +92,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Generic>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Generic>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { Y_UNUSED(output); if (!EnsureArgsCount(*input, 0, ctx.Expr)) { return IGraphTransformer::TStatus::Error; @@ -95,7 +104,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Resource>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Resource>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { Y_UNUSED(output); if (!EnsureArgsCount(*input, 1, ctx.Expr)) { return IGraphTransformer::TStatus::Error; @@ -112,7 +121,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Tagged>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Tagged>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { Y_UNUSED(output); if (!EnsureArgsCount(*input, 2, ctx.Expr)) { return IGraphTransformer::TStatus::Error; @@ -142,7 +151,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Error>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Error>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { Y_UNUSED(output); if (!EnsureArgsCount(*input, 4, ctx.Expr)) { return IGraphTransformer::TStatus::Error; @@ -184,7 +193,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Data>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Data>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { Y_UNUSED(output); if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) { return IGraphTransformer::TStatus::Error; @@ -221,7 +230,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::List>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::List>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { Y_UNUSED(output); if (!EnsureArgsCount(*input, 1, ctx.Expr)) { return IGraphTransformer::TStatus::Error; @@ -242,7 +251,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Stream>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Stream>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { Y_UNUSED(output); if (!EnsureArgsCount(*input, 1, ctx.Expr)) { return IGraphTransformer::TStatus::Error; @@ -263,7 +272,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Flow>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Flow>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { Y_UNUSED(output); if (!EnsureArgsCount(*input, 1, ctx.Expr)) { return IGraphTransformer::TStatus::Error; @@ -284,7 +293,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Block>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Block>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { Y_UNUSED(output); if (!EnsureArgsCount(*input, 1, ctx.Expr)) { return IGraphTransformer::TStatus::Error; @@ -305,7 +314,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Scalar>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Scalar>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { Y_UNUSED(output); if (!EnsureArgsCount(*input, 1, ctx.Expr)) { return IGraphTransformer::TStatus::Error; @@ -326,7 +335,57 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Optional>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Linear>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { + Y_UNUSED(output); + if (!CheckLinearLangver(input->Pos(), ctx.Types.LangVer, ctx.Expr)) { + return IGraphTransformer::TStatus::Error; + } + + if (!EnsureArgsCount(*input, 1, ctx.Expr)) { + return IGraphTransformer::TStatus::Error; + } + + if (auto status = EnsureTypeRewrite(input->HeadRef(), ctx.Expr); status != IGraphTransformer::TStatus::Ok) { + return status; + } + + auto itemType = input->Child(0)->GetTypeAnn()->Cast<TTypeExprType>()->GetType(); + if (!EnsureInspectableType(input->Child(0)->Pos(), *itemType, ctx.Expr)) { + return IGraphTransformer::TStatus::Error; + } + + auto type = ctx.Expr.MakeType<TLinearExprType>(itemType); + input->SetTypeAnn(ctx.Expr.MakeType<TTypeExprType>(type)); + return IGraphTransformer::TStatus::Ok; + } + + template <> + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::DynamicLinear>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { + Y_UNUSED(output); + if (!CheckLinearLangver(input->Pos(), ctx.Types.LangVer, ctx.Expr)) { + return IGraphTransformer::TStatus::Error; + } + + if (!EnsureArgsCount(*input, 1, ctx.Expr)) { + return IGraphTransformer::TStatus::Error; + } + + if (auto status = EnsureTypeRewrite(input->HeadRef(), ctx.Expr); status != IGraphTransformer::TStatus::Ok) { + return status; + } + + auto itemType = input->Child(0)->GetTypeAnn()->Cast<TTypeExprType>()->GetType(); + if (!EnsureInspectableType(input->Child(0)->Pos(), *itemType, ctx.Expr)) { + return IGraphTransformer::TStatus::Error; + } + + auto type = ctx.Expr.MakeType<TDynamicLinearExprType>(itemType); + input->SetTypeAnn(ctx.Expr.MakeType<TTypeExprType>(type)); + return IGraphTransformer::TStatus::Ok; + } + + template <> + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Optional>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { Y_UNUSED(output); if (!EnsureArgsCount(*input, 1, ctx.Expr)) { return IGraphTransformer::TStatus::Error; @@ -347,7 +406,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Tuple>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Tuple>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { Y_UNUSED(output); TTypeAnnotationNode::TListType items; for (size_t i = 0; i < input->ChildrenSize(); ++i) { @@ -369,7 +428,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Multi>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Multi>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { Y_UNUSED(output); TTypeAnnotationNode::TListType items; for (size_t i = 0; i < input->ChildrenSize(); ++i) { @@ -392,7 +451,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Struct>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Struct>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { Y_UNUSED(output); TVector<const TItemExprType*> items; for (size_t i = 0; i < input->ChildrenSize(); ++i) { @@ -443,7 +502,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Dict>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Dict>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { Y_UNUSED(output); if (!EnsureArgsCount(*input, 2, ctx.Expr)) { return IGraphTransformer::TStatus::Error; @@ -473,7 +532,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Void>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Void>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { Y_UNUSED(output); if (!EnsureArgsCount(*input, 0, ctx.Expr)) { return IGraphTransformer::TStatus::Error; @@ -485,7 +544,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Null>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Null>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { Y_UNUSED(output); if (!EnsureArgsCount(*input, 0, ctx.Expr)) { return IGraphTransformer::TStatus::Error; @@ -497,7 +556,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Unit>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Unit>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { Y_UNUSED(output); if (!EnsureArgsCount(*input, 0, ctx.Expr)) { return IGraphTransformer::TStatus::Error; @@ -509,7 +568,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::EmptyList>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::EmptyList>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { Y_UNUSED(output); if (!EnsureArgsCount(*input, 0, ctx.Expr)) { return IGraphTransformer::TStatus::Error; @@ -521,7 +580,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::EmptyDict>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::EmptyDict>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { Y_UNUSED(output); if (!EnsureArgsCount(*input, 0, ctx.Expr)) { return IGraphTransformer::TStatus::Error; @@ -533,7 +592,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::OptionalItem>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::OptionalItem>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { if (!EnsureArgsCount(*input, 1, ctx.Expr)) { return IGraphTransformer::TStatus::Error; } @@ -565,7 +624,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::ListItem>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::ListItem>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { if (!EnsureArgsCount(*input, 1, ctx.Expr)) { return IGraphTransformer::TStatus::Error; } @@ -597,7 +656,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::StreamItem>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::StreamItem>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { if (!EnsureArgsCount(*input, 1, ctx.Expr)) { return IGraphTransformer::TStatus::Error; } @@ -624,7 +683,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::TupleElement>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::TupleElement>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { if (!EnsureArgsCount(*input, 2, ctx.Expr)) { return IGraphTransformer::TStatus::Error; } @@ -663,7 +722,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::StructMember>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::StructMember>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { if (!EnsureArgsCount(*input, 2, ctx.Expr)) { return IGraphTransformer::TStatus::Error; } @@ -703,7 +762,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::DictKey>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::DictKey>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { if (!EnsureArgsCount(*input, 1, ctx.Expr)) { return IGraphTransformer::TStatus::Error; } @@ -729,7 +788,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::DictPayload>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::DictPayload>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { if (!EnsureArgsCount(*input, 1, ctx.Expr)) { return IGraphTransformer::TStatus::Error; } @@ -755,7 +814,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Callable>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Callable>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { Y_UNUSED(output); if (!EnsureMinArgsCount(*input, 2, ctx.Expr)) { return IGraphTransformer::TStatus::Error; @@ -856,7 +915,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::CallableResult>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::CallableResult>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { if (!EnsureArgsCount(*input, 1, ctx.Expr)) { return IGraphTransformer::TStatus::Error; } @@ -877,7 +936,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::CallableArgument>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::CallableArgument>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { if (!EnsureArgsCount(*input, 2, ctx.Expr)) { return IGraphTransformer::TStatus::Error; } @@ -953,6 +1012,40 @@ namespace NTypeAnnImpl { return IGraphTransformer::TStatus::Ok; } + template <> + IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::LinearItem>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { + if (!CheckLinearLangver(input->Pos(), ctx.Types.LangVer, ctx.Expr)) { + return IGraphTransformer::TStatus::Error; + } + + if (!EnsureArgsCount(*input, 1, ctx.Expr)) { + return IGraphTransformer::TStatus::Error; + } + + auto resType = MakeTypeHandleResourceType(ctx.Expr); + if (input->Child(0)->GetTypeAnn() == resType) { + input->SetTypeAnn(resType); + return IGraphTransformer::TStatus::Ok; + } + + if (auto status = EnsureTypeRewrite(input->HeadRef(), ctx.Expr); status != IGraphTransformer::TStatus::Ok) { + return status; + } + + auto type = input->Child(0)->GetTypeAnn()->Cast<TTypeExprType>()->GetType(); + if (type->GetKind() == ETypeAnnotationKind::Linear) { + output = ExpandType(input->Pos(), *type->Cast<TLinearExprType>()->GetItemType(), ctx.Expr); + return IGraphTransformer::TStatus::Repeat; + } else if (type->GetKind() == ETypeAnnotationKind::DynamicLinear) { + output = ExpandType(input->Pos(), *type->Cast<TDynamicLinearExprType>()->GetItemType(), ctx.Expr); + return IGraphTransformer::TStatus::Repeat; + } else { + ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(0)->Pos()), + TStringBuilder() << "Expected (dynamic) linear type, but got: " << *type)); + return IGraphTransformer::TStatus::Error; + } + } + IGraphTransformer::TStatus FormatTypeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { Y_UNUSED(output); if (!EnsureArgsCount(*input, 1, ctx.Expr)) { @@ -1041,7 +1134,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::AddMember>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::AddMember>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { if (!EnsureArgsCount(*input, 3, ctx.Expr)) { return IGraphTransformer::TStatus::Error; } @@ -1133,17 +1226,17 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::RemoveMember>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::RemoveMember>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { return RemoveMemberImpl(input, output, ctx, false); } template <> - IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::ForceRemoveMember>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::ForceRemoveMember>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { return RemoveMemberImpl(input, output, ctx, true); } template <> - IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::FlattenMembers>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::FlattenMembers>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { TVector<const TItemExprType*> allItems; for (auto& child : input->Children()) { if (!EnsureTupleSize(*child, 2, ctx.Expr)) { @@ -1189,7 +1282,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Variant>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Variant>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { Y_UNUSED(output); if (!EnsureArgsCount(*input, 1, ctx.Expr)) { return IGraphTransformer::TStatus::Error; @@ -1214,7 +1307,7 @@ namespace NTypeAnnImpl { } template <> - IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::VariantUnderlying>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::VariantUnderlying>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { if (!EnsureArgsCount(*input, 1, ctx.Expr)) { return IGraphTransformer::TStatus::Error; } @@ -1305,6 +1398,44 @@ namespace NTypeAnnImpl { } template <> + IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Linear>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { + Y_UNUSED(output); + if (!CheckLinearLangver(input->Pos(), ctx.Types.LangVer, ctx.Expr)) { + return IGraphTransformer::TStatus::Error; + } + + if (!EnsureArgsCount(*input, 1, ctx.Expr)) { + return IGraphTransformer::TStatus::Error; + } + + if (!EnsureTypeHandleResourceType(*input->Child(0), ctx.Expr)) { + return IGraphTransformer::TStatus::Error; + } + + input->SetTypeAnn(MakeTypeHandleResourceType(ctx.Expr)); + return IGraphTransformer::TStatus::Ok; + } + + template <> + IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::DynamicLinear>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { + Y_UNUSED(output); + if (!CheckLinearLangver(input->Pos(), ctx.Types.LangVer, ctx.Expr)) { + return IGraphTransformer::TStatus::Error; + } + + if (!EnsureArgsCount(*input, 1, ctx.Expr)) { + return IGraphTransformer::TStatus::Error; + } + + if (!EnsureTypeHandleResourceType(*input->Child(0), ctx.Expr)) { + return IGraphTransformer::TStatus::Error; + } + + input->SetTypeAnn(MakeTypeHandleResourceType(ctx.Expr)); + return IGraphTransformer::TStatus::Ok; + } + + template <> IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::List>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) { Y_UNUSED(output); if (!EnsureArgsCount(*input, 1, ctx.Expr)) { diff --git a/yql/essentials/core/type_ann/type_ann_types.h b/yql/essentials/core/type_ann/type_ann_types.h index 1223b0877e7..5e266da3851 100644 --- a/yql/essentials/core/type_ann/type_ann_types.h +++ b/yql/essentials/core/type_ann/type_ann_types.h @@ -8,7 +8,7 @@ namespace NYql { namespace NTypeAnnImpl { template <ETypeAnnotationKind> - IGraphTransformer::TStatus TypeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx); + IGraphTransformer::TStatus TypeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx); #define TYPE_ANN_TYPE_ARGUMENT_MAP(xx) \ xx(Unknown, 0) \ @@ -25,14 +25,15 @@ namespace NTypeAnnImpl { xx(ForceRemoveMember, 11) \ xx(FlattenMembers, 12) \ xx(VariantUnderlying, 13) \ - xx(StreamItem, 14) + xx(StreamItem, 14) \ + xx(LinearItem, 15) enum class ETypeArgument { TYPE_ANN_TYPE_ARGUMENT_MAP(ENUM_VALUE_GEN) }; template <ETypeArgument> - IGraphTransformer::TStatus TypeArgWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx); + IGraphTransformer::TStatus TypeArgWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx); IGraphTransformer::TStatus ParseTypeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx); IGraphTransformer::TStatus FormatTypeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx); IGraphTransformer::TStatus FormatTypeDiffWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx); @@ -55,5 +56,7 @@ namespace NTypeAnnImpl { template <TExprNode::EType> IGraphTransformer::TStatus MakeCodeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx); + + bool CheckLinearLangver(TPositionHandle pos, TLangVersion langver, TExprContext& ctx); } // namespace NTypeAnnImpl } // namespace NYql diff --git a/yql/essentials/core/yql_default_valid_value.cpp b/yql/essentials/core/yql_default_valid_value.cpp index 69e0fd1eb15..f42ec429f0d 100644 --- a/yql/essentials/core/yql_default_valid_value.cpp +++ b/yql/essentials/core/yql_default_valid_value.cpp @@ -159,6 +159,16 @@ private: Result_ = false; // YQL_ENSURE(false, "ScalarExprType is not supported."); } + void Visit(const TLinearExprType& type) override { + Y_UNUSED(type); + Result_ = false; // YQL_ENSURE(false, "BlockExprType is not supported."); + } + + void Visit(const TDynamicLinearExprType& type) override { + Y_UNUSED(type); + Result_ = false; // YQL_ENSURE(false, "ScalarExprType is not supported."); + } + private: const TTypeAnnotationNode* Type_; bool Result_ = false; @@ -453,6 +463,16 @@ private: YQL_ENSURE(false, "ScalarExprType is not supported."); } + void Visit(const TLinearExprType& type) override { + Y_UNUSED(type); + YQL_ENSURE(false, "LinearExprType is not supported."); + } + + void Visit(const TDynamicLinearExprType& type) override { + Y_UNUSED(type); + YQL_ENSURE(false, "DynamicLinearExprType is not supported."); + } + private: const TTypeAnnotationNode* Type_; TExprContext& Ctx_; diff --git a/yql/essentials/core/yql_expr_type_annotation.cpp b/yql/essentials/core/yql_expr_type_annotation.cpp index 1d863435864..6f234230fd1 100644 --- a/yql/essentials/core/yql_expr_type_annotation.cpp +++ b/yql/essentials/core/yql_expr_type_annotation.cpp @@ -6120,6 +6120,20 @@ TExprNode::TPtr ExpandTypeNoCache(TPositionHandle position, const TTypeAnnotatio return ret; } + case ETypeAnnotationKind::Linear: + { + auto ret = ctx.NewCallable(position, "LinearType", + { ExpandType(position, *type.Cast<TLinearExprType>()->GetItemType(), ctx) }); + return ret; + } + + case ETypeAnnotationKind::DynamicLinear: + { + auto ret = ctx.NewCallable(position, "DynamicLinearType", + { ExpandType(position, *type.Cast<TDynamicLinearExprType>()->GetItemType(), ctx) }); + return ret; + } + default: YQL_ENSURE(false, "Unsupported kind: " << (ui32)type.GetKind()); } diff --git a/yql/essentials/data/language/sql_functions.json b/yql/essentials/data/language/sql_functions.json index 2535c8e3428..9c7d6ed3b8f 100644 --- a/yql/essentials/data/language/sql_functions.json +++ b/yql/essentials/data/language/sql_functions.json @@ -384,6 +384,10 @@ "kind": "Normal" }, { + "name": "DynamicLinearTypeHandle", + "kind": "Normal" + }, + { "name": "DynamicVariant", "kind": "Normal" }, @@ -628,6 +632,18 @@ "kind": "Agg" }, { + "name": "LinearItemType", + "kind": "Normal" + }, + { + "name": "LinearType", + "kind": "Normal" + }, + { + "name": "LinearTypeHandle", + "kind": "Normal" + }, + { "name": "ListAggregate", "kind": "Normal" }, diff --git a/yql/essentials/providers/common/comp_nodes/yql_factory.cpp b/yql/essentials/providers/common/comp_nodes/yql_factory.cpp index 4eba3673481..7e6ea121c30 100644 --- a/yql/essentials/providers/common/comp_nodes/yql_factory.cpp +++ b/yql/essentials/providers/common/comp_nodes/yql_factory.cpp @@ -32,6 +32,9 @@ struct TYqlCallableComputationNodeBuilderFuncMapFiller { Map["DataTypeHandle"] = &WrapMakeType<NYql::ETypeAnnotationKind::Data>; Map["OptionalItemType"] = &WrapSplitType<NYql::ETypeAnnotationKind::Optional>; Map["OptionalTypeHandle"] = &WrapMakeType<NYql::ETypeAnnotationKind::Optional>; + Map["LinearItemType"] = &WrapSplitType<NYql::ETypeAnnotationKind::Linear>; + Map["LinearTypeHandle"] = &WrapMakeType<NYql::ETypeAnnotationKind::Linear>; + Map["DynamicLinearTypeHandle"] = &WrapMakeType<NYql::ETypeAnnotationKind::DynamicLinear>; Map["ListItemType"] = &WrapSplitType<NYql::ETypeAnnotationKind::List>; Map["ListTypeHandle"] = &WrapMakeType<NYql::ETypeAnnotationKind::List>; Map["StreamItemType"] = &WrapSplitType<NYql::ETypeAnnotationKind::Stream>; diff --git a/yql/essentials/providers/common/comp_nodes/yql_maketype.cpp b/yql/essentials/providers/common/comp_nodes/yql_maketype.cpp index a9de200c3f6..e7858748769 100644 --- a/yql/essentials/providers/common/comp_nodes/yql_maketype.cpp +++ b/yql/essentials/providers/common/comp_nodes/yql_maketype.cpp @@ -109,6 +109,18 @@ namespace { static constexpr size_t MinValue = 1; static constexpr size_t MaxValue = 1; }; + + template <> + struct TMakeTypeArgs<NYql::ETypeAnnotationKind::Linear> { + static constexpr size_t MinValue = 1; + static constexpr size_t MaxValue = 1; + }; + + template <> + struct TMakeTypeArgs<NYql::ETypeAnnotationKind::DynamicLinear> { + static constexpr size_t MinValue = 1; + static constexpr size_t MaxValue = 1; + }; } template <NYql::ETypeAnnotationKind Kind> @@ -322,6 +334,18 @@ public: break; } + case NYql::ETypeAnnotationKind::Linear: { + auto type = GetYqlType(Args_[0]->GetValue(ctx)); + retType = exprCtxPtr->template MakeType<NYql::TLinearExprType>(type); + break; + } + + case NYql::ETypeAnnotationKind::DynamicLinear: { + auto type = GetYqlType(Args_[0]->GetValue(ctx)); + retType = exprCtxPtr->template MakeType<NYql::TDynamicLinearExprType>(type); + break; + } + default: MKQL_ENSURE(false, "Unsupported kind:" << Kind); } @@ -406,5 +430,11 @@ template IComputationNode* WrapMakeType<NYql::ETypeAnnotationKind::Callable> template IComputationNode* WrapMakeType<NYql::ETypeAnnotationKind::Pg> (TCallable& callable, const TComputationNodeFactoryContext& ctx, ui32 exprCtxMutableIndex); +template IComputationNode* WrapMakeType<NYql::ETypeAnnotationKind::Linear> + (TCallable& callable, const TComputationNodeFactoryContext& ctx, ui32 exprCtxMutableIndex); + +template IComputationNode* WrapMakeType<NYql::ETypeAnnotationKind::DynamicLinear> + (TCallable& callable, const TComputationNodeFactoryContext& ctx, ui32 exprCtxMutableIndex); + } } diff --git a/yql/essentials/providers/common/comp_nodes/yql_splittype.cpp b/yql/essentials/providers/common/comp_nodes/yql_splittype.cpp index 0506d74523a..86f8490b4bc 100644 --- a/yql/essentials/providers/common/comp_nodes/yql_splittype.cpp +++ b/yql/essentials/providers/common/comp_nodes/yql_splittype.cpp @@ -192,6 +192,20 @@ public: return MakeString(castedType->GetName()); } + case NYql::ETypeAnnotationKind::Linear: { + const NYql::TTypeAnnotationNode* itemType; + if (type->GetKind() == NYql::ETypeAnnotationKind::Linear) { + itemType = type->Cast<NYql::TLinearExprType>()->GetItemType(); + } else if (type->GetKind() == NYql::ETypeAnnotationKind::DynamicLinear) { + itemType = type->Cast<NYql::TDynamicLinearExprType>()->GetItemType(); + } else { + ReportError(*exprCtxPtr, NYql::TIssue(Pos_, TStringBuilder() << "Cannot cast type " << *type << " to (dynamic) linear type")); + UdfTerminate(exprCtxPtr->IssueManager.GetIssues().ToString().data()); + } + + return NUdf::TUnboxedValuePod(new TYqlTypeResource(exprCtxPtr, itemType)); + } + default: MKQL_ENSURE(false, "Unsupported kind:" << Kind); } @@ -251,5 +265,8 @@ template IComputationNode* WrapSplitType<NYql::ETypeAnnotationKind::Callable> template IComputationNode* WrapSplitType<NYql::ETypeAnnotationKind::Pg> (TCallable& callable, const TComputationNodeFactoryContext& ctx, ui32 exprCtxMutableIndex); +template IComputationNode* WrapSplitType<NYql::ETypeAnnotationKind::Linear> + (TCallable& callable, const TComputationNodeFactoryContext& ctx, ui32 exprCtxMutableIndex); + } } diff --git a/yql/essentials/providers/common/mkql/yql_provider_mkql.cpp b/yql/essentials/providers/common/mkql/yql_provider_mkql.cpp index 37dcece2c54..0369cf0d751 100644 --- a/yql/essentials/providers/common/mkql/yql_provider_mkql.cpp +++ b/yql/essentials/providers/common/mkql/yql_provider_mkql.cpp @@ -2329,6 +2329,9 @@ TMkqlCommonCallableCompiler::TShared::TShared() { "CallableTypeHandle", "PgTypeName", "PgTypeHandle", + "LinearTypeHandle", + "DynamicLinearTypeHandle", + "LinearItemType", "WorldCode", "AtomCode", "ListCode", diff --git a/yql/essentials/providers/common/mkql/yql_type_mkql.cpp b/yql/essentials/providers/common/mkql/yql_type_mkql.cpp index 7ea15315782..d49a7f6d89a 100644 --- a/yql/essentials/providers/common/mkql/yql_type_mkql.cpp +++ b/yql/essentials/providers/common/mkql/yql_type_mkql.cpp @@ -209,6 +209,24 @@ NKikimr::NMiniKQL::TType* BuildTypeImpl(const TTypeAnnotationNode& annotation, c return typeBuilder.NewBlockType(itemType, NKikimr::NMiniKQL::TBlockType::EShape::Scalar); } + case ETypeAnnotationKind::Linear: { + auto linear = annotation.Cast<TLinearExprType>(); + auto itemType = BuildType(*linear->GetItemType(), typeBuilder, memoization, err); + if (!itemType) { + return nullptr; + } + return typeBuilder.NewLinearType(itemType, false); + } + + case ETypeAnnotationKind::DynamicLinear: { + auto linear = annotation.Cast<TDynamicLinearExprType>(); + auto itemType = BuildType(*linear->GetItemType(), typeBuilder, memoization, err); + if (!itemType) { + return nullptr; + } + return typeBuilder.NewLinearType(itemType, true); + } + case ETypeAnnotationKind::Item: case ETypeAnnotationKind::World: case ETypeAnnotationKind::Error: @@ -443,13 +461,11 @@ const TTypeAnnotationNode* ConvertMiniKQLType(TPosition position, NKikimr::NMini { auto linType = static_cast<TLinearType*>(type); auto itemType = ConvertMiniKQLType(position, linType->GetItemType(), ctx); - /*if (linType->IsDynamic()) { + if (linType->IsDynamic()) { return ctx.MakeType<TDynamicLinearExprType>(itemType); } else { return ctx.MakeType<TLinearExprType>(itemType); - }*/ - Y_UNUSED(itemType); - ythrow yexception() << "TODO"; + } } } @@ -513,12 +529,12 @@ ETypeAnnotationKind ConvertMiniKQLTypeKind(NKikimr::NMiniKQL::TType* type) { return ETypeAnnotationKind::Multi; case TType::EKind::Linear: { - /*auto linType = static_cast<TLinearType*>(type); + auto linType = static_cast<TLinearType*>(type); if (linType->IsDynamic()) { return ETypeAnnotationKind::DynamicLinear; } else { return ETypeAnnotationKind::Linear; - }*/ + } break; } } diff --git a/yql/essentials/providers/common/schema/expr/yql_expr_schema.cpp b/yql/essentials/providers/common/schema/expr/yql_expr_schema.cpp index b834794b5bd..cc40b5c18a9 100644 --- a/yql/essentials/providers/common/schema/expr/yql_expr_schema.cpp +++ b/yql/essentials/providers/common/schema/expr/yql_expr_schema.cpp @@ -224,6 +224,12 @@ public: case ETypeAnnotationKind::Stream: TBase::SaveStreamType(*type->Cast<TStreamExprType>()); break; + case ETypeAnnotationKind::Linear: + TBase::SaveLinearType(*type->Cast<TLinearExprType>()); + break; + case ETypeAnnotationKind::DynamicLinear: + TBase::SaveDynamicLinearType(*type->Cast<TDynamicLinearExprType>()); + break; default: YQL_ENSURE(false, "Unsupported type annotation kind: " << type->GetKind()); } @@ -337,6 +343,12 @@ struct TExprTypeLoader { TMaybe<TType> LoadOptionalType(TType itemType, ui32 /*level*/) { return Ctx.MakeType<TOptionalExprType>(itemType); } + TMaybe<TType> LoadLinearType(TType itemType, ui32 /*level*/) { + return Ctx.MakeType<TLinearExprType>(itemType); + } + TMaybe<TType> LoadDynamicLinearType(TType itemType, ui32 /*level*/) { + return Ctx.MakeType<TDynamicLinearExprType>(itemType); + } TMaybe<TType> LoadTupleType(const TVector<TType>& elements, ui32 /*level*/) { auto ret = Ctx.MakeType<TTupleExprType>(elements); YQL_ENSURE(ret->Validate(TPosition(), Ctx)); diff --git a/yql/essentials/providers/common/schema/mkql/yql_mkql_schema.cpp b/yql/essentials/providers/common/schema/mkql/yql_mkql_schema.cpp index 8273070925e..8796574d087 100644 --- a/yql/essentials/providers/common/schema/mkql/yql_mkql_schema.cpp +++ b/yql/essentials/providers/common/schema/mkql/yql_mkql_schema.cpp @@ -264,6 +264,12 @@ struct TRuntimeTypeLoader { TMaybe<TType> LoadDictType(TType keyType, TType valType, ui32 /*level*/) { return Builder.NewDictType(keyType, valType, false); } + TMaybe<TType> LoadLinearType(TType itemType, ui32 /*level*/) { + return Builder.NewLinearType(itemType, false); + } + TMaybe<TType> LoadDynamicLinearType(TType itemType, ui32 /*level*/) { + return Builder.NewLinearType(itemType, true); + } TMaybe<TType> LoadCallableType(TType returnType, const TVector<TType>& argTypes, const TVector<TString>& argNames, const TVector<ui64>& argFlags, size_t optionalCount, const TString& payload, ui32 /*level*/) { diff --git a/yql/essentials/providers/common/schema/parser/yql_type_parser.h b/yql/essentials/providers/common/schema/parser/yql_type_parser.h index df673d760b4..bb3270d6ad6 100644 --- a/yql/essentials/providers/common/schema/parser/yql_type_parser.h +++ b/yql/essentials/providers/common/schema/parser/yql_type_parser.h @@ -115,6 +115,24 @@ protected: Writer_.OnEndList(); } + template <typename TLinearType> + void SaveLinearType(const TLinearType& linearType) { + SaveTypeHeader("LinearType"); + Writer_.OnListItem(); + TSelf item(Writer_, ExtendedForm_); + item.Save(linearType.GetItemType()); + Writer_.OnEndList(); + } + + template <typename TLinearType> + void SaveDynamicLinearType(const TLinearType& linearType) { + SaveTypeHeader("DynamicLinearType"); + Writer_.OnListItem(); + TSelf item(Writer_, ExtendedForm_); + item.Save(linearType.GetItemType()); + Writer_.OnEndList(); + } + template <typename TDictType> void SaveDictType(const TDictType& dictType) { SaveTypeHeader("DictType"); @@ -314,6 +332,26 @@ TMaybe<typename TLoader::TType> DoLoadTypeFromYson(TLoader& loader, const NYT::T return Nothing(); } return loader.LoadOptionalType(*itemType, level); + } else if (typeName == "LinearType") { + if (node.Size() != 2) { + loader.Error("Invalid optional type scheme"); + return Nothing(); + } + auto itemType = DoLoadTypeFromYson(loader, node[1], level + 1); + if (!itemType) { + return Nothing(); + } + return loader.LoadLinearType(*itemType, level); + } else if (typeName == "DynamicLinearType") { + if (node.Size() != 2) { + loader.Error("Invalid optional type scheme"); + return Nothing(); + } + auto itemType = DoLoadTypeFromYson(loader, node[1], level + 1); + if (!itemType) { + return Nothing(); + } + return loader.LoadDynamicLinearType(*itemType, level); } else if (typeName == "TupleType") { if (node.Size() != 2 || !node[1].IsList()) { loader.Error("Invalid tuple type scheme"); diff --git a/yql/essentials/providers/common/schema/skiff/yql_skiff_schema.cpp b/yql/essentials/providers/common/schema/skiff/yql_skiff_schema.cpp index e8f9abdc99b..bd9e5429db1 100644 --- a/yql/essentials/providers/common/schema/skiff/yql_skiff_schema.cpp +++ b/yql/essentials/providers/common/schema/skiff/yql_skiff_schema.cpp @@ -143,6 +143,12 @@ struct TSkiffTypeLoader { return NYT::TNode()("wire_type", "string32"); } + TMaybe<TType> LoadLinearType(TType /*itemType*/, ui32 /*level*/) { + ythrow yexception() << "Unsupported type: LinearType"; + } + TMaybe<TType> LoadDynamicLinearType(TType /*itemType*/, ui32 /*level*/) { + ythrow yexception() << "Unsupported type: DynamicLinearType"; + } TMaybe<TType> LoadResourceType(const TString& /*tag*/, ui32 /*level*/) { ythrow yexception() << "Unsupported type: Resource"; } diff --git a/yql/essentials/sql/v1/builtin.cpp b/yql/essentials/sql/v1/builtin.cpp index 473984841c8..35af7dcd20d 100644 --- a/yql/essentials/sql/v1/builtin.cpp +++ b/yql/essentials/sql/v1/builtin.cpp @@ -3134,6 +3134,9 @@ struct TBuiltinFuncData { {"taggedtype", {"TaggedType", "Normal", BuildSimpleBuiltinFactoryCallback<TYqlTaggedType>()}}, {"varianttype", {"VariantType", "Normal", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("VariantType", 1, 1)}}, {"callabletype", {"CallableType", "Normal", BuildSimpleBuiltinFactoryCallback<TYqlCallableType>()}}, + {"lineartype", {"LinearType", "Normal", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("LinearType", 1, 1)}}, + {"dynamiclineartype", {"LinearType", "Normal", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("DynamicLinearType", 1, 1)}}, + {"linearitemtype", {"LinearItemType", "Normal", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("LinearItemType", 1, 1)}}, {"optionalitemtype", {"OptionalItemType", "Normal", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("OptionalItemType", 1, 1)}}, {"listitemtype", {"ListItemType", "Normal", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListItemType", 1, 1)}}, {"streamitemtype", {"ListItemType", "Normal", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("StreamItemType", 1, 1)}}, @@ -3168,6 +3171,8 @@ struct TBuiltinFuncData { {"datatypecomponents", {"DataTypeComponents", "Normal", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("DataTypeComponents", 1, 1)}}, {"datatypehandle", {"DataTypeHandle", "Normal", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("DataTypeHandle", 1, 1)}}, {"optionaltypehandle", {"OptionalTypeHandle", "Normal", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("OptionalTypeHandle", 1, 1)}}, + {"lineartypehandle", {"LinearTypeHandle", "Normal", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("LinearTypeHandle", 1, 1)}}, + {"dynamiclineartypehandle", {"DynamicLinearTypeHandle", "Normal", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("DynamicLinearTypeHandle", 1, 1)}}, {"listtypehandle", {"ListTypeHandle", "Normal", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListTypeHandle", 1, 1)}}, {"streamtypehandle", {"StreamTypeHandle", "Normal", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("StreamTypeHandle", 1, 1)}}, {"tupletypecomponents", {"TupleTypeComponents", "Normal", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("TupleTypeComponents", 1, 1)}}, diff --git a/yql/essentials/tests/sql/minirun/part6/canondata/result.json b/yql/essentials/tests/sql/minirun/part6/canondata/result.json index 560a7290800..09014fa6e9b 100644 --- a/yql/essentials/tests/sql/minirun/part6/canondata/result.json +++ b/yql/essentials/tests/sql/minirun/part6/canondata/result.json @@ -1029,6 +1029,20 @@ "uri": "https://{canondata_backend}/1871102/cf0bf303bf8ddaa5f80dc41d0b1079fd931793f8/resource.tar.gz#test.test_like-ilike-Ansi-Results_/results.txt" } ], + "test.test[linear-types-default.txt-Debug]": [ + { + "checksum": "013b2c346f23df65f2e461b9a9cff6f9", + "size": 420, + "uri": "https://{canondata_backend}/1781765/972251ebb8228a889fb9ce1afa36c3b56345fcfe/resource.tar.gz#test.test_linear-types-default.txt-Debug_/opt.yql" + } + ], + "test.test[linear-types-default.txt-Results]": [ + { + "checksum": "c41448a02612fcc93b6ebd7962faad93", + "size": 1625, + "uri": "https://{canondata_backend}/1781765/972251ebb8228a889fb9ce1afa36c3b56345fcfe/resource.tar.gz#test.test_linear-types-default.txt-Results_/results.txt" + } + ], "test.test[match_recognize-alerts_without_order-default.txt-Debug]": [ { "checksum": "617ad997b55cab0792da8c20f2fdeb07", diff --git a/yql/essentials/tests/sql/minirun/part9/canondata/result.json b/yql/essentials/tests/sql/minirun/part9/canondata/result.json index a313c227381..49df7e40b13 100644 --- a/yql/essentials/tests/sql/minirun/part9/canondata/result.json +++ b/yql/essentials/tests/sql/minirun/part9/canondata/result.json @@ -936,6 +936,20 @@ "uri": "https://{canondata_backend}/1942173/7dbfc6f1dbd4edd784817a1f9360cbbf58ed389f/resource.tar.gz#test.test_json-jsondocument_json_exists-default.txt-Results_/results.txt" } ], + "test.test[linear-types_reflection-default.txt-Debug]": [ + { + "checksum": "f560663decd46b1e0aa9ffa6b4cb4abe", + "size": 636, + "uri": "https://{canondata_backend}/1600758/7572854f0d921d6c5b446004dd4694f0b511211c/resource.tar.gz#test.test_linear-types_reflection-default.txt-Debug_/opt.yql" + } + ], + "test.test[linear-types_reflection-default.txt-Results]": [ + { + "checksum": "dc95189bef8e953c51115063d8e7182d", + "size": 2230, + "uri": "https://{canondata_backend}/1600758/7572854f0d921d6c5b446004dd4694f0b511211c/resource.tar.gz#test.test_linear-types_reflection-default.txt-Results_/results.txt" + } + ], "test.test[optimizers-constant_fold_minmax-default.txt-Debug]": [ { "checksum": "fb7c8de975c9383e0a70b0f78e868776", diff --git a/yql/essentials/tests/sql/sql2yql/canondata/result.json b/yql/essentials/tests/sql/sql2yql/canondata/result.json index 58981eb0d31..85601647767 100644 --- a/yql/essentials/tests/sql/sql2yql/canondata/result.json +++ b/yql/essentials/tests/sql/sql2yql/canondata/result.json @@ -4976,6 +4976,20 @@ "uri": "https://{canondata_backend}/1937150/ec0019724df75083b0e89cab22f57e10ef36744e/resource.tar.gz#test_sql2yql.test_like-like_rewrite_/sql.yql" } ], + "test_sql2yql.test[linear-types]": [ + { + "checksum": "f756d489eb05467c7a6414636f47f37e", + "size": 1609, + "uri": "https://{canondata_backend}/1781765/e398ef188885373eb0a98e1d374e17ce1b8dfd7c/resource.tar.gz#test_sql2yql.test_linear-types_/sql.yql" + } + ], + "test_sql2yql.test[linear-types_reflection]": [ + { + "checksum": "4566c1aaefced662dfd823a332922d0d", + "size": 2089, + "uri": "https://{canondata_backend}/1942100/f91a9f890b15407bdf858550427100932981d900/resource.tar.gz#test_sql2yql.test_linear-types_reflection_/sql.yql" + } + ], "test_sql2yql.test[match_recognize-after_match_skip_past_last_row]": [ { "checksum": "8c019a9e653e16decf0c5d7eee2fe567", @@ -11989,6 +12003,16 @@ "uri": "file://test_sql_format.test_like-like_rewrite_/formatted.sql" } ], + "test_sql_format.test[linear-types]": [ + { + "uri": "file://test_sql_format.test_linear-types_/formatted.sql" + } + ], + "test_sql_format.test[linear-types_reflection]": [ + { + "uri": "file://test_sql_format.test_linear-types_reflection_/formatted.sql" + } + ], "test_sql_format.test[match_recognize-after_match_skip_past_last_row]": [ { "uri": "file://test_sql_format.test_match_recognize-after_match_skip_past_last_row_/formatted.sql" diff --git a/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_linear-types_/formatted.sql b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_linear-types_/formatted.sql new file mode 100644 index 00000000000..55128f8b7d7 --- /dev/null +++ b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_linear-types_/formatted.sql @@ -0,0 +1,6 @@ +SELECT + FormatType(LinearType(Int32)), + FormatType(DynamicLinearType(Int32)), + FormatType(ParseType('Linear<Int32>')), + FormatType(LinearItemType(LinearType(Int32))) +; diff --git a/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_linear-types_reflection_/formatted.sql b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_linear-types_reflection_/formatted.sql new file mode 100644 index 00000000000..cf8c59edce8 --- /dev/null +++ b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_linear-types_reflection_/formatted.sql @@ -0,0 +1,8 @@ +SELECT + TypeKind(TypeHandle(LinearType(Int32))), + TypeKind(TypeHandle(DynamicLinearType(Int32))), + FormatType(EvaluateType(TypeHandle(LinearType(Int32)))), + FormatType(LinearTypeHandle(TypeHandle(Int32))), + FormatType(DynamicLinearTypeHandle(TypeHandle(Int32))), + FormatType(LinearItemType(TypeHandle(LinearType(Int32)))) +; diff --git a/yql/essentials/tests/sql/suites/linear/default.cfg b/yql/essentials/tests/sql/suites/linear/default.cfg new file mode 100644 index 00000000000..7e882f1da85 --- /dev/null +++ b/yql/essentials/tests/sql/suites/linear/default.cfg @@ -0,0 +1,2 @@ +langver 2025.04 + diff --git a/yql/essentials/tests/sql/suites/linear/types.yql b/yql/essentials/tests/sql/suites/linear/types.yql new file mode 100644 index 00000000000..a9d832acd94 --- /dev/null +++ b/yql/essentials/tests/sql/suites/linear/types.yql @@ -0,0 +1,5 @@ +select FormatType(LinearType(Int32)), + FormatType(DynamicLinearType(Int32)), + FormatType(ParseType('Linear<Int32>')), + FormatType(LinearItemType(LinearType(Int32))) + diff --git a/yql/essentials/tests/sql/suites/linear/types_reflection.yql b/yql/essentials/tests/sql/suites/linear/types_reflection.yql new file mode 100644 index 00000000000..9f63f82606e --- /dev/null +++ b/yql/essentials/tests/sql/suites/linear/types_reflection.yql @@ -0,0 +1,6 @@ +select TypeKind(TypeHandle(LinearType(Int32))), + TypeKind(TypeHandle(DynamicLinearType(Int32))), + FormatType(EvaluateType(TypeHandle(LinearType(Int32)))), + FormatType(LinearTypeHandle(TypeHandle(Int32))), + FormatType(DynamicLinearTypeHandle(TypeHandle(Int32))), + FormatType(LinearItemType(TypeHandle(LinearType(Int32)))); diff --git a/yt/yql/providers/yt/lib/row_spec/yql_row_spec.cpp b/yt/yql/providers/yt/lib/row_spec/yql_row_spec.cpp index 3e5bf28c6ac..c44241ddf62 100644 --- a/yt/yql/providers/yt/lib/row_spec/yql_row_spec.cpp +++ b/yt/yql/providers/yt/lib/row_spec/yql_row_spec.cpp @@ -114,6 +114,8 @@ ui64 GetNativeYtTypeFlagsImpl(const TTypeAnnotationNode* itemType) { case ETypeAnnotationKind::Type: case ETypeAnnotationKind::Block: case ETypeAnnotationKind::Scalar: + case ETypeAnnotationKind::Linear: + case ETypeAnnotationKind::DynamicLinear: case ETypeAnnotationKind::LastType: break; } |
