aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/public/purecalc/common/transformations/root_to_blocks.cpp
blob: 07c959d1077c79fb67cdc2a308c55a8d008f31f0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include "root_to_blocks.h"

#include <yql/essentials/public/purecalc/common/transformations/utils.h>

#include <yql/essentials/core/yql_expr_type_annotation.h>

using namespace NYql;
using namespace NYql::NPureCalc;

namespace {

class TRootToBlocks: public TSyncTransformerBase {
private:
    bool AcceptsBlocks_;
    EProcessorMode ProcessorMode_;
    bool Wrapped_;

public:
    explicit TRootToBlocks(bool acceptsBlocks, EProcessorMode processorMode)
        : AcceptsBlocks_(acceptsBlocks)
        , ProcessorMode_(processorMode)
        , Wrapped_(false)
    {
    }

public:
    void Rewind() override {
        Wrapped_ = false;
    }

    TStatus DoTransform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
        if (Wrapped_ || !AcceptsBlocks_) {
            return IGraphTransformer::TStatus::Ok;
        }

        const TTypeAnnotationNode* returnItemType;
        const TTypeAnnotationNode* returnType = input->GetTypeAnn();
        if (ProcessorMode_ == EProcessorMode::PullList) {
            Y_ENSURE(returnType->GetKind() == ETypeAnnotationKind::List);
            returnItemType = returnType->Cast<TListExprType>()->GetItemType();
        } else {
            Y_ENSURE(returnType->GetKind() == ETypeAnnotationKind::Stream);
            returnItemType = returnType->Cast<TStreamExprType>()->GetItemType();
        }

        Y_ENSURE(returnItemType->GetKind() == ETypeAnnotationKind::Struct);
        const TStructExprType* structType = returnItemType->Cast<TStructExprType>();
        const auto blocksLambda = NodeToBlocks(input->Pos(), structType, ctx);
        bool wrapLMap = ProcessorMode_ == EProcessorMode::PullList;
        output = ApplyToIterable(input->Pos(), input, blocksLambda, wrapLMap, ctx);

        Wrapped_ = true;

        return IGraphTransformer::TStatus(IGraphTransformer::TStatus::Repeat, true);
    }
};

} // namespace

TAutoPtr<IGraphTransformer> NYql::NPureCalc::MakeRootToBlocks(
    bool acceptsBlocks,
    EProcessorMode processorMode
) {
    return new TRootToBlocks(acceptsBlocks, processorMode);
}