@@ -148,12 +148,29 @@ bool IsNullRejectingPredicate(const TFilterInfo &filter, TExprContext &ctx) {
148148
149149std::shared_ptr<TOpCBOTree> JoinCBOTrees (std::shared_ptr<TOpCBOTree> & left, std::shared_ptr<TOpCBOTree> & right, std::shared_ptr<TOpJoin> &join) {
150150 auto newJoin = std::make_shared<TOpJoin>(left->TreeRoot , right->TreeRoot , join->Pos , join->JoinKind , join->JoinKeys );
151- auto newTree = std::make_shared<TOpCBOTree>(newJoin, newJoin->Pos );
152- newTree->TreeNodes = left->TreeNodes ;
153- newTree->TreeNodes .insert (newTree->TreeNodes .end (), right->TreeNodes .begin (), right->TreeNodes .end ());
154- newTree->Children = left->Children ;
155- newTree->Children .insert (newTree->Children .end (), right->Children .begin (), right->Children .end ());
156- return newTree;
151+
152+ auto treeNodes = left->TreeNodes ;
153+ treeNodes.insert (treeNodes.end (), right->TreeNodes .begin (), right->TreeNodes .end ());
154+ treeNodes.push_back (newJoin);
155+
156+ return std::make_shared<TOpCBOTree>(newJoin, treeNodes, newJoin->Pos );
157+ }
158+
159+ std::shared_ptr<TOpCBOTree> AddJoinToCBOTree (std::shared_ptr<TOpCBOTree> & cboTree, std::shared_ptr<TOpJoin> &join) {
160+ TVector<std::shared_ptr<IOperator>> treeNodes;
161+
162+ if (join->GetLeftInput () == cboTree) {
163+ join->SetLeftInput (cboTree->TreeRoot );
164+ treeNodes.insert (treeNodes.end (), cboTree->TreeNodes .begin (), cboTree->TreeNodes .end ());
165+ treeNodes.push_back (join);
166+ }
167+ else {
168+ join->SetRightInput (cboTree->TreeRoot );
169+ treeNodes.push_back (join);
170+ treeNodes.insert (treeNodes.end (), cboTree->TreeNodes .begin (), cboTree->TreeNodes .end ());
171+ }
172+
173+ return std::make_shared<TOpCBOTree>(join, treeNodes, join->Pos );
157174}
158175
159176void ExtractConjuncts (TExprNode::TPtr node, TVector<TExprNode::TPtr> & conjuncts) {
@@ -344,7 +361,7 @@ bool TExtractJoinExpressionsRule::TestAndApply(std::shared_ptr<IOperator> &input
344361 filter->FilterLambda = newFilterLambda;
345362
346363 auto newMap = std::make_shared<TOpMap>(filter->GetInput (), input->Pos , mapElements, false );
347- filter->Children [ 0 ] = newMap;
364+ filter->SetInput ( newMap) ;
348365 return true ;
349366 }
350367
@@ -396,7 +413,7 @@ bool TInlineScalarSubplanRule::TestAndApply(std::shared_ptr<IOperator> &input, T
396413
397414 TVector<std::pair<TInfoUnit,TInfoUnit>> joinKeys;
398415 auto cross = std::make_shared<TOpJoin>(child, limit, subplan->Pos , " Cross" , joinKeys);
399- unaryOp->Children [ 0 ] = cross;
416+ unaryOp->SetInput ( cross) ;
400417
401418 props.ScalarSubplans .Remove (scalarIU);
402419
@@ -474,12 +491,12 @@ std::shared_ptr<IOperator> TPushMapRule::SimpleTestAndApply(const std::shared_pt
474491
475492 if (leftMapElements.size ()) {
476493 auto leftInput = join->GetLeftInput ();
477- join->Children [ 0 ] = std::make_shared<TOpMap>(leftInput, input->Pos , leftMapElements, false );
494+ join->SetLeftInput ( std::make_shared<TOpMap>(leftInput, input->Pos , leftMapElements, false ) );
478495 }
479496
480497 if (rightMapElements.size ()) {
481498 auto rightInput = join->GetRightInput ();
482- join->Children [ 1 ] = std::make_shared<TOpMap>(rightInput, input->Pos , rightMapElements, false );
499+ join->SetRightInput ( std::make_shared<TOpMap>(rightInput, input->Pos , rightMapElements, false ) );
483500 }
484501
485502 // If there was an enforcer on the input map, move it to the output
@@ -601,8 +618,8 @@ std::shared_ptr<IOperator> TPushFilterRule::SimpleTestAndApply(const std::shared
601618 join->JoinKind = " Inner" ;
602619 }
603620
604- join->Children [ 0 ] = leftInput;
605- join->Children [ 1 ] = rightInput;
621+ join->SetLeftInput ( leftInput) ;
622+ join->SetRightInput ( rightInput) ;
606623
607624 if (topLevelPreds.size ()) {
608625 auto topFilterLambda = BuildFilterLambdaFromConjuncts (join->Pos , topLevelPreds, ctx.ExprCtx , props.PgSyntax );
@@ -669,46 +686,54 @@ std::shared_ptr<IOperator> TExpandCBOTreeRule::SimpleTestAndApply(const std::sha
669686
670687 bool leftSideCBOTree = true ;
671688
672- if (leftInput->Kind == EOperator::CBOTree) {
673- cboTree = CastOperator<TOpCBOTree>(leftInput);
674- }
675- else if (leftInput->Kind == EOperator::Filter &&
676- CastOperator<TOpFilter>(leftInput)->GetInput ()->Kind == EOperator::CBOTree &&
677- join->JoinKind == " Inner" ) {
678- maybeFilter = CastOperator<TOpFilter>(leftInput);
679- cboTree = CastOperator<TOpCBOTree>(maybeFilter->GetInput ());
680- }
681- else if (rightInput->Kind == EOperator::CBOTree) {
682- cboTree = CastOperator<TOpCBOTree>(rightInput);
683- leftSideCBOTree = false ;
684- }
685- else if (rightInput->Kind == EOperator::Filter &&
686- CastOperator<TOpFilter>(rightInput)->GetInput ()->Kind == EOperator::CBOTree &&
687- join->JoinKind == " Inner" ) {
688- maybeFilter = CastOperator<TOpFilter>(rightInput);
689- cboTree = CastOperator<TOpCBOTree>(maybeFilter->GetInput ());
690- leftSideCBOTree = false ;
691- }
692- else {
693- return input;
689+ auto findCBOTree = [&join](const std::shared_ptr<IOperator>& op,
690+ std::shared_ptr<TOpCBOTree>& cboTree,
691+ std::shared_ptr<TOpFilter>& maybeFilter) {
692+
693+ if (op->Kind == EOperator::CBOTree) {
694+ cboTree = CastOperator<TOpCBOTree>(op);
695+ return true ;
696+ }
697+ if (op->Kind == EOperator::Filter &&
698+ CastOperator<TOpFilter>(op)->GetInput ()->Kind == EOperator::CBOTree &&
699+ join->JoinKind == " Inner" ) {
700+
701+ maybeFilter = CastOperator<TOpFilter>(op);
702+ cboTree = CastOperator<TOpCBOTree>(maybeFilter->GetInput ());
703+ return true ;
704+ }
705+
706+ return false ;
707+ };
708+
709+ if (!findCBOTree (leftInput, cboTree, maybeFilter)) {
710+ if (!findCBOTree (rightInput, cboTree, maybeFilter)) {
711+ return input;
712+ } else {
713+ leftSideCBOTree = true ;
714+ }
694715 }
695716
696717 std::shared_ptr<TOpFilter> maybeAnotherFilter;
697718 auto otherSide = leftSideCBOTree ? join->GetRightInput () : join->GetLeftInput ();
698719 std::shared_ptr<TOpCBOTree> otherSideCBOTree;
699720
700721 if (otherSide->Kind == EOperator::Filter &&
701- CastOperator<TOpFilter>(otherSide)->GetInput ()->Kind == EOperator::CBOTree) {
722+ CastOperator<TOpFilter>(otherSide)->GetInput ()->Kind == EOperator::CBOTree &&
723+ join->JoinKind == " Inner" ) {
724+
702725 maybeAnotherFilter = CastOperator<TOpFilter>(otherSide);
703726 otherSideCBOTree = CastOperator<TOpCBOTree>(maybeAnotherFilter->GetInput ());
704- } else {
705- otherSideCBOTree = std::make_shared<TOpCBOTree>(otherSide, otherSide->Pos );
706727 }
707728
708- if (leftSideCBOTree) {
709- cboTree = JoinCBOTrees (cboTree, otherSideCBOTree, join);
729+ if (otherSideCBOTree) {
730+ if (leftSideCBOTree) {
731+ cboTree = JoinCBOTrees (cboTree, otherSideCBOTree, join);
732+ } else {
733+ cboTree = JoinCBOTrees (otherSideCBOTree, cboTree, join);
734+ }
710735 } else {
711- cboTree = JoinCBOTrees (otherSideCBOTree, cboTree, join);
736+ cboTree = AddJoinToCBOTree ( cboTree, join);
712737 }
713738
714739 if (maybeFilter && maybeAnotherFilter) {
@@ -718,7 +743,7 @@ std::shared_ptr<IOperator> TExpandCBOTreeRule::SimpleTestAndApply(const std::sha
718743 }
719744
720745 if (maybeFilter) {
721- maybeFilter->Children [ 0 ] = cboTree;
746+ maybeFilter->SetInput ( cboTree) ;
722747 return maybeFilter;
723748 } else {
724749 return cboTree;
@@ -810,7 +835,7 @@ bool TAssignStagesRule::TestAndApply(std::shared_ptr<IOperator> &input, TRBOCont
810835 }
811836 YQL_CLOG (TRACE, CoreDq) << " Assign stages join" ;
812837 } else if (input->Kind == EOperator::Filter || input->Kind == EOperator::Map) {
813- auto childOp = input-> Children [ 0 ] ;
838+ auto childOp = CastOperator<IUnaryOperator>( input)-> GetInput () ;
814839 auto prevStageId = *(childOp->Props .StageId );
815840
816841 // If the child operator is a source, it requires its own stage
0 commit comments