summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvvvv <[email protected]>2025-09-18 12:35:25 +0300
committervvvv <[email protected]>2025-09-18 12:48:14 +0300
commitf5a6d6cdfb9d7c44659f134a53c2fa273ec85599 (patch)
tree5cc206b17db5fa8f976ea922c997095a1d133687
parente2dc5e15bc02bff63e44ed9c74ff1093d87d845b (diff)
YQL-20339 expr types & reflection
init commit_hash:1c72053b3785a26cfde418f28a9d054b5a624627
-rw-r--r--yql/essentials/ast/yql_expr.cpp64
-rw-r--r--yql/essentials/ast/yql_expr.h83
-rw-r--r--yql/essentials/ast/yql_expr_types.h4
-rw-r--r--yql/essentials/ast/yql_type_string.cpp47
-rw-r--r--yql/essentials/core/type_ann/type_ann_core.cpp79
-rw-r--r--yql/essentials/core/type_ann/type_ann_types.cpp203
-rw-r--r--yql/essentials/core/type_ann/type_ann_types.h9
-rw-r--r--yql/essentials/core/yql_default_valid_value.cpp20
-rw-r--r--yql/essentials/core/yql_expr_type_annotation.cpp14
-rw-r--r--yql/essentials/data/language/sql_functions.json16
-rw-r--r--yql/essentials/providers/common/comp_nodes/yql_factory.cpp3
-rw-r--r--yql/essentials/providers/common/comp_nodes/yql_maketype.cpp30
-rw-r--r--yql/essentials/providers/common/comp_nodes/yql_splittype.cpp17
-rw-r--r--yql/essentials/providers/common/mkql/yql_provider_mkql.cpp3
-rw-r--r--yql/essentials/providers/common/mkql/yql_type_mkql.cpp28
-rw-r--r--yql/essentials/providers/common/schema/expr/yql_expr_schema.cpp12
-rw-r--r--yql/essentials/providers/common/schema/mkql/yql_mkql_schema.cpp6
-rw-r--r--yql/essentials/providers/common/schema/parser/yql_type_parser.h38
-rw-r--r--yql/essentials/providers/common/schema/skiff/yql_skiff_schema.cpp6
-rw-r--r--yql/essentials/sql/v1/builtin.cpp5
-rw-r--r--yql/essentials/tests/sql/minirun/part6/canondata/result.json14
-rw-r--r--yql/essentials/tests/sql/minirun/part9/canondata/result.json14
-rw-r--r--yql/essentials/tests/sql/sql2yql/canondata/result.json24
-rw-r--r--yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_linear-types_/formatted.sql6
-rw-r--r--yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_linear-types_reflection_/formatted.sql8
-rw-r--r--yql/essentials/tests/sql/suites/linear/default.cfg2
-rw-r--r--yql/essentials/tests/sql/suites/linear/types.yql5
-rw-r--r--yql/essentials/tests/sql/suites/linear/types_reflection.yql6
-rw-r--r--yt/yql/providers/yt/lib/row_spec/yql_row_spec.cpp2
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;
}