aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/providers/common/transform/yql_exec.cpp
blob: 6128cf211d9535f5ef39e4382b5271b90e6d6ddb (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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include "yql_exec.h"

#include <yql/essentials/core/yql_execution.h>
#include <yql/essentials/utils/log/log.h>
#include <yql/essentials/utils/yql_panic.h>

#include <util/string/builder.h>
#include <util/generic/vector.h>
#include <util/generic/string.h>


namespace NYql {

using namespace NNodes;

TExecTransformerBase::TStatusCallbackPair TExecTransformerBase::CallbackTransform(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
    YQL_ENSURE(input->Type() == TExprNode::Callable);
    output = input;
    if (auto handlerInfo = Handlers.FindPtr(input->Content())) {
        auto status = (handlerInfo->Prerequisite)(input);
        if (status.Level != TStatus::Ok) {
            return SyncStatus(status);
        }
        TString uniqId = TStringBuilder() << '#' << input->UniqueId();
        YQL_LOG_CTX_SCOPE(uniqId);

        return (handlerInfo->Handler)(input, output, ctx);
    }

    ctx.AddError(TIssue(ctx.GetPosition(input->Pos()), TStringBuilder() << "Don't know how to execute node: " << input->Content()));
    return SyncError();
}

void TExecTransformerBase::AddHandler(std::initializer_list<TStringBuf> names, TPrerequisite prerequisite, THandler handler) {
    THandlerInfo info;
    info.Handler = std::move(handler);
    info.Prerequisite = std::move(prerequisite);
    for (auto name: names) {
        YQL_ENSURE(Handlers.emplace(name, info).second, "Duplicate execution handler for " << name);
    }
}

TExecTransformerBase::THandler TExecTransformerBase::Pass() {
    return [] (const TExprNode::TPtr& input, TExprNode::TPtr& /*output*/, TExprContext& ctx) {
        return ExecPass(input, ctx);
    };
}

TExecTransformerBase::TStatusCallbackPair TExecTransformerBase::ExecPass(const TExprNode::TPtr& input, TExprContext& ctx) {
    input->SetState(TExprNode::EState::ExecutionComplete);
    input->SetResult(ctx.NewWorld(input->Pos()));
    return SyncOk();
}

TExecTransformerBase::TPrerequisite TExecTransformerBase::RequireAll() {
    return [] (const TExprNode::TPtr& input) {
        TStatus combinedStatus = TStatus::Ok;
        for (size_t i = 0; i < input->ChildrenSize(); ++i) {
            combinedStatus = combinedStatus.Combine(RequireChild(*input, (ui32)i));
        }
        return combinedStatus;
    };
}

TExecTransformerBase::TPrerequisite TExecTransformerBase::RequireNone() {
    return [] (const TExprNode::TPtr& /*input*/) {
        return TStatus::Ok;
    };
}

TExecTransformerBase::TPrerequisite TExecTransformerBase::RequireFirst() {
    return [] (const TExprNode::TPtr& input) {
        return RequireChild(*input, 0);
    };
}

TExecTransformerBase::TPrerequisite TExecTransformerBase::RequireAllOf(std::initializer_list<size_t> children) {
    return [required = TVector<size_t>(children)] (const TExprNode::TPtr& input) {
        TStatus combinedStatus = TStatus::Ok;
        for (size_t i: required) {
            YQL_ENSURE(i < input->ChildrenSize());
            combinedStatus = combinedStatus.Combine(RequireChild(*input, (ui32)i));
        }
        return combinedStatus;
    };
}

TExecTransformerBase::TPrerequisite TExecTransformerBase::RequireSequenceOf(std::initializer_list<size_t> children) {
    return [required = TVector<size_t>(children)] (const TExprNode::TPtr& input) -> TStatus {
        for (size_t i: required) {
            YQL_ENSURE(i < input->ChildrenSize());
            auto status = RequireChild(*input, (ui32)i);
            if (status.Level != TStatus::Ok) {
                return status;
            }
        }
        return TStatus::Ok;
    };
}

}