diff options
| -rw-r--r-- | ydb/library/yql/ast/yql_expr.cpp | 28 | ||||
| -rw-r--r-- | ydb/library/yql/ast/yql_expr.h | 39 | ||||
| -rw-r--r-- | ydb/library/yql/ast/yql_expr_types.h | 3 | ||||
| -rw-r--r-- | ydb/library/yql/ast/yql_type_string.cpp | 32 | ||||
| -rw-r--r-- | ydb/library/yql/ast/yql_type_string_ut.cpp | 4 | ||||
| -rw-r--r-- | ydb/library/yql/core/type_ann/type_ann_core.cpp | 1 | ||||
| -rw-r--r-- | ydb/library/yql/core/type_ann/type_ann_types.cpp | 21 |
7 files changed, 127 insertions, 1 deletions
diff --git a/ydb/library/yql/ast/yql_expr.cpp b/ydb/library/yql/ast/yql_expr.cpp index cfb9e11f6d4..da142ff5d3d 100644 --- a/ydb/library/yql/ast/yql_expr.cpp +++ b/ydb/library/yql/ast/yql_expr.cpp @@ -570,6 +570,17 @@ namespace { return nullptr; return Expr.MakeType<TBlockExprType>(r); + } else if (content == TStringBuf("ChunkedBlock")) { + if (node.GetChildrenCount() != 2) { + AddError(node, "Bad chunked block type annotation"); + return nullptr; + } + + auto r = CompileTypeAnnotationNode(*node.GetChild(1)); + if (!r) + return nullptr; + + return Expr.MakeType<TChunkedBlockExprType>(r); } else if (content == TStringBuf("Scalar")) { if (node.GetChildrenCount() != 2) { AddError(node, "Bad scalar type annotation"); @@ -837,6 +848,14 @@ namespace { return TAstNode::NewList(TPosition(), pool, self, itemType); } + case ETypeAnnotationKind::ChunkedBlock: + { + auto type = annotation.Cast<TChunkedBlockExprType>(); + auto self = TAstNode::NewLiteralAtom(TPosition(), TStringBuf("ChunkedBlock"), pool); + auto itemType = ConvertTypeAnnotationToAst(*type->GetItemType(), pool, refAtoms); + return TAstNode::NewList(TPosition(), pool, self, itemType); + } + case ETypeAnnotationKind::Scalar: { auto type = annotation.Cast<TScalarExprType>(); @@ -3372,6 +3391,15 @@ const TBlockExprType* TMakeTypeImpl<TBlockExprType>::Make(TExprContext& ctx, con return AddType<TBlockExprType>(ctx, hash, itemType); } +const TChunkedBlockExprType* TMakeTypeImpl<TChunkedBlockExprType>::Make(TExprContext& ctx, const TTypeAnnotationNode* itemType) { + const auto hash = TChunkedBlockExprType::MakeHash(itemType); + TChunkedBlockExprType sample(hash, itemType); + if (const auto found = FindType(sample, ctx)) + return found; + + return AddType<TChunkedBlockExprType>(ctx, hash, itemType); +} + const TScalarExprType* TMakeTypeImpl<TScalarExprType>::Make(TExprContext& ctx, const TTypeAnnotationNode* itemType) { const auto hash = TScalarExprType::MakeHash(itemType); TScalarExprType sample(hash, itemType); diff --git a/ydb/library/yql/ast/yql_expr.h b/ydb/library/yql/ast/yql_expr.h index 540f6ce7569..7ec95914503 100644 --- a/ydb/library/yql/ast/yql_expr.h +++ b/ydb/library/yql/ast/yql_expr.h @@ -80,6 +80,7 @@ class TFlowExprType; class TEmptyListExprType; class TEmptyDictExprType; class TBlockExprType; +class TChunkedBlockExprType; class TScalarExprType; const size_t DefaultMistypeDistance = 3; @@ -114,6 +115,7 @@ struct TTypeAnnotationVisitor { virtual void Visit(const TEmptyListExprType& type) = 0; virtual void Visit(const TEmptyDictExprType& type) = 0; virtual void Visit(const TBlockExprType& type) = 0; + virtual void Visit(const TChunkedBlockExprType& type) = 0; virtual void Visit(const TScalarExprType& type) = 0; }; @@ -652,6 +654,33 @@ private: const TTypeAnnotationNode* ItemType; }; +class TChunkedBlockExprType : public TTypeAnnotationNode { +public: + static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::ChunkedBlock; + + TChunkedBlockExprType(ui64 hash, const TTypeAnnotationNode* itemType) + : TTypeAnnotationNode(KindValue, itemType->GetFlags() | TypeNonPersistable, hash) + , ItemType(itemType) + { + } + + static ui64 MakeHash(const TTypeAnnotationNode* itemType) { + ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::ChunkedBlock; + return StreamHash(itemType->GetHash(), hash); + } + + const TTypeAnnotationNode* GetItemType() const { + return ItemType; + } + + bool operator==(const TChunkedBlockExprType& other) const { + return GetItemType() == other.GetItemType(); + } + +private: + const TTypeAnnotationNode* ItemType; +}; + class TScalarExprType : public TTypeAnnotationNode { public: static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Scalar; @@ -1356,6 +1385,9 @@ inline bool TTypeAnnotationNode::Equals(const TTypeAnnotationNode& node) const { case ETypeAnnotationKind::Block: return static_cast<const TBlockExprType&>(*this) == static_cast<const TBlockExprType&>(node); + case ETypeAnnotationKind::ChunkedBlock: + return static_cast<const TChunkedBlockExprType&>(*this) == static_cast<const TChunkedBlockExprType&>(node); + case ETypeAnnotationKind::Scalar: return static_cast<const TScalarExprType&>(*this) == static_cast<const TScalarExprType&>(node); @@ -1418,6 +1450,8 @@ inline void TTypeAnnotationNode::Accept(TTypeAnnotationVisitor& visitor) const { return visitor.Visit(static_cast<const TMultiExprType&>(*this)); case ETypeAnnotationKind::Block: return visitor.Visit(static_cast<const TBlockExprType&>(*this)); + case ETypeAnnotationKind::ChunkedBlock: + return visitor.Visit(static_cast<const TChunkedBlockExprType&>(*this)); case ETypeAnnotationKind::Scalar: return visitor.Visit(static_cast<const TScalarExprType&>(*this)); case ETypeAnnotationKind::LastType: @@ -2345,6 +2379,11 @@ struct TMakeTypeImpl<TBlockExprType> { }; template <> +struct TMakeTypeImpl<TChunkedBlockExprType> { + static const TChunkedBlockExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType); +}; + +template <> struct TMakeTypeImpl<TScalarExprType> { static const TScalarExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType); }; diff --git a/ydb/library/yql/ast/yql_expr_types.h b/ydb/library/yql/ast/yql_expr_types.h index bb628af2725..1c24e30e5e5 100644 --- a/ydb/library/yql/ast/yql_expr_types.h +++ b/ydb/library/yql/ast/yql_expr_types.h @@ -30,7 +30,8 @@ namespace NYql { xx(Multi, 23) \ xx(Pg, 24) \ xx(Block, 25) \ - xx(Scalar, 26) + xx(Scalar, 26) \ + xx(ChunkedBlock, 27) enum class ETypeAnnotationKind : ui64 { YQL_TYPE_ANN_KIND_MAP(ENUM_VALUE_GEN) diff --git a/ydb/library/yql/ast/yql_type_string.cpp b/ydb/library/yql/ast/yql_type_string.cpp index 33876d45ad0..cd51ac8283d 100644 --- a/ydb/library/yql/ast/yql_type_string.cpp +++ b/ydb/library/yql/ast/yql_type_string.cpp @@ -82,6 +82,7 @@ enum EToken TOKEN_DYNUMBER = -49, TOKEN_SCALAR = -50, TOKEN_BLOCK = -51, + TOKEN_CHUNKED_BLOCK = -52, // identifiers TOKEN_IDENTIFIER = -100, @@ -145,6 +146,7 @@ EToken TokenTypeFromStr(TStringBuf str) { TStringBuf("JsonDocument"), TOKEN_JSON_DOCUMENT }, { TStringBuf("DyNumber"), TOKEN_DYNUMBER }, { TStringBuf("Block"), TOKEN_BLOCK}, + { TStringBuf("ChunkedBlock"), TOKEN_CHUNKED_BLOCK}, { TStringBuf("Scalar"), TOKEN_SCALAR}, }; @@ -311,6 +313,10 @@ private: type = ParseBlockType(); break; + case TOKEN_CHUNKED_BLOCK: + type = ParseChunkedBlockType(); + break; + case TOKEN_SCALAR: type = ParseScalarType(); break; @@ -668,6 +674,17 @@ private: return MakeBlockType(itemType); } + TAstNode* ParseChunkedBlockType() { + GetNextToken(); // eat keyword + EXPECT_AND_SKIP_TOKEN('<', nullptr); + + auto itemType = ParseType(); + if (!itemType) return nullptr; + + EXPECT_AND_SKIP_TOKEN('>', nullptr); + return MakeChunkedBlockType(itemType); + } + TAstNode* ParseScalarType() { GetNextToken(); // eat keyword EXPECT_AND_SKIP_TOKEN('<', nullptr); @@ -932,6 +949,14 @@ private: return MakeList(items, Y_ARRAY_SIZE(items)); } + TAstNode* MakeChunkedBlockType(TAstNode* itemType) { + TAstNode* items[] = { + MakeLiteralAtom(TStringBuf("ChunkedBlockType")), + itemType, + }; + return MakeList(items, Y_ARRAY_SIZE(items)); + } + TAstNode* MakeScalarType(TAstNode* itemType) { TAstNode* items[] = { MakeLiteralAtom(TStringBuf("ScalarType")), @@ -1268,6 +1293,13 @@ private: Out_ << '>'; } + void Visit(const TChunkedBlockExprType& type) final { + TopLevel = false; + Out_ << TStringBuf("ChunkedBlock<"); + type.GetItemType()->Accept(*this); + Out_ << '>'; + } + void Visit(const TScalarExprType& type) final { TopLevel = false; Out_ << TStringBuf("Scalar<"); diff --git a/ydb/library/yql/ast/yql_type_string_ut.cpp b/ydb/library/yql/ast/yql_type_string_ut.cpp index 655d7a60910..15872412b2f 100644 --- a/ydb/library/yql/ast/yql_type_string_ut.cpp +++ b/ydb/library/yql/ast/yql_type_string_ut.cpp @@ -571,6 +571,10 @@ Y_UNIT_TEST_SUITE(TTypeString) TestFormat("((Block (Data String)))", "Block<String>"); } + Y_UNIT_TEST(FormatChunkedBlock) { + TestFormat("((ChunkedBlock (Data String)))", "ChunkedBlock<String>"); + } + Y_UNIT_TEST(FormatScalar) { TestFormat("((Scalar (Data String)))", "Scalar<String>"); } diff --git a/ydb/library/yql/core/type_ann/type_ann_core.cpp b/ydb/library/yql/core/type_ann/type_ann_core.cpp index 3a809f39715..92161f8f1ab 100644 --- a/ydb/library/yql/core/type_ann/type_ann_core.cpp +++ b/ydb/library/yql/core/type_ann/type_ann_core.cpp @@ -11476,6 +11476,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot> Functions["StreamType"] = &TypeWrapper<ETypeAnnotationKind::Stream>; Functions["FlowType"] = &TypeWrapper<ETypeAnnotationKind::Flow>; Functions["BlockType"] = &TypeWrapper<ETypeAnnotationKind::Block>; + Functions["ChunkedBlockType"] = &TypeWrapper<ETypeAnnotationKind::ChunkedBlock>; Functions["ScalarType"] = &TypeWrapper<ETypeAnnotationKind::Scalar>; Functions["Nothing"] = &NothingWrapper; Functions["AsOptionalType"] = &AsOptionalTypeWrapper; diff --git a/ydb/library/yql/core/type_ann/type_ann_types.cpp b/ydb/library/yql/core/type_ann/type_ann_types.cpp index f596a2f6c90..67db6223c1d 100644 --- a/ydb/library/yql/core/type_ann/type_ann_types.cpp +++ b/ydb/library/yql/core/type_ann/type_ann_types.cpp @@ -304,6 +304,27 @@ namespace NTypeAnnImpl { } template <> + IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::ChunkedBlock>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + Y_UNUSED(output); + 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<TChunkedBlockExprType>(itemType); + input->SetTypeAnn(ctx.Expr.MakeType<TTypeExprType>(type)); + return IGraphTransformer::TStatus::Ok; + } + + template <> IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Scalar>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { Y_UNUSED(output); if (!EnsureArgsCount(*input, 1, ctx.Expr)) { |
