diff options
author | a-romanov <Anton.Romanov@ydb.tech> | 2023-04-24 11:28:33 +0300 |
---|---|---|
committer | a-romanov <Anton.Romanov@ydb.tech> | 2023-04-24 11:28:33 +0300 |
commit | f9a0c8229df295ad699d1395f7f5c24b53a35ecc (patch) | |
tree | 944f5483024f383a6207291ffdefd831a23f1c10 | |
parent | 3ca56fe57785e4c4c7e76e58a6be982174ca7337 (diff) | |
download | ydb-f9a0c8229df295ad699d1395f7f5c24b53a35ecc.tar.gz |
YQL-8971 YQL-15555 Fix unique in case inner + any join.
-rw-r--r-- | ydb/library/yql/core/yql_expr_constraint.cpp | 23 | ||||
-rw-r--r-- | ydb/library/yql/core/yql_join.cpp | 32 | ||||
-rw-r--r-- | ydb/library/yql/providers/dq/provider/yql_dq_datasink_constraints.cpp | 21 |
3 files changed, 44 insertions, 32 deletions
diff --git a/ydb/library/yql/core/yql_expr_constraint.cpp b/ydb/library/yql/core/yql_expr_constraint.cpp index cacf929e975..48c8603f167 100644 --- a/ydb/library/yql/core/yql_expr_constraint.cpp +++ b/ydb/library/yql/core/yql_expr_constraint.cpp @@ -2534,7 +2534,6 @@ private: const bool lOneRow = lUnique && lUnique->HasEqualColumns(GetKeys(core.LeftKeysColumns().Ref())); const bool rOneRow = rUnique && rUnique->HasEqualColumns(GetKeys(core.RightKeysColumns().Ref())); - const bool bothOne = lOneRow && rOneRow; const bool singleSide = joinType.Content().ends_with("Semi") || joinType.Content().ends_with("Only"); @@ -2552,13 +2551,17 @@ private: unique = lUnique->RenameFields(ctx, leftRename); else if (rightSide && rUnique) unique = rUnique->RenameFields(ctx, rightRename); - } else if (joinType.IsAtom("Exclusion") || (lOneRow && rOneRow && joinType.IsAtom({"Inner", "Full", "Left", "Right"}))) { - if (lUnique && rUnique) - unique = TUniqueConstraintNode::Merge(lUnique->RenameFields(ctx, leftRename), rUnique->RenameFields(ctx, rightRename), ctx); - else if (lUnique) + } else { + const bool exclusion = joinType.IsAtom("Exclusion"); + const bool useLeft = lUnique && (rOneRow || exclusion); + const bool useRight = rUnique && (lOneRow || exclusion); + + if (useLeft && !useRight) unique = lUnique->RenameFields(ctx, leftRename); - else if (rUnique) - unique = rUnique->RenameFields(ctx, rightRename); + else if (useRight && !useLeft) + unique = lUnique->RenameFields(ctx, leftRename); + else if (useLeft && useRight) + unique = TUniqueConstraintNode::Merge(lUnique->RenameFields(ctx, leftRename), rUnique->RenameFields(ctx, rightRename), ctx); } const auto lDistinct = core.LeftInput().Ref().GetConstraint<TDistinctConstraintNode>(); @@ -2570,9 +2573,9 @@ private: else if (rightSide && rDistinct) distinct = rDistinct->RenameFields(ctx, rightRename); } else { - const bool useBoth = bothOne && joinType.IsAtom("Inner"); - const bool useLeft = lDistinct && ((leftSide && rOneRow) || useBoth); - const bool useRight = rDistinct && ((rightSide && lOneRow) || useBoth); + const bool inner = joinType.IsAtom("Inner"); + const bool useLeft = lDistinct && rOneRow && (inner || leftSide); + const bool useRight = rDistinct && lOneRow && (inner || rightSide); if (useLeft && !useRight) distinct = lDistinct->RenameFields(ctx, leftRename); diff --git a/ydb/library/yql/core/yql_join.cpp b/ydb/library/yql/core/yql_join.cpp index 1eba696aba5..109c7ec0c2b 100644 --- a/ydb/library/yql/core/yql_join.cpp +++ b/ydb/library/yql/core/yql_join.cpp @@ -259,7 +259,7 @@ namespace { scope.clear(); - const bool singleSide = joinType.Content().ends_with("Only") || joinType.Content().ends_with("Semi"); + const bool singleSide = joinType.Content().ends_with("Only") || joinType.Content().ends_with("Semi"); const bool rightSide = joinType.Content().starts_with("Right"); const bool leftSide = joinType.Content().starts_with("Left"); @@ -334,9 +334,11 @@ namespace { } } - const bool lOneRow = (lUnique && lUnique->HasEqualColumns(lCheck)) || (leftHints && (leftHints->contains("unique") || leftHints->contains("any"))); - const bool rOneRow = (rUnique && rUnique->HasEqualColumns(rCheck)) || (rightHints && (rightHints->contains("unique") || rightHints->contains("any"))); - const bool bothOne = lOneRow && rOneRow; + const bool lAny = leftHints && (leftHints->contains("unique") || leftHints->contains("any")); + const bool rAny = rightHints && (rightHints->contains("unique") || rightHints->contains("any")); + + const bool lOneRow = lAny || lUnique && lUnique->HasEqualColumns(lCheck); + const bool rOneRow = rAny || rUnique && rUnique->HasEqualColumns(rCheck); if (unique) { if (singleSide) { @@ -344,13 +346,17 @@ namespace { *unique = lUnique; else if (rightSide) *unique = rUnique; - } else if (joinType.IsAtom("Exclusion") || (lOneRow && rOneRow && joinType.IsAtom({"Inner", "Full", "Left", "Right"}))) { - if (lUnique && rUnique) - *unique = TUniqueConstraintNode::Merge(lUnique, rUnique, ctx); - else if (lUnique) + } else if (!joinType.IsAtom("Cross")) { + const bool exclusion = joinType.IsAtom("Exclusion") ; + const bool useLeft = lUnique && (rOneRow || exclusion); + const bool useRight = rUnique && (lOneRow || exclusion); + + if (useLeft && !useRight) *unique = lUnique; - else if (rUnique) + else if (useRight && !useLeft) *unique = rUnique; + else if (useLeft && useRight) + *unique = TUniqueConstraintNode::Merge(lUnique, rUnique, ctx); } } @@ -360,10 +366,10 @@ namespace { *distinct = lDistinct; else if (rightSide) *distinct = rDistinct; - } else { - const bool useBoth = bothOne && joinType.IsAtom("Inner"); - const bool useLeft = lDistinct && ((leftSide && rOneRow) || useBoth); - const bool useRight = rDistinct && ((rightSide && lOneRow) || useBoth); + } else if (!joinType.IsAtom("Cross")) { + const bool inner = joinType.IsAtom("Inner"); + const bool useLeft = lDistinct && rOneRow && (inner || leftSide); + const bool useRight = rDistinct && lOneRow && (inner || rightSide); if (useLeft && !useRight) *distinct = lDistinct; diff --git a/ydb/library/yql/providers/dq/provider/yql_dq_datasink_constraints.cpp b/ydb/library/yql/providers/dq/provider/yql_dq_datasink_constraints.cpp index f08ff6628b8..ceb82185f91 100644 --- a/ydb/library/yql/providers/dq/provider/yql_dq_datasink_constraints.cpp +++ b/ydb/library/yql/providers/dq/provider/yql_dq_datasink_constraints.cpp @@ -175,7 +175,6 @@ public: const bool lOneRow = lUnique && lUnique->HasEqualColumns(leftJoinKeys); const bool rOneRow = rUnique && rUnique->HasEqualColumns(rightJoinKeys); - const bool bothOne = lOneRow && rOneRow; const auto makeRename = [&ctx](const TExprBase& label) -> TConstraintNode::TPathReduce { if (label.Ref().IsAtom()) { @@ -199,13 +198,17 @@ public: unique = leftRename ? lUnique->RenameFields(ctx, leftRename) : lUnique; else if (rightSide && rUnique) unique = rightRename ? rUnique->RenameFields(ctx, rightRename) : rUnique; - } else if (joinType.IsAtom("Exclusion") || (lOneRow && rOneRow && joinType.IsAtom({"Inner", "Full", "Left", "Right"}))) { - if (lUnique && rUnique) - unique = TUniqueConstraintNode::Merge(leftRename ? lUnique->RenameFields(ctx, leftRename) : lUnique, rightRename ? rUnique->RenameFields(ctx, rightRename) : rUnique, ctx); - else if (lUnique) + } else { + const bool exclusion = joinType.IsAtom("Exclusion"); + const bool useLeft = lUnique && (rOneRow || exclusion); + const bool useRight = rUnique && (lOneRow || exclusion); + + if (useLeft && !useRight) unique = leftRename ? lUnique->RenameFields(ctx, leftRename) : lUnique; - else if (rUnique) + else if (useRight && !useLeft) unique = rightRename ? rUnique->RenameFields(ctx, rightRename) : rUnique; + else if (useRight && useLeft) + unique = TUniqueConstraintNode::Merge(leftRename ? lUnique->RenameFields(ctx, leftRename) : lUnique, rightRename ? rUnique->RenameFields(ctx, rightRename) : rUnique, ctx); } const auto lDistinct = join.LeftInput().Ref().GetConstraint<TDistinctConstraintNode>(); @@ -217,9 +220,9 @@ public: else if (rightSide && rDistinct) distinct = rightRename ? rDistinct->RenameFields(ctx, rightRename) : rDistinct; } else { - const bool useBoth = bothOne && joinType.IsAtom("Inner"); - const bool useLeft = lDistinct && ((leftSide && rOneRow) || useBoth); - const bool useRight = rDistinct && ((rightSide && lOneRow) || useBoth); + const bool inner = joinType.IsAtom("Inner"); + const bool useLeft = lDistinct && rOneRow && (inner || leftSide); + const bool useRight = rDistinct && lOneRow && (inner || rightSide); if (useLeft && !useRight) distinct = leftRename ? lDistinct->RenameFields(ctx, leftRename) : lDistinct; |