|
4 | 4 | #include <ydb/library/yql/parser/pg_wrapper/interface/optimizer.h>
|
5 | 5 | #include <ydb/library/yql/providers/common/provider/yql_provider.h>
|
6 | 6 | #include <ydb/library/yql/utils/log/log.h>
|
| 7 | +#include <ydb/library/yql/core/cbo/cbo_optimizer_new.h> |
7 | 8 |
|
8 | 9 | #include <ydb/library/yql/dq/opt/dq_opt_log.h>
|
9 | 10 |
|
@@ -408,8 +409,102 @@ class TJoinReorderer {
|
408 | 409 | IOptimizer::TOutput Result;
|
409 | 410 | };
|
410 | 411 |
|
| 412 | +class TOptimizerTreeBuilder |
| 413 | +{ |
| 414 | +public: |
| 415 | + TOptimizerTreeBuilder(std::shared_ptr<IBaseOptimizerNode>& tree, std::shared_ptr<IProviderContext>& ctx, TYtJoinNodeOp::TPtr inputTree) |
| 416 | + : Tree(tree) |
| 417 | + , Ctx(ctx) |
| 418 | + , InputTree(inputTree) |
| 419 | + { } |
| 420 | + |
| 421 | + void Do() { |
| 422 | + Ctx = std::make_shared<TDummyProviderContext>(); |
| 423 | + Tree = ProcessNode(InputTree); |
| 424 | + } |
| 425 | + |
| 426 | +private: |
| 427 | + std::shared_ptr<IBaseOptimizerNode> ProcessNode(TYtJoinNode::TPtr node) { |
| 428 | + if (auto* op = dynamic_cast<TYtJoinNodeOp*>(node.Get())) { |
| 429 | + return OnOp(op); |
| 430 | + } else if (auto* leaf = dynamic_cast<TYtJoinNodeLeaf*>(node.Get())) { |
| 431 | + return OnLeaf(leaf); |
| 432 | + } else { |
| 433 | + YQL_ENSURE("Unknown node type"); |
| 434 | + return nullptr; |
| 435 | + } |
| 436 | + } |
| 437 | + |
| 438 | + std::shared_ptr<IBaseOptimizerNode> OnOp(TYtJoinNodeOp* op) { |
| 439 | + auto joinKind = ConvertToJoinKind(TString(op->JoinKind->Content())); |
| 440 | + auto left = ProcessNode(op->Left); |
| 441 | + auto right = ProcessNode(op->Right); |
| 442 | + YQL_ENSURE(op->LeftLabel->ChildrenSize() == op->RightLabel->ChildrenSize()); |
| 443 | + std::set<std::pair<NDq::TJoinColumn, NDq::TJoinColumn>> joinConditions; |
| 444 | + for (ui32 i = 0; i < op->LeftLabel->ChildrenSize(); i += 2) { |
| 445 | + auto ltable = op->LeftLabel->Child(i)->Content(); |
| 446 | + auto lcolumn = op->LeftLabel->Child(i + 1)->Content(); |
| 447 | + auto rtable = op->RightLabel->Child(i)->Content(); |
| 448 | + auto rcolumn = op->RightLabel->Child(i + 1)->Content(); |
| 449 | + NDq::TJoinColumn lcol{TString(ltable), TString(lcolumn)}; |
| 450 | + NDq::TJoinColumn rcol{TString(rtable), TString(rcolumn)}; |
| 451 | + joinConditions.insert({lcol, rcol}); |
| 452 | + } |
| 453 | + |
| 454 | + return std::make_shared<TJoinOptimizerNode>( |
| 455 | + left, right, joinConditions, joinKind, EJoinAlgoType::GraceJoin |
| 456 | + ); |
| 457 | + } |
| 458 | + |
| 459 | + std::shared_ptr<IBaseOptimizerNode> OnLeaf(TYtJoinNodeLeaf* leaf) { |
| 460 | + TString label; |
| 461 | + if (leaf->Label->ChildrenSize() == 0) { |
| 462 | + label = leaf->Label->Content(); |
| 463 | + } else { |
| 464 | + for (ui32 i = 0; i < leaf->Label->ChildrenSize(); ++i) { |
| 465 | + label += leaf->Label->Child(i)->Content(); |
| 466 | + if (i+1 != leaf->Label->ChildrenSize()) { |
| 467 | + label += ","; |
| 468 | + } |
| 469 | + } |
| 470 | + } |
| 471 | + |
| 472 | + TYtSection section{leaf->Section}; |
| 473 | + auto stat = std::make_shared<TOptimizerStatistics>(); |
| 474 | + if (Y_UNLIKELY(!section.Settings().Empty()) && Y_UNLIKELY(section.Settings().Item(0).Name() == "Test")) { |
| 475 | + for (const auto& setting : section.Settings()) { |
| 476 | + if (setting.Name() == "Rows") { |
| 477 | + stat->Nrows += FromString<ui64>(setting.Value().Ref().Content()); |
| 478 | + } else if (setting.Name() == "Size") { |
| 479 | + stat->Cost += FromString<ui64>(setting.Value().Ref().Content()); |
| 480 | + } |
| 481 | + } |
| 482 | + } else { |
| 483 | + for (auto path: section.Paths()) { |
| 484 | + auto tableStat = TYtTableBaseInfo::GetStat(path.Table()); |
| 485 | + stat->Cost += tableStat->DataSize; |
| 486 | + stat->Nrows += tableStat->RecordsCount; |
| 487 | + } |
| 488 | + } |
| 489 | + |
| 490 | + return std::make_shared<TRelOptimizerNode>( |
| 491 | + std::move(label), std::move(stat) |
| 492 | + ); |
| 493 | + } |
| 494 | + |
| 495 | + std::shared_ptr<IBaseOptimizerNode>& Tree; |
| 496 | + std::shared_ptr<IProviderContext>& Ctx; |
| 497 | + |
| 498 | + TYtJoinNodeOp::TPtr InputTree; |
| 499 | +}; |
| 500 | + |
411 | 501 | } // namespace
|
412 | 502 |
|
| 503 | +void BuildOptimizerJoinTree(std::shared_ptr<IBaseOptimizerNode>& tree, std::shared_ptr<IProviderContext>& ctx, TYtJoinNodeOp::TPtr op) |
| 504 | +{ |
| 505 | + TOptimizerTreeBuilder(tree, ctx, op).Do(); |
| 506 | +} |
| 507 | + |
413 | 508 | TYtJoinNodeOp::TPtr OrderJoins(TYtJoinNodeOp::TPtr op, const TYtState::TPtr& state, TExprContext& ctx, bool debug)
|
414 | 509 | {
|
415 | 510 | if (state->Types->CostBasedOptimizer == ECostBasedOptimizerType::Disable) {
|
|
0 commit comments