aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/core/extract_predicate/extract_predicate_dbg.cpp
blob: 19bb1fd14fe83276336827654ab5d47f470fa2c4 (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
#include "extract_predicate_dbg.h"
#include "extract_predicate.h"

#include <yql/essentials/utils/log/log.h>
#include <yql/essentials/core/yql_expr_optimize.h>
#include <yql/essentials/core/yql_expr_type_annotation.h>

namespace NYql {
namespace {

TExprNode::TPtr ExpandRangeComputeFor(const TExprNode::TPtr& node, TExprContext& ctx,
    const TIntrusivePtr<TTypeAnnotationContext>& typesCtx)
{
    if (!node->IsCallable("RangeComputeFor")) {
        return node;
    }

    YQL_CLOG(DEBUG, Core) << "Expanding " << node->Content();

    TPositionHandle pos = node->Pos();
    TExprNode::TPtr result = ctx.NewCallable(pos, "Nothing", { ExpandType(pos, *node->GetTypeAnn(), ctx) });

    TPredicateExtractorSettings settings;
    settings.HaveNextValueCallable = true;
    auto extractor = MakePredicateRangeExtractor(settings);
    YQL_ENSURE(extractor);

    TVector<TString> indexKeys;
    for (auto& key : node->Tail().ChildrenList()) {
        YQL_ENSURE(key->IsAtom());
        indexKeys.push_back(ToString(key->Content()));
    }

    THashSet<TString> possibleKeys;
    if (!extractor->Prepare(node->ChildPtr(1), *node->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType(), possibleKeys, ctx, *typesCtx)) {
        YQL_CLOG(DEBUG, Core) << "Prepare: ranges can not be built for predicate";
        return result;
    }

    if (AllOf(indexKeys, [&possibleKeys](const TString& key) { return !possibleKeys.contains(key); })) {
        YQL_CLOG(DEBUG, Core) << "No intersection between possible range keys and actual keys";
        return result;
    }


    auto buildResult = extractor->BuildComputeNode(indexKeys, ctx, *typesCtx);
    if (!buildResult.ComputeNode) {
        YQL_CLOG(DEBUG, Core) << "BuildComputeNode: ranges can not be built for predicate";
        return result;
    }

    TString prunedLambdaSerialized;
    {
        auto ast = ConvertToAst(*buildResult.PrunedLambda, ctx, TExprAnnotationFlags::None, true);
        YQL_ENSURE(ast.Root);
        prunedLambdaSerialized = "__yql_ast:" + ast.Root->ToString(TAstPrintFlags::PerLine | TAstPrintFlags::ShortQuote);
    }

    result = ctx.Builder(pos)
        .Callable("Just")
            .List(0)
                .Add(0, buildResult.ComputeNode)
                .Callable(1, "AsTagged")
                    .Callable(0, "String")
                        .Atom(0, prunedLambdaSerialized)
                    .Seal()
                    .Atom(1, "AST", TNodeFlags::Default)
                .Seal()
            .Seal()
        .Seal()
        .Build();

    return result;
}

} // namespace

THolder<IGraphTransformer> MakeExpandRangeComputeForTransformer(const TIntrusivePtr<TTypeAnnotationContext>& types) {
    return CreateFunctorTransformer(
        [types](const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
            TOptimizeExprSettings settings(types.Get());
            settings.CustomInstantTypeTransformer = types->CustomInstantTypeTransformer.Get();
            using namespace std::placeholders;
            return OptimizeExpr(input, output, std::bind(&ExpandRangeComputeFor, _1, _2, types), ctx, settings);
        }
    );
}

} // namespace NYql