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
|