Skip to content

Commit 5ef387d

Browse files
pashandor789yumkampavelvelikhovPavel Ivanov
authored
[CBO] Merge transitive closure + cycles fixes in DPHyp (#10857)
Co-authored-by: yumkam <[email protected]> Co-authored-by: Pavel Velikhov <[email protected]> Co-authored-by: Pavel Ivanov <[email protected]>
1 parent 0bf5166 commit 5ef387d

35 files changed

+1219
-765
lines changed

ydb/core/kqp/opt/logical/kqp_opt_cbo.cpp

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ TMaybeNode<TKqlKeyInc> GetRightTableKeyPrefix(const TKqlKeyRange& range) {
3636
/**
3737
* KQP specific rule to check if a LookupJoin is applicable
3838
*/
39-
bool IsLookupJoinApplicableDetailed(const std::shared_ptr<NYql::TRelOptimizerNode>& node, const TVector<TString>& joinColumns, const TKqpProviderContext& ctx) {
39+
bool IsLookupJoinApplicableDetailed(const std::shared_ptr<NYql::TRelOptimizerNode>& node, const TVector<TJoinColumn>& joinColumns, const TKqpProviderContext& ctx) {
4040

4141
auto rel = std::static_pointer_cast<TKqpRelOptimizerNode>(node);
4242
auto expr = TExprBase(rel->Node);
@@ -45,7 +45,7 @@ bool IsLookupJoinApplicableDetailed(const std::shared_ptr<NYql::TRelOptimizerNod
4545
return false;
4646
}
4747

48-
if (find_if(joinColumns.begin(), joinColumns.end(), [&] (const TString& s) { return node->Stats->KeyColumns->Data[0] == s;}) != joinColumns.end()) {
48+
if (std::find_if(joinColumns.begin(), joinColumns.end(), [&] (const TJoinColumn& c) { return node->Stats->KeyColumns->Data[0] == c.AttributeName;}) != joinColumns.end()) {
4949
return true;
5050
}
5151

@@ -97,8 +97,8 @@ bool IsLookupJoinApplicableDetailed(const std::shared_ptr<NYql::TRelOptimizerNod
9797
return false;
9898
}
9999

100-
if (prefixSize < node->Stats->KeyColumns->Data.size() && (find_if(joinColumns.begin(), joinColumns.end(), [&] (const TString& s) {
101-
return node->Stats->KeyColumns->Data[prefixSize] == s;
100+
if (prefixSize < node->Stats->KeyColumns->Data.size() && (std::find_if(joinColumns.begin(), joinColumns.end(), [&] (const TJoinColumn& c) {
101+
return node->Stats->KeyColumns->Data[prefixSize] == c.AttributeName;
102102
}) == joinColumns.end())){
103103
return false;
104104
}
@@ -108,12 +108,11 @@ bool IsLookupJoinApplicableDetailed(const std::shared_ptr<NYql::TRelOptimizerNod
108108

109109
bool IsLookupJoinApplicable(std::shared_ptr<IBaseOptimizerNode> left,
110110
std::shared_ptr<IBaseOptimizerNode> right,
111-
const std::set<std::pair<TJoinColumn, TJoinColumn>>& joinConditions,
112-
const TVector<TString>& leftJoinKeys,
113-
const TVector<TString>& rightJoinKeys,
111+
const TVector<TJoinColumn>& leftJoinKeys,
112+
const TVector<TJoinColumn>& rightJoinKeys,
114113
TKqpProviderContext& ctx
115114
) {
116-
Y_UNUSED(left, joinConditions, leftJoinKeys);
115+
Y_UNUSED(left, leftJoinKeys);
117116

118117
if (!(right->Stats->StorageType == EStorageType::RowStorage)) {
119118
return false;
@@ -130,7 +129,7 @@ bool IsLookupJoinApplicable(std::shared_ptr<IBaseOptimizerNode> left,
130129
}
131130

132131
for (auto rightCol : rightJoinKeys) {
133-
if (std::find(rightStats->KeyColumns->Data.begin(), rightStats->KeyColumns->Data.end(), rightCol) == rightStats->KeyColumns->Data.end()) {
132+
if (find(rightStats->KeyColumns->Data.begin(), rightStats->KeyColumns->Data.end(), rightCol.AttributeName) == rightStats->KeyColumns->Data.end()) {
134133
return false;
135134
}
136135
}
@@ -142,18 +141,17 @@ bool IsLookupJoinApplicable(std::shared_ptr<IBaseOptimizerNode> left,
142141

143142
bool TKqpProviderContext::IsJoinApplicable(const std::shared_ptr<IBaseOptimizerNode>& left,
144143
const std::shared_ptr<IBaseOptimizerNode>& right,
145-
const std::set<std::pair<NDq::TJoinColumn, NDq::TJoinColumn>>& joinConditions,
146-
const TVector<TString>& leftJoinKeys,
147-
const TVector<TString>& rightJoinKeys,
144+
const TVector<TJoinColumn>& leftJoinKeys,
145+
const TVector<TJoinColumn>& rightJoinKeys,
148146
EJoinAlgoType joinAlgo,
149-
EJoinKind joinKind) {
147+
EJoinKind joinKind) {
150148

151149
switch( joinAlgo ) {
152150
case EJoinAlgoType::LookupJoin:
153151
if ((OptLevel != 3) && (left->Stats->Nrows > 1000)) {
154152
return false;
155153
}
156-
return IsLookupJoinApplicable(left, right, joinConditions, leftJoinKeys, rightJoinKeys, *this);
154+
return IsLookupJoinApplicable(left, right, leftJoinKeys, rightJoinKeys, *this);
157155

158156
case EJoinAlgoType::LookupJoinReverse:
159157
if (joinKind != EJoinKind::LeftSemi) {
@@ -162,7 +160,7 @@ bool TKqpProviderContext::IsJoinApplicable(const std::shared_ptr<IBaseOptimizerN
162160
if ((OptLevel != 3) && (right->Stats->Nrows > 1000)) {
163161
return false;
164162
}
165-
return IsLookupJoinApplicable(right, left, joinConditions, rightJoinKeys, leftJoinKeys, *this);
163+
return IsLookupJoinApplicable(right, left, rightJoinKeys, leftJoinKeys, *this);
166164

167165
case EJoinAlgoType::MapJoin:
168166
return joinKind != EJoinKind::OuterJoin && joinKind != EJoinKind::Exclusion && right->Stats->ByteSize < 1e6;

ydb/core/kqp/opt/logical/kqp_opt_cbo.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ struct TKqpProviderContext : public NYql::TBaseProviderContext {
2525

2626
virtual bool IsJoinApplicable(const std::shared_ptr<NYql::IBaseOptimizerNode>& left,
2727
const std::shared_ptr<NYql::IBaseOptimizerNode>& right,
28-
const std::set<std::pair<NYql::NDq::TJoinColumn, NYql::NDq::TJoinColumn>>& joinConditions,
29-
const TVector<TString>& leftJoinKeys, const TVector<TString>& rightJoinKeys,
28+
const TVector<NYql::NDq::TJoinColumn>& leftJoinKeys, const TVector<NYql::NDq::TJoinColumn>& rightJoinKeys,
3029
NYql::EJoinAlgoType joinAlgo, NYql::EJoinKind joinKind) override;
3130

3231
virtual double ComputeJoinCost(const NYql::TOptimizerStatistics& leftStats, const NYql::TOptimizerStatistics& rightStats, const double outputRows, const double outputByteSize, NYql::EJoinAlgoType joinAlgo) const override;

ydb/core/kqp/ut/common/kqp_ut_common.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,6 +1463,24 @@ NJson::TJsonValue GetJoinOrder(const TString& deserializedPlan) {
14631463
return GetJoinOrderImpl(optRoot);
14641464
}
14651465

1466+
NJson::TJsonValue GetJoinOrderFromDetailedJoinOrderImpl(const NJson::TJsonValue& opt) {
1467+
if (!opt.GetMapSafe().contains("table")) {
1468+
NJson::TJsonValue res;
1469+
auto args = opt.GetMapSafe().at("args").GetArraySafe();
1470+
for (size_t i = 0; i < args.size(); ++i) {
1471+
res.AppendValue(GetJoinOrderFromDetailedJoinOrderImpl(args[i]));
1472+
}
1473+
return res;
1474+
}
1475+
1476+
return opt.GetMapSafe().at("table");
1477+
}
1478+
1479+
NJson::TJsonValue GetJoinOrderFromDetailedJoinOrder(const TString& deserializedDetailedJoinOrder) {
1480+
NJson::TJsonValue optRoot;
1481+
NJson::ReadJsonTree(deserializedDetailedJoinOrder, &optRoot, true);
1482+
return GetJoinOrderFromDetailedJoinOrderImpl(optRoot);
1483+
}
14661484

14671485
} // namspace NKqp
14681486
} // namespace NKikimr

ydb/core/kqp/ut/common/kqp_ut_common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,5 +350,7 @@ NJson::TJsonValue GetDetailedJoinOrder(const TString& deserializedPlan, const TG
350350
/* Gets tables join order without details : only tables. */
351351
NJson::TJsonValue GetJoinOrder(const TString& deserializedPlan);
352352

353+
NJson::TJsonValue GetJoinOrderFromDetailedJoinOrder(const TString& deserializedDetailedJoinOrder);
354+
353355
} // namespace NKqp
354356
} // namespace NKikimr

ydb/core/kqp/ut/join/data/join_order/lookupbug.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,4 @@
6060
}
6161
]
6262
}
63+

ydb/core/kqp/ut/join/data/join_order/tpcc.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@
2424
}
2525
]
2626
}
27+

0 commit comments

Comments
 (0)