Skip to content

Commit 30e189b

Browse files
authored
Fix literal rewrite rule for predicate pushdown (#809)
* Fix range union * fix ydb/library/yql/core/extract_predicate/ut * fix ydb/library/yql/tests/sql/yt_native_file/part6 YDBREQUESTS-3030
1 parent 8579425 commit 30e189b

File tree

4 files changed

+81
-27
lines changed

4 files changed

+81
-27
lines changed

ydb/core/kqp/ut/opt/kqp_extract_predicate_unpack_ut.cpp

+40-4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ void PrepareTablesToUnpack(TSession session) {
1616
Value String,
1717
PRIMARY KEY (Key, Fk)
1818
);
19+
CREATE TABLE `/Root/ComplexKeyNotNull` (
20+
Key Int32 NOT NULL,
21+
Fk Int32 NOT NULL,
22+
Value String,
23+
PRIMARY KEY (Key, Fk)
24+
);
25+
1926
CREATE TABLE `/Root/UintComplexKey` (
2027
Key UInt64,
2128
Fk Int64,
@@ -65,6 +72,14 @@ void PrepareTablesToUnpack(TSession session) {
6572
(4, 104, "Value2"),
6673
(5, 105, "Value3");
6774
75+
REPLACE INTO `/Root/ComplexKeyNotNull` (Key, Fk, Value) VALUES
76+
(1, 101, "Value1"),
77+
(2, 102, "Value1"),
78+
(2, 103, "Value3"),
79+
(3, 103, "Value2"),
80+
(4, 104, "Value2"),
81+
(5, 105, "Value3");
82+
6883
REPLACE INTO `/Root/UintComplexKey` (Key, Fk, Value) VALUES
6984
(null, null, "NullValue"),
7085
(1, 101, "Value1"),
@@ -293,13 +308,24 @@ Y_UNIT_TEST(ComplexRange) {
293308
TestRange(
294309
R"(
295310
SELECT Key, Fk, Value FROM `/Root/ComplexKey`
311+
WHERE (Key, Fk) >= (4, 104);
312+
)",
313+
R"([
314+
[[4];[104];["Value2"]];
315+
[[5];[105];["Value3"]]
316+
])",
317+
2);
318+
319+
TestRange(
320+
R"(
321+
SELECT Key, Fk, Value FROM `/Root/ComplexKeyNotNull`
296322
WHERE (Key, Fk) >= (1, 101) AND (Key, Fk) < (4, 104);
297323
)",
298324
R"([
299-
[[1];[101];["Value1"]];
300-
[[2];[102];["Value1"]];
301-
[[2];[103];["Value3"]];
302-
[[3];[103];["Value2"]]
325+
[1;101;["Value1"]];
326+
[2;102;["Value1"]];
327+
[2;103;["Value3"]];
328+
[3;103;["Value2"]]
303329
])",
304330
4);
305331

@@ -314,6 +340,16 @@ Y_UNIT_TEST(ComplexRange) {
314340
1,
315341
2);
316342

343+
TestRange(
344+
R"(
345+
SELECT Key, Fk, Value FROM `/Root/ComplexKey`
346+
WHERE (Key < 2) OR (Key = 2 AND Fk > 102)
347+
)",
348+
R"([
349+
[[1];[101];["Value1"]];[[2];[103];["Value3"]]
350+
])",
351+
2,
352+
2);
317353
}
318354

