Skip to content

Commit 2a528e7

Browse files
rvu1024blinkov
authored andcommitted
DynamicVariant constraints
commit_hash:7e11aee2a54d8ec6c92e4170c530f9899a850877
1 parent f883c02 commit 2a528e7

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

yql/essentials/core/yql_expr_constraint.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ class TCallableConstraintTransformer : public TCallableTransformerBase<TCallable
201201
Functions["Visit"] = &TCallableConstraintTransformer::VisitWrap;
202202
Functions["VariantItem"] = &TCallableConstraintTransformer::VariantItemWrap;
203203
Functions["Variant"] = &TCallableConstraintTransformer::VariantWrap;
204+
Functions["DynamicVariant"] = &TCallableConstraintTransformer::DynamicVariantWrap;
204205
Functions["Guess"] = &TCallableConstraintTransformer::GuessWrap;
205206
Functions["Mux"] = &TCallableConstraintTransformer::MuxWrap;
206207
Functions["Nth"] = &TCallableConstraintTransformer::NthWrap;
@@ -668,6 +669,43 @@ class TCallableConstraintTransformer : public TCallableTransformerBase<TCallable
668669
FilterFromHead<TPartOfChoppedConstraintNode>(input, filter, ctx);
669670
FilterFromHead<TPartOfUniqueConstraintNode>(input, filterForUnique, ctx);
670671
FilterFromHead<TPartOfDistinctConstraintNode>(input, filterForDistinct, ctx);
672+
673+
const auto unwrapedOutItemType = RemoveOptionalType(outItemType);
674+
const auto unwrapedInItemType = RemoveOptionalType(inItemType);
675+
if (unwrapedInItemType->GetKind() == ETypeAnnotationKind::Variant && unwrapedOutItemType->GetKind() == ETypeAnnotationKind::Variant
676+
&& unwrapedOutItemType->Cast<TVariantExprType>()->GetUnderlyingType()->GetKind() == ETypeAnnotationKind::Tuple) {
677+
678+
const auto tupleUnderInType = unwrapedInItemType->Cast<TVariantExprType>()->GetUnderlyingType()->Cast<TTupleExprType>();
679+
const auto tupleUnderOutType = unwrapedOutItemType->Cast<TVariantExprType>()->GetUnderlyingType()->Cast<TTupleExprType>();
680+
if (auto multi = input->Head().GetConstraint<TMultiConstraintNode>()) {
681+
if (tupleUnderOutType->GetSize() < tupleUnderInType->GetSize()) {
682+
TMultiConstraintNode::TMapType multiItems;
683+
std::copy_if(multi->GetItems().cbegin(), multi->GetItems().cend(),
684+
std::back_inserter(multiItems),
685+
[&](const auto& item) { return item.first < tupleUnderOutType->GetSize(); }
686+
);
687+
if (!multiItems.empty()) {
688+
input->AddConstraint(ctx.MakeConstraint<TMultiConstraintNode>(std::move(multiItems)));
689+
}
690+
} else {
691+
input->AddConstraint(multi);
692+
}
693+
}
694+
if (auto varItem = input->Head().GetConstraint<TVarIndexConstraintNode>()) {
695+
if (tupleUnderOutType->GetSize() < tupleUnderInType->GetSize()) {
696+
TVarIndexConstraintNode::TMapType filteredItems;
697+
std::copy_if(varItem->GetIndexMapping().cbegin(), varItem->GetIndexMapping().cend(),
698+
std::back_inserter(filteredItems),
699+
[&](const auto& item) { return item.second < tupleUnderOutType->GetSize(); }
700+
);
701+
if (!filteredItems.empty()) {
702+
input->AddConstraint(ctx.MakeConstraint<TVarIndexConstraintNode>(std::move(filteredItems)));
703+
}
704+
} else {
705+
input->AddConstraint(varItem);
706+
}
707+
}
708+
}
671709
return TStatus::Ok;
672710
}
673711

@@ -1985,6 +2023,28 @@ class TCallableConstraintTransformer : public TCallableTransformerBase<TCallable
19852023
return TStatus::Ok;
19862024
}
19872025

2026+
TStatus DynamicVariantWrap(const TExprNode::TPtr& input, TExprNode::TPtr& /*output*/, TExprContext& ctx) const {
2027+
if (auto underlyingType = RemoveOptionalType(input->GetTypeAnn())->Cast<TVariantExprType>()->GetUnderlyingType(); underlyingType->GetKind() == ETypeAnnotationKind::Tuple) {
2028+
TConstraintSet target;
2029+
CopyExcept(target, input->Head().GetConstraintSet(), TVarIndexConstraintNode::Name());
2030+
TMultiConstraintNode::TMapType items;
2031+
for (ui32 i = 0; i < underlyingType->Cast<TTupleExprType>()->GetSize(); ++i) {
2032+
items.emplace_back(i, target);
2033+
}
2034+
input->AddConstraint(ctx.MakeConstraint<TMultiConstraintNode>(std::move(items)));
2035+
if (auto varIndex = input->Head().GetConstraint<TVarIndexConstraintNode>()) {
2036+
TVarIndexConstraintNode::TMapType filteredItems;
2037+
for (ui32 i = 0; i < underlyingType->Cast<TTupleExprType>()->GetSize(); ++i) {
2038+
for (auto& item: varIndex->GetIndexMapping()) {
2039+
filteredItems.push_back(std::make_pair(i, item.second));
2040+
}
2041+
}
2042+
input->AddConstraint(ctx.MakeConstraint<TVarIndexConstraintNode>(std::move(filteredItems)));
2043+
}
2044+
}
2045+
return TStatus::Ok;
2046+
}
2047+
19882048
TStatus GuessWrap(const TExprNode::TPtr& input, TExprNode::TPtr& /*output*/, TExprContext& ctx) const {
19892049
auto inputType = input->Head().GetTypeAnn();
19902050
if (inputType->GetKind() == ETypeAnnotationKind::Optional) {

0 commit comments

Comments
 (0)