@@ -5073,6 +5073,19 @@ TExprNode::TListType&& DropUnused(TExprNode::TListType&& list, const std::vector
5073
5073
return std::move (list);
5074
5074
}
5075
5075
5076
+ std::set<ui32> FillAllIndexes (const TTypeAnnotationNode& rowType) {
5077
+ std::set<ui32> set;
5078
+ for (ui32 i = 0U ; i < rowType.Cast <TMultiExprType>()->GetSize (); ++i)
5079
+ set.emplace (i);
5080
+ return set;
5081
+ }
5082
+
5083
+ template <bool EvenOnly>
5084
+ void RemoveUsedIndexes (const TExprNode& list, std::set<ui32>& unused) {
5085
+ for (auto i = 0U ; i < list.ChildrenSize () >> (EvenOnly ? 1U : 0U ); ++i)
5086
+ unused.erase (FromString<ui32>(list.Child (EvenOnly ? i << 1U : i)->Content ()));
5087
+ }
5088
+
5076
5089
TExprNode::TPtr DropUnusedArgs (const TExprNode& lambda, const std::vector<ui32>& unused, TExprContext& ctx, ui32 skip = 0U ) {
5077
5090
const auto & copy = ctx.DeepCopyLambda (lambda);
5078
5091
return ctx.ChangeChild (*copy, 0U , ctx.NewArguments (copy->Head ().Pos (), DropUnused (copy->Head ().ChildrenList (), unused, skip)));
@@ -5095,6 +5108,28 @@ void DropUnusedRenames(TExprNode::TPtr& renames, const std::vector<ui32>& unused
5095
5108
renames = ctx.ChangeChildren (*renames, std::move (children));
5096
5109
}
5097
5110
5111
+ template <bool EvenOnly>
5112
+ void UpdateInputIndexes (TExprNode::TPtr& indexes, const std::vector<ui32>& unused, TExprContext& ctx) {
5113
+ TExprNode::TListType children;
5114
+ children.reserve (indexes->ChildrenSize ());
5115
+ for (auto i = 0U ; i < indexes->ChildrenSize () >> (EvenOnly ? 1U : 0U ); ++i) {
5116
+ const auto idx = i << (EvenOnly ? 1U : 0U );
5117
+ const auto outIndex = indexes->Child (idx);
5118
+ const auto oldValue = FromString<ui32>(outIndex->Content ());
5119
+ const auto newValue = oldValue - ui32 (std::distance (unused.cbegin (), std::lower_bound (unused.cbegin (), unused.cend (), oldValue)));
5120
+ if (oldValue == newValue) {
5121
+ children.emplace_back (indexes->ChildPtr (idx));
5122
+ } else {
5123
+ children.emplace_back (ctx.NewAtom (indexes->Child (idx)->Pos (), newValue));
5124
+ }
5125
+ if constexpr (EvenOnly) {
5126
+ children.emplace_back (indexes->ChildPtr (1U + idx));
5127
+ }
5128
+ }
5129
+
5130
+ indexes = ctx.ChangeChildren (*indexes, std::move (children));
5131
+ }
5132
+
5098
5133
TExprNode::TPtr DropUnusedStateFromUpdate (const TExprNode& lambda, const std::vector<ui32>& unused, TExprContext& ctx) {
5099
5134
const auto & copy = ctx.DeepCopyLambda (lambda, DropUnused (GetLambdaBody (lambda), unused));
5100
5135
return ctx.ChangeChild (*copy, 0U , ctx.NewArguments (copy->Head ().Pos (), DropUnused (copy->Head ().ChildrenList (), unused, lambda.Head ().ChildrenSize () - lambda.ChildrenSize () + 1U )));
@@ -6698,6 +6733,59 @@ TExprNode::TPtr OptimizeMapJoinCore(const TExprNode::TPtr& node, TExprContext& c
6698
6733
return node;
6699
6734
}
6700
6735
6736
+ TExprNode::TPtr OptimizeGraceJoinCore (const TExprNode::TPtr& node, TExprContext& ctx) {
6737
+ const TCoGraceJoinCore grace (node);
6738
+ auto leftUnused = FillAllIndexes (GetSeqItemType (*grace.LeftInput ().Ref ().GetTypeAnn ()));
6739
+ auto rightUnused = FillAllIndexes (GetSeqItemType (*grace.RightInput ().Ref ().GetTypeAnn ()));
6740
+ RemoveUsedIndexes<false >(grace.LeftKeysColumns ().Ref (), leftUnused);
6741
+ RemoveUsedIndexes<false >(grace.RightKeysColumns ().Ref (), rightUnused);
6742
+ RemoveUsedIndexes<true >(grace.LeftRenames ().Ref (), leftUnused);
6743
+ RemoveUsedIndexes<true >(grace.RightRenames ().Ref (), rightUnused);
6744
+ if (!(leftUnused.empty () && rightUnused.empty ())) {
6745
+ YQL_CLOG (DEBUG, CorePeepHole) << node->Content () << " with " << leftUnused.size () << " left and " << rightUnused.size () << " right unused columns." ;
6746
+
6747
+ auto children = node->ChildrenList ();
6748
+ if (!leftUnused.empty ()) {
6749
+ const std::vector<ui32> unused (leftUnused.cbegin (), leftUnused.cend ());
6750
+ children[TCoGraceJoinCore::idx_LeftInput] = MakeWideMapForDropUnused (std::move (children[TCoGraceJoinCore::idx_LeftInput]), unused, ctx);
6751
+ UpdateInputIndexes<false >(children[TCoGraceJoinCore::idx_LeftKeysColumns], unused, ctx);
6752
+ UpdateInputIndexes<true >(children[TCoGraceJoinCore::idx_LeftRenames], unused, ctx);
6753
+ }
6754
+ if (!rightUnused.empty ()) {
6755
+ const std::vector<ui32> unused (rightUnused.cbegin (), rightUnused.cend ());
6756
+ children[TCoGraceJoinCore::idx_RightInput] = MakeWideMapForDropUnused (std::move (children[TCoGraceJoinCore::idx_RightInput]), unused, ctx);
6757
+ UpdateInputIndexes<false >(children[TCoGraceJoinCore::idx_RightKeysColumns], unused, ctx);
6758
+ UpdateInputIndexes<true >(children[TCoGraceJoinCore::idx_RightRenames], unused, ctx);
6759
+ }
6760
+ return ctx.ChangeChildren (*node, std::move (children));
6761
+ }
6762
+
6763
+ return node;
6764
+ }
6765
+
6766
+ TExprNode::TPtr OptimizeGraceSelfJoinCore (const TExprNode::TPtr& node, TExprContext& ctx) {
6767
+ const TCoGraceSelfJoinCore grace (node);
6768
+ auto unused = FillAllIndexes (GetSeqItemType (*grace.Input ().Ref ().GetTypeAnn ()));
6769
+ RemoveUsedIndexes<false >(grace.LeftKeysColumns ().Ref (), unused);
6770
+ RemoveUsedIndexes<false >(grace.RightKeysColumns ().Ref (), unused);
6771
+ RemoveUsedIndexes<true >(grace.LeftRenames ().Ref (), unused);
6772
+ RemoveUsedIndexes<true >(grace.RightRenames ().Ref (), unused);
6773
+ if (!unused.empty ()) {
6774
+ YQL_CLOG (DEBUG, CorePeepHole) << node->Content () << " with " << unused.size () << " unused columns." ;
6775
+
6776
+ auto children = node->ChildrenList ();
6777
+ const std::vector<ui32> vector (unused.cbegin (), unused.cend ());
6778
+ children[TCoGraceSelfJoinCore::idx_Input] = MakeWideMapForDropUnused (std::move (children[TCoGraceSelfJoinCore::idx_Input]), vector, ctx);
6779
+ UpdateInputIndexes<false >(children[TCoGraceSelfJoinCore::idx_LeftKeysColumns], vector, ctx);
6780
+ UpdateInputIndexes<false >(children[TCoGraceSelfJoinCore::idx_RightKeysColumns], vector, ctx);
6781
+ UpdateInputIndexes<true >(children[TCoGraceSelfJoinCore::idx_LeftRenames], vector, ctx);
6782
+ UpdateInputIndexes<true >(children[TCoGraceSelfJoinCore::idx_RightRenames], vector, ctx);
6783
+ return ctx.ChangeChildren (*node, std::move (children));
6784
+ }
6785
+
6786
+ return node;
6787
+ }
6788
+
6701
6789
TExprNode::TPtr OptimizeCommonJoinCore (const TExprNode::TPtr& node, TExprContext& ctx) {
6702
6790
if (const auto & input = node->Head (); input.IsCallable (" NarrowMap" ) && input.Tail ().Tail ().IsCallable (" AsStruct" )) {
6703
6791
YQL_CLOG (DEBUG, CorePeepHole) << " Swap " << node->Content () << " with " << input.Content ();
@@ -8338,6 +8426,8 @@ struct TPeepHoleRules {
8338
8426
{" WideCondense1" , &OptimizeWideCondense1},
8339
8427
{" WideChopper" , &OptimizeWideChopper},
8340
8428
{" MapJoinCore" , &OptimizeMapJoinCore},
8429
+ {" GraceJoinCore" , &OptimizeGraceJoinCore},
8430
+ {" GraceSelfJoinCore" , &OptimizeGraceSelfJoinCore},
8341
8431
{" CommonJoinCore" , &OptimizeCommonJoinCore},
8342
8432
{" BuildTablePath" , &DoBuildTablePath},
8343
8433
{" Exists" , &OptimizeExists},
0 commit comments