Skip to content

Commit d6681e8

Browse files
authored
Fix simplification of unique constraint. (#2950)
1 parent 815fbb4 commit d6681e8

File tree

2 files changed

+51
-9
lines changed

2 files changed

+51
-9
lines changed

ydb/library/yql/ast/yql_constraint.cpp

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,20 +1232,32 @@ TUniqueConstraintNodeBase<Distinct>::DoGetSimplifiedForType(const TTypeAnnotatio
12321232
for (bool setChanged = true; setChanged;) {
12331233
setChanged = false;
12341234
for (auto it = sets.begin(); sets.end() != it;) {
1235-
if (it->size() != 1U || it->front().size() <= 1U)
1236-
++it;
1237-
else {
1235+
if (!it->empty() && it->front().size() > 1U) {
1236+
TPartOfConstraintBase::TSetType prefixes;
1237+
prefixes.reserve(it->size());
1238+
for (const auto& path : *it) {
1239+
if (path.size() > 1U) {
1240+
prefixes.emplace_back(getPrefix(path));
1241+
}
1242+
}
1243+
12381244
auto from = it++;
1239-
const auto prefix = getPrefix(from->front());
1240-
while (sets.cend() != it && it->size() == 1U && it->front().size() > 1U && prefix == getPrefix(it->front()))
1241-
++it;
1245+
if (prefixes.size() < from->size())
1246+
continue;
12421247

1243-
if (ssize_t(GetElementsCount(TBase::GetSubTypeByPath(prefix, rowType))) == std::distance(from, it)) {
1244-
*from++ = TPartOfConstraintBase::TSetType{std::move(prefix)};
1248+
while (sets.cend() != it && it->size() == prefixes.size() &&
1249+
std::all_of(it->cbegin(), it->cend(), [&](const TPartOfConstraintBase::TPathType& path) { return path.size() > 1U && prefixes.contains(getPrefix(path)); })) {
1250+
++it;
1251+
}
1252+
1253+
if (std::all_of(prefixes.cbegin(), prefixes.cend(),
1254+
[width = std::distance(from, it), &rowType] (const TPartOfConstraintBase::TPathType& path) { return width == ssize_t(GetElementsCount(TBase::GetSubTypeByPath(path, rowType))); })) {
1255+
*from++ =std::move(prefixes);
12451256
it = sets.erase(from, it);
12461257
changed = setChanged = true;
12471258
}
1248-
}
1259+
} else
1260+
++it;
12491261
}
12501262
}
12511263
}

ydb/library/yql/core/ut/yql_expr_constraint_ut.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1566,6 +1566,36 @@ Y_UNIT_TEST_SUITE(TYqlExprConstraints) {
15661566
CheckConstraint<TDistinctConstraintNode>(exprRoot, "Skip", "Distinct((key))");
15671567
}
15681568

1569+
Y_UNIT_TEST(PartitionsByKeysWithCondense1WithPairItemsTupleKeyAndDuplicateOut) {
1570+
const auto s = R"(
1571+
(
1572+
(let mr_sink (DataSink 'yt (quote plato)))
1573+
(let list (AsList
1574+
(AsStruct '('key '((Just (String '4)) (Just (String '%)))) '('subkey (Just (String 'c))) '('value (Just (String 'x))))
1575+
(AsStruct '('key '((Just (String '1)) (Just (String '€)))) '('subkey (Just (String 'b))) '('value (Just (String 'y))))
1576+
(AsStruct '('key '((Just (String '4)) (Just (String '$)))) '('subkey (Just (String 'b))) '('value (Just (String 'z))))
1577+
))
1578+
(let extractor (lambda '(row) '((Nth (Member row 'key) '0) (Nth (Member row 'key) '1))))
1579+
(let aggr (PartitionsByKeys list (lambda '(item) (Member item 'key)) (Void) (Void)
1580+
(lambda '(stream) (Map (Condense1 stream extractor
1581+
(lambda '(row state) (IsKeySwitch row state extractor (lambda '(item) item)))
1582+
(lambda '(row state) state)
1583+
)
1584+
(lambda '(item) (AsStruct '('one '(item)) '('two '(item))))
1585+
))
1586+
))
1587+
(let world (Write! world mr_sink (Key '('table (String 'Output))) (Skip aggr (Uint64 '1)) '('('mode 'renew))))
1588+
(let world (Commit! world mr_sink))
1589+
(return world)
1590+
)
1591+
)";
1592+
1593+
TExprContext exprCtx;
1594+
const auto exprRoot = ParseAndAnnotate(s, exprCtx);
1595+
CheckConstraint<TUniqueConstraintNode>(exprRoot, "Skip", "Unique(({one,two}))");
1596+
CheckConstraint<TDistinctConstraintNode>(exprRoot, "Skip", "Distinct(({one,two}))");
1597+
}
1598+
15691599
Y_UNIT_TEST(ShuffleByKeysInputUnique) {
15701600
const auto s = R"(
15711601
(

0 commit comments

Comments
 (0)