Skip to content

Commit a4775cf

Browse files
committed
Add support for KqpOlapApply in explain (#18431)
1 parent 2a7fe82 commit a4775cf

File tree

5 files changed

+56
-11
lines changed

5 files changed

+56
-11
lines changed

ydb/core/kqp/opt/kqp_query_plan.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,6 +1154,8 @@ class TxPlanSerializer {
11541154
return Sprintf(strRegexp[compSign].c_str(), attr.c_str(), value.c_str());
11551155
}
11561156
}
1157+
} else if (auto olapApply = TMaybeNode<TKqpOlapApply>(node)) {
1158+
return NPlanUtils::ExtractPredicate(olapApply.Cast().Lambda()).Body;
11571159
}
11581160

11591161
for (const auto& child: node->Children()) {

ydb/core/kqp/opt/kqp_statistics_transformer.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,8 @@ class TKqpOlapPredicateSelectivityComputer: public TPredicateSelectivityComputer
473473
tmpSelectivity *= Compute(andNode.Cast().Arg(i));
474474
}
475475
resSelectivity = tmpSelectivity;
476+
} else if (auto olapApply = input.Maybe<TKqpOlapApply>()) {
477+
resSelectivity = TPredicateSelectivityComputer::Compute(olapApply.Cast().Lambda().Body());
476478
} else if (auto orNode = input.Maybe<TKqpOlapOr>()) {
477479
double tmpSelectivity = 0.0;
478480
for (size_t i = 0; i < orNode.Cast().ArgCount(); i++) {

ydb/core/kqp/ut/join/kqp_join_order_ut.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -287,10 +287,9 @@ Y_UNIT_TEST_SUITE(OlapEstimationRowsCorrectness) {
287287
TestOlapEstimationRowsCorrectness("queries/tpch2.sql", "stats/tpch1000s.json");
288288
}
289289

290-
// FIXME: Cardinality estimation is broken because of new type of OLAP pushdown
291-
// Y_UNIT_TEST(TPCH3) {
292-
// TestOlapEstimationRowsCorrectness("queries/tpch3.sql", "stats/tpch1000s.json");
293-
// }
290+
Y_UNIT_TEST(TPCH3) {
291+
TestOlapEstimationRowsCorrectness("queries/tpch3.sql", "stats/tpch1000s.json");
292+
}
294293

295294
Y_UNIT_TEST(TPCH5) {
296295
TestOlapEstimationRowsCorrectness("queries/tpch5.sql", "stats/tpch1000s.json");

ydb/library/yql/dq/opt/dq_opt_predicate_selectivity.cpp

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ namespace {
1717
* Check if a callable is an attribute of some table
1818
* Currently just return a boolean and cover only basic cases
1919
*/
20-
TMaybe<TCoMember> IsAttribute(const TExprBase& input) {
20+
std::optional<TString> IsAttribute(const TExprBase& input) {
2121
if (auto member = input.Maybe<TCoMember>()) {
22-
return member.Cast();
22+
return TString(member.Cast().Name());
2323
} else if (auto cast = input.Maybe<TCoSafeCast>()) {
2424
return IsAttribute(cast.Cast().Value());
2525
} else if (auto ifPresent = input.Maybe<TCoIfPresent>()) {
@@ -35,8 +35,37 @@ namespace {
3535
} else if (auto exists = input.Maybe<TCoExists>()) {
3636
auto child = TExprBase(input.Ptr()->ChildRef(0));
3737
return IsAttribute(child);
38+
} else if (auto argument = input.Maybe<TCoArgument>()) {
39+
TString argumentName = TString(argument.Cast().Name());
40+
TStringBuf olapApplyMemberPrefix = "members_";
41+
if (argumentName.StartsWith(olapApplyMemberPrefix)) {
42+
return argumentName.substr(olapApplyMemberPrefix.length(), argumentName.size() - olapApplyMemberPrefix.length());
43+
} else {
44+
return argumentName;
45+
}
3846
}
47+
return std::nullopt;
48+
}
3949

50+
TMaybe<TCoMember> IsMember(const TExprBase& input) {
51+
if (auto member = input.Maybe<TCoMember>()) {
52+
return member.Cast();
53+
} else if (auto cast = input.Maybe<TCoSafeCast>()) {
54+
return IsMember(cast.Cast().Value());
55+
} else if (auto ifPresent = input.Maybe<TCoIfPresent>()) {
56+
return IsMember(ifPresent.Cast().Optional());
57+
} else if (auto just = input.Maybe<TCoJust>()) {
58+
return IsMember(just.Cast().Input());
59+
} else if (input.Ptr()->IsCallable("PgCast")) {
60+
auto child = TExprBase(input.Ptr()->ChildRef(0));
61+
return IsMember(child);
62+
} else if (input.Ptr()->IsCallable("FromPg")) {
63+
auto child = TExprBase(input.Ptr()->ChildRef(0));
64+
return IsMember(child);
65+
} else if (auto exists = input.Maybe<TCoExists>()) {
66+
auto child = TExprBase(input.Ptr()->ChildRef(0));
67+
return IsMember(child);
68+
}
4069
return Nothing();
4170
}
4271

@@ -143,26 +172,32 @@ double NYql::NDq::TPredicateSelectivityComputer::ComputeEqualitySelectivity(cons
143172
return ComputeEqualitySelectivity(right, left);
144173
}
145174

146-
if (auto maybeMember = IsAttribute(left)) {
175+
if (auto attribute = IsAttribute(left)) {
147176
// In case both arguments refer to an attribute, return 0.2
148-
if (auto maybeAnotherMember = IsAttribute(right)) {
177+
if (IsAttribute(right)) {
149178
if (CollectMemberEqualities) {
150-
MemberEqualities.Add(*maybeMember.Get(), *maybeAnotherMember.Get());
179+
auto maybeMember = IsMember(left);
180+
auto maybeAnotherMember = IsMember(right);
181+
if (maybeMember && maybeAnotherMember) {
182+
MemberEqualities.Add(*maybeMember.Get(), *maybeAnotherMember.Get());
183+
}
151184
}
152185
return 0.3;
153186
}
154187
// In case the right side is a constant that can be extracted, compute the selectivity using statistics
155188
// Currently, with the basic statistics we just return 1/nRows
156189

157190
else if (IsConstantExprWithParams(right.Ptr())) {
158-
TString attributeName = maybeMember.Get()->Name().StringValue();
191+
TString attributeName = attribute.value();
159192
if (!IsConstantExpr(right.Ptr())) {
160193
return DefaultSelectivity(Stats, attributeName);
161194
}
162195

163196
if (Stats == nullptr || Stats->ColumnStatistics == nullptr) {
164197
if (CollectColumnsStatUsedMembers) {
165-
ColumnStatsUsedMembers.AddEquality(*maybeMember.Get());
198+
if (auto maybeMember = IsMember(left)) {
199+
ColumnStatsUsedMembers.AddEquality(*maybeMember.Get());
200+
}
166201
}
167202
return DefaultSelectivity(Stats, attributeName);
168203
}

ydb/library/yql/utils/plan/plan_utils.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,13 @@ TString PrettyExprStr(const TExprBase& expr) {
285285

286286
return TStringBuilder() << "[" << JoinStrings(std::move(items), ",") << "]";
287287
} else {
288+
if (auto arg = expr.Maybe<TCoArgument>()) {
289+
TStringBuf yqlOlapApplyMember = "members_";
290+
TString argumentName = TString(arg.Cast().Name());
291+
if (argumentName.StartsWith(yqlOlapApplyMember)) {
292+
return argumentName.substr(yqlOlapApplyMember.length(), argumentName.length() - yqlOlapApplyMember.length());
293+
}
294+
}
288295
auto raw = TString(expr.Ref().Content());
289296
// return raw.StartsWith("_yql_agg_") ? "" : raw;
290297
return raw;

0 commit comments

Comments
 (0)