diff options
author | kndrvt <[email protected]> | 2025-06-20 15:36:52 +0300 |
---|---|---|
committer | kndrvt <[email protected]> | 2025-06-20 16:07:13 +0300 |
commit | 935e53d2a9ee4b43cc0548ba836b23c003c8078e (patch) | |
tree | 99fa1a3b091548f8f2d974f443b45847b9e66a1b /yql/essentials/sql/v1/sql_select.cpp | |
parent | 532fb55c30629ecb7b2720b02d446ea89ac76917 (diff) |
YQL-17269: support INTERSECT and EXCEPT without PositionalUnionAll
commit_hash:632e24794e8bcf6ef0502b7e8c031e964d28d36a
Diffstat (limited to 'yql/essentials/sql/v1/sql_select.cpp')
-rw-r--r-- | yql/essentials/sql/v1/sql_select.cpp | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/yql/essentials/sql/v1/sql_select.cpp b/yql/essentials/sql/v1/sql_select.cpp index 04a8b1e38af..b9be35f76f1 100644 --- a/yql/essentials/sql/v1/sql_select.cpp +++ b/yql/essentials/sql/v1/sql_select.cpp @@ -1368,6 +1368,7 @@ TSourcePtr TSqlSelect::Build(const TRule& node, TPosition pos, TSelectKindResult TVector<TSourcePtr> sources{ std::move(first.Source)}; bool currentQuantifier = false; + TString currentSelectOperator; for (int i = 0; i < blocks.size(); ++i) { auto& b = blocks[i]; @@ -1389,14 +1390,16 @@ TSourcePtr TSqlSelect::Build(const TRule& node, TPosition pos, TSelectKindResult } auto selectOp = b.GetRule_select_op1(); - const TString token = ToLowerUTF8(Token(selectOp.GetToken1())); - if (token == "union") { + const TString selectOperator = ToLowerUTF8(Token(selectOp.GetToken1())); + if (selectOperator == "union") { // nothing - } else if (token == "intersect" || token == "except") { - Ctx_.Error() << "INTERSECT and EXCEPT are not implemented yet"; - return nullptr; + } else if (selectOperator == "intersect" || selectOperator == "except") { + if (!IsBackwardCompatibleFeatureAvailable(Ctx_.Settings.LangVer, MakeLangVersion(2025, 3), Ctx_.Settings.BackportMode)) { + Ctx_.Error() << "INTERSECT and EXCEPT are available starting from 2025.03 version"; + return nullptr; + } } else { - Y_ABORT("You should change implementation according to grammar changes. Invalid token: %s", token.c_str()); + Y_ABORT("You should change implementation according to grammar changes. Invalid token: %s", selectOperator.c_str()); } bool quantifier = false; @@ -1411,17 +1414,19 @@ TSourcePtr TSqlSelect::Build(const TRule& node, TPosition pos, TSelectKindResult } } - if (!second && quantifier != currentQuantifier) { - auto source = BuildUnion(pos, std::move(sources), currentQuantifier, {}); + // currentSelectOperator == "" <=> second == true + if (!second && (currentSelectOperator != selectOperator || quantifier != currentQuantifier)) { + auto source = BuildSelectOp(pos, std::move(sources), currentSelectOperator, currentQuantifier, {}); sources.clear(); sources.emplace_back(std::move(source)); } sources.emplace_back(std::move(next.Source)); currentQuantifier = quantifier; + currentSelectOperator = selectOperator; } - auto result = BuildUnion(pos, std::move(sources), currentQuantifier, outermostSettings); + auto result = BuildSelectOp(pos, std::move(sources), currentSelectOperator, currentQuantifier, outermostSettings); if (orderBy) { TVector<TNodePtr> groupByExpr; |