319355
Y_UNIT_TEST(SqlIn) {

ydb/library/yql/core/extract_predicate/extract_predicate_impl.cpp

+37-18
Original file line numberDiff line numberDiff line change
@@ -430,8 +430,8 @@ TExprNode::TPtr ExpandTupleBinOp(const TExprNode& node, TExprContext& ctx) {
430430
if (node.IsCallable({"<=", ">="})) {
431431
return ctx.Builder(node.Pos())
432432
.Callable("Or")
433-
.Add(0, ctx.RenameNode(node, "=="))
434-
.Add(1, ctx.RenameNode(node, node.IsCallable("<=") ? "<" : ">"))
433+
.Add(0, ctx.RenameNode(node, node.IsCallable("<=") ? "<" : ">"))
434+
.Add(1, ctx.RenameNode(node, "=="))
435435
.Seal()
436436
.Build();
437437
}
@@ -1542,15 +1542,15 @@ TMaybe<TRangeBoundHint> CompareBounds(
15421542
return Nothing();
15431543
}
15441544
if (auto cmp = TryCompareColumns(hint1.Columns[i], hint2.Columns[i])) {
1545-
if ((cmp < 0) == min) {
1545+
if (cmp == 0) {
1546+
continue;
1547+
} else if ((cmp < 0) == min) {
15461548
hint = hint1;
15471549
} else {
15481550
hint = hint2;
15491551
}
15501552

1551-
if (cmp != 0) {
1552-
break;
1553-
}
1553+
break;
15541554
} else {
15551555
return Nothing();
15561556
}
@@ -1599,7 +1599,7 @@ TMaybe<TRangeHint> RangeHintExtend(const TMaybe<TRangeHint>& hint1, size_t hint1
15991599
}
16001600
}
16011601

1602-
bool IsValid(const TRangeBoundHint& left, const TRangeBoundHint& right, bool acceptExclusivePoint = true) {
1602+
bool IsValid(const TRangeBoundHint& left, const TRangeBoundHint& right) {
16031603
for (size_t i = 0; ; ++i) {
16041604
if (i >= left.Columns.size() || i >= right.Columns.size()) {
16051605
// ok, we have +-inf and sure that it's valid
@@ -1608,15 +1608,12 @@ bool IsValid(const TRangeBoundHint& left, const TRangeBoundHint& right, bool acc
16081608
auto cmp = TryCompareColumns(left.Columns[i], right.Columns[i]);
16091609
if (!cmp) {
16101610
return false;
1611-
} else {
1612-
if (*cmp < 0) {
1613-
return true;
1614-
} else if (*cmp > 0) {
1615-
return false;
1616-
}
1611+
} else if (*cmp < 0) {
1612+
return true;
1613+
} else if (*cmp > 0) {
1614+
return false;
16171615
}
16181616
}
1619-
return acceptExclusivePoint || left.Inclusive || right.Inclusive;
16201617
}
16211618

16221619
TMaybe<TRangeHint> RangeHintUnion(const TRangeHint& hint1, const TRangeHint& hint2) {
@@ -1630,11 +1627,33 @@ TMaybe<TRangeHint> RangeHintUnion(const TRangeHint& hint1, const TRangeHint& hin
16301627
if (!left || !right || !intersection) {
16311628
return Nothing();
16321629
}
1633-
if (IsValid(intersection->Left, intersection->Right, false)) {
1634-
return TRangeHint{.Left = std::move(*left), .Right = std::move(*right)};
1635-
} else {
1636-
return Nothing();
1630+
1631+
{ // check if there is no gap between ranges
1632+
for (size_t i = 0; ; ++i) {
1633+
bool leftFinished = i >= intersection->Left.Columns.size();
1634+
bool rightFinished = i >= intersection->Right.Columns.size();
1635+
if (leftFinished || rightFinished) {
1636+
if (leftFinished && intersection->Left.Inclusive) {
1637+
break;
1638+
}
1639+
if (rightFinished && intersection->Right.Inclusive) {
1640+
break;
1641+
}
1642+
return {};
1643+
}
1644+
1645+
auto cmp = TryCompareColumns(intersection->Left.Columns[i], intersection->Right.Columns[i]);
1646+
if (!cmp) {
1647+
return {};
1648+
} else if (*cmp < 0) {
1649+
break;
1650+
} else if (*cmp > 0) {
1651+
return {};
1652+
}
1653+
}
16371654
}
1655+
1656+
return TRangeHint{.Left = std::move(*left), .Right = std::move(*right)};
16381657
}
16391658

16401659
TMaybe<TRangeHint> RangeHintUnion(const TMaybe<TRangeHint>& hint1, const TMaybe<TRangeHint>& hint2) {

ydb/library/yql/core/extract_predicate/ut/extract_predicate_ut.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -523,8 +523,7 @@ Y_UNIT_TEST_SUITE(TYqlExtractPredicate) {
523523
"(let $2 (StructType '('\"x\" $1) '('\"y\" $1)))\n"
524524
"(let $3 (Int32 '1))\n"
525525
"(let $4 (Int32 '\"2\"))\n"
526-
"(return (RangeOr (RangeAnd (Range $2 (lambda '($5) (== (Member $5 '\"x\") $3))) (Range $2 (lambda '($6) (== (Member $6 '\"y\") $4)))) (Range $2 (lambda '($7) (< (Member $7 '\"x\") $3))) (RangeAnd (Range $2 (lambda '($8) (== (Memb"
527-
"er $8 '\"x\") $3))) (Range $2 (lambda '($9) (< (Member $9 '\"y\") $4))))))\n"
526+
"(return (RangeOr (Range $2 (lambda '($5) (< (Member $5 '\"x\") $3))) (RangeAnd (Range $2 (lambda '($6) (== (Member $6 '\"x\") $3))) (Range $2 (lambda '($7) (< (Member $7 '\"y\") $4)))) (RangeAnd (Range $2 (lambda '($8) (== (Member $8 '\"x\") $3))) (Range $2 (lambda '($9) (== (Member $9 '\"y\") $4))))))\n"
528527
")\n";
529528

530529
TExprContext exprCtx;

ydb/library/yql/tests/sql/yt_native_file/part6/canondata/result.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -669,9 +669,9 @@
669669
],
670670
"test.test[compute_range-tuples_compare-default.txt-Debug]": [
671671
{
672-
"checksum": "962da2716dd68cffc53234286a48d7c7",
673-
"size": 4596,
674-
"uri": "https://{canondata_backend}/995452/3862ff9a9bced9f226a84891d10e8a5df01e3ec0/resource.tar.gz#test.test_compute_range-tuples_compare-default.txt-Debug_/opt.yql"
672+
"checksum": "1214969b596fc6210776601e78bd0c24",
673+
"size": 4603,
674+
"uri": "https://{canondata_backend}/1784117/8b994472d7c14f553ca7722e774cd8684ad93d6a/resource.tar.gz#test.test_compute_range-tuples_compare-default.txt-Debug_/opt.yql"
675675
}
676676
],
677677
"test.test[compute_range-tuples_compare-default.txt-Plan]": [

0 commit comments

Comments
 (0)