diff options
author | kndrvt <[email protected]> | 2025-06-30 14:40:06 +0300 |
---|---|---|
committer | kndrvt <[email protected]> | 2025-06-30 15:05:46 +0300 |
commit | 118cd9ce9b40173fc06e327961e4d38d2dc727a8 (patch) | |
tree | cdf2b6ae29517744b64004251677eb100577f8c0 /yql/essentials/sql/v1/sql_select.cpp | |
parent | a3de1fc96221b7276abf4cf89e13e2fa6a5724d6 (diff) |
YQL-17269: restrict multiple INTERSECT and EXCEPT
commit_hash:635c8def3bba6890d2d80b418fca9bec6cbd4b73
Diffstat (limited to 'yql/essentials/sql/v1/sql_select.cpp')
-rw-r--r-- | yql/essentials/sql/v1/sql_select.cpp | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/yql/essentials/sql/v1/sql_select.cpp b/yql/essentials/sql/v1/sql_select.cpp index b9be35f76f1..51894a2bda8 100644 --- a/yql/essentials/sql/v1/sql_select.cpp +++ b/yql/essentials/sql/v1/sql_select.cpp @@ -1359,7 +1359,7 @@ TSourcePtr TSqlSelect::Build(const TRule& node, TPosition pos, TSelectKindResult auto blocks = node.GetBlock2(); - TPosition unionPos = pos; // Position of first select + TPosition opPos = pos; // Position of first select TVector<TSortSpecificationPtr> orderBy; bool assumeOrderBy = false; TNodePtr skipTake; @@ -1372,7 +1372,7 @@ TSourcePtr TSqlSelect::Build(const TRule& node, TPosition pos, TSelectKindResult for (int i = 0; i < blocks.size(); ++i) { auto& b = blocks[i]; - const bool second = (i == 0); + const bool first = (i == 0); const bool last = (i + 1 == blocks.size()); TSelectKindPlacement placement; placement.IsLastInSelectOp = last; @@ -1395,7 +1395,7 @@ TSourcePtr TSqlSelect::Build(const TRule& node, TPosition pos, TSelectKindResult // nothing } 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"; + Ctx_.Error() << "INTERSECT and EXCEPT are available starting from 2025.03 version."; return nullptr; } } else { @@ -1414,11 +1414,23 @@ TSourcePtr TSqlSelect::Build(const TRule& node, TPosition pos, TSelectKindResult } } - // 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)); + // currentSelectOperator == "" <=> first == true + if (!first) { + if (currentSelectOperator == selectOperator) { + if (currentSelectOperator == "union") { + if (currentQuantifier != quantifier) { + auto source = BuildSelectOp(pos, std::move(sources), currentSelectOperator, currentQuantifier, {}); + sources.clear(); + sources.emplace_back(std::move(source)); + } + } else { + Ctx_.Error() << "Multiple usage of INTERSECT and EXCEPT is not implemented yet."; + return nullptr; + } + } else { + Ctx_.Error() << "Simultaneous usage of UNION, INTERSECT, and EXCEPT is not implemented yet."; + return nullptr; + } } sources.emplace_back(std::move(next.Source)); @@ -1442,15 +1454,15 @@ TSourcePtr TSqlSelect::Build(const TRule& node, TPosition pos, TSelectKindResult bool stream = false; TVector<TNodePtr> terms; - terms.push_back(BuildColumn(unionPos, "*", "")); + terms.push_back(BuildColumn(opPos, "*", "")); - result = BuildSelectCore(Ctx_, unionPos, std::move(result), groupByExpr, groupBy, compactGroupBy, groupBySuffix, + result = BuildSelectCore(Ctx_, opPos, std::move(result), groupByExpr, groupBy, compactGroupBy, groupBySuffix, assumeOrderBy, orderBy, having, std::move(winSpecs), legacyHoppingWindowSpec, std::move(terms), distinct, std::move(without), forceWithout, stream, outermostSettings, {}, {}); - result = BuildSelect(unionPos, std::move(result), skipTake); + result = BuildSelect(opPos, std::move(result), skipTake); } else if (skipTake) { - result = BuildSelect(unionPos, std::move(result), skipTake); + result = BuildSelect(opPos, std::move(result), skipTake); } return result; |