@@ -12,31 +12,6 @@ namespace NYql {
12
12
13
13
namespace {
14
14
15
- bool AreSimilarTrees (TYtJoinNode::TPtr node1, TYtJoinNode::TPtr node2) {
16
- if (node1 == node2) {
17
- return true ;
18
- }
19
- if (node1 && !node2) {
20
- return false ;
21
- }
22
- if (node2 && !node1) {
23
- return false ;
24
- }
25
- if (node1->Scope != node2->Scope ) {
26
- return false ;
27
- }
28
- auto opLeft = dynamic_cast <TYtJoinNodeOp*>(node1.Get ());
29
- auto opRight = dynamic_cast <TYtJoinNodeOp*>(node2.Get ());
30
- if (opLeft && opRight) {
31
- return AreSimilarTrees (opLeft->Left , opRight->Left )
32
- && AreSimilarTrees (opLeft->Right , opRight->Right );
33
- } else if (!opLeft && !opRight) {
34
- return true ;
35
- } else {
36
- return false ;
37
- }
38
- }
39
-
40
15
void DebugPrint (TYtJoinNode::TPtr node, TExprContext& ctx, int level) {
41
16
auto * op = dynamic_cast <TYtJoinNodeOp*>(node.Get ());
42
17
auto printScope = [](const TVector<TString>& scope) -> TString {
@@ -409,6 +384,16 @@ class TJoinReorderer {
409
384
IOptimizer::TOutput Result;
410
385
};
411
386
387
+ class TYtRelOptimizerNode : public TRelOptimizerNode {
388
+ public:
389
+ TYtRelOptimizerNode (TString label, std::shared_ptr<TOptimizerStatistics> stats, TYtJoinNodeLeaf* leaf)
390
+ : TRelOptimizerNode(std::move(label), std::move(stats))
391
+ , OriginalLeaf(leaf)
392
+ { }
393
+
394
+ TYtJoinNodeLeaf* OriginalLeaf;
395
+ };
396
+
412
397
class TOptimizerTreeBuilder
413
398
{
414
399
public:
@@ -487,8 +472,8 @@ class TOptimizerTreeBuilder
487
472
}
488
473
}
489
474
490
- return std::make_shared<TRelOptimizerNode >(
491
- std::move (label), std::move (stat)
475
+ return std::make_shared<TYtRelOptimizerNode >(
476
+ std::move (label), std::move (stat), leaf
492
477
);
493
478
}
494
479
@@ -498,13 +483,80 @@ class TOptimizerTreeBuilder
498
483
TYtJoinNodeOp::TPtr InputTree;
499
484
};
500
485
486
+ TYtJoinNode::TPtr BuildYtJoinTree (std::shared_ptr<IBaseOptimizerNode> node, TVector<TString>& scope, TExprContext& ctx, TPositionHandle pos) {
487
+ if (node->Kind == RelNodeType) {
488
+ auto * leaf = static_cast <TYtRelOptimizerNode*>(node.get ())->OriginalLeaf ;
489
+ scope.insert (scope.end (), leaf->Scope .begin (), leaf->Scope .end ());
490
+ return leaf;
491
+ } else if (node->Kind == JoinNodeType) {
492
+ auto ret = MakeIntrusive<TYtJoinNodeOp>();
493
+ auto * op = static_cast <TJoinOptimizerNode*>(node.get ());
494
+ ret->JoinKind = ctx.NewAtom (pos, ConvertToJoinString (op->JoinType ));
495
+ TVector<TExprNodePtr> leftLabel, rightLabel;
496
+ leftLabel.reserve (op->JoinConditions .size () * 2 );
497
+ rightLabel.reserve (op->JoinConditions .size () * 2 );
498
+ for (auto & [left, right] : op->JoinConditions ) {
499
+ leftLabel.emplace_back (ctx.NewAtom (pos, left.RelName ));
500
+ leftLabel.emplace_back (ctx.NewAtom (pos, left.AttributeName ));
501
+
502
+ rightLabel.emplace_back (ctx.NewAtom (pos, right.RelName ));
503
+ rightLabel.emplace_back (ctx.NewAtom (pos, right.AttributeName ));
504
+ }
505
+ ret->LeftLabel = Build<TCoAtomList>(ctx, pos)
506
+ .Add (leftLabel)
507
+ .Done ()
508
+ .Ptr ();
509
+ ret->RightLabel = Build<TCoAtomList>(ctx, pos)
510
+ .Add (rightLabel)
511
+ .Done ()
512
+ .Ptr ();
513
+ int index = scope.size ();
514
+ ret->Left = BuildYtJoinTree (op->LeftArg , scope, ctx, pos);
515
+ ret->Right = BuildYtJoinTree (op->RightArg , scope, ctx, pos);
516
+ ret->Scope .insert (ret->Scope .end (), scope.begin () + index , scope.end ());
517
+ return ret;
518
+ } else {
519
+ YQL_ENSURE (false , " Unknown node type" );
520
+ }
521
+ }
522
+
501
523
} // namespace
502
524
525
+ bool AreSimilarTrees (TYtJoinNode::TPtr node1, TYtJoinNode::TPtr node2) {
526
+ if (node1 == node2) {
527
+ return true ;
528
+ }
529
+ if (node1 && !node2) {
530
+ return false ;
531
+ }
532
+ if (node2 && !node1) {
533
+ return false ;
534
+ }
535
+ if (node1->Scope != node2->Scope ) {
536
+ return false ;
537
+ }
538
+ auto opLeft = dynamic_cast <TYtJoinNodeOp*>(node1.Get ());
539
+ auto opRight = dynamic_cast <TYtJoinNodeOp*>(node2.Get ());
540
+ if (opLeft && opRight) {
541
+ return AreSimilarTrees (opLeft->Left , opRight->Left )
542
+ && AreSimilarTrees (opLeft->Right , opRight->Right );
543
+ } else if (!opLeft && !opRight) {
544
+ return true ;
545
+ } else {
546
+ return false ;
547
+ }
548
+ }
549
+
503
550
void BuildOptimizerJoinTree (std::shared_ptr<IBaseOptimizerNode>& tree, std::shared_ptr<IProviderContext>& ctx, TYtJoinNodeOp::TPtr op)
504
551
{
505
552
TOptimizerTreeBuilder (tree, ctx, op).Do ();
506
553
}
507
554
555
+ TYtJoinNode::TPtr BuildYtJoinTree (std::shared_ptr<IBaseOptimizerNode> node, TExprContext& ctx, TPositionHandle pos) {
556
+ TVector<TString> scope;
557
+ return BuildYtJoinTree (node, scope, ctx, pos);
558
+ }
559
+
508
560
TYtJoinNodeOp::TPtr OrderJoins (TYtJoinNodeOp::TPtr op, const TYtState::TPtr& state, TExprContext& ctx, bool debug)
509
561
{
510
562
if (state->Types ->CostBasedOptimizer == ECostBasedOptimizerType::Disable) {
0 commit comments