From 1edf3b2254b1300308f3f8691de94f100e900098 Mon Sep 17 00:00:00 2001 From: Robert Schulze Date: Thu, 15 Feb 2024 16:19:56 +0000 Subject: [PATCH] Replace ORDER BY ALL by ORDER BY * to get rid of ambiguities --- .../statements/select/order-by.md | 3 +- .../statements/select/order-by.md | 6 +- src/Analyzer/Passes/QueryAnalysisPass.cpp | 3 - src/Analyzer/QueryNode.h | 4 +- src/Interpreters/TreeRewriter.cpp | 19 +--- src/Parsers/ASTSelectQuery.cpp | 2 +- src/Parsers/ParserSelectQuery.cpp | 24 ++--- .../0_stateless/02567_and_consistency.sql | 10 +- .../02884_string_distance_function.sql | 14 +-- .../0_stateless/02943_order_by_all.reference | 34 +------ .../0_stateless/02943_order_by_all.sql | 96 ++++--------------- .../02962_join_using_bug_57894.sql | 12 +-- 12 files changed, 61 insertions(+), 166 deletions(-) diff --git a/docs/en/sql-reference/statements/select/order-by.md b/docs/en/sql-reference/statements/select/order-by.md index bea5dcab461..29aca70762e 100644 --- a/docs/en/sql-reference/statements/select/order-by.md +++ b/docs/en/sql-reference/statements/select/order-by.md @@ -9,10 +9,9 @@ The `ORDER BY` clause contains - a list of expressions, e.g. `ORDER BY visits, search_phrase`, - a list of numbers referring to columns in the `SELECT` clause, e.g. `ORDER BY 2, 1`, or -- `ALL` (without other expressions or numbers) which means all columns of the `SELECT` clause: `ORDER BY ALL`. +- `*` (without other expressions or numbers) which means all columns of the `SELECT` clause: `ORDER BY *`. To disable sorting by column numbers, set setting [enable_positional_arguments](../../../operations/settings/settings.md#enable-positional-arguments) = 0. -`ORDER BY ALL` cannot be used when the `SELECT` clause contains identifiers or aliases named `all` (case-insensitively). The `ORDER BY` clause can be attributed by a `DESC` (descending) or `ASC` (ascending) modifier which determines the sorting direction. Unless an explicit sort order is specified, `ASC` is used by default. diff --git a/docs/zh/sql-reference/statements/select/order-by.md b/docs/zh/sql-reference/statements/select/order-by.md index 3286fc9f9e7..9540c96a10d 100644 --- a/docs/zh/sql-reference/statements/select/order-by.md +++ b/docs/zh/sql-reference/statements/select/order-by.md @@ -61,14 +61,14 @@ sidebar_label: ORDER BY 我们只建议使用 `COLLATE` 对于少量行的最终排序,因为排序与 `COLLATE` 比正常的按字节排序效率低。 -## ORDER BY ALL +## ORDER BY * -`ORDER BY ALL` 对所有选定的列进行升序排序。 +`ORDER BY *` 对所有选定的列进行升序排序。 示例: ``` sql -SELECT a, b, c FROM t ORDER BY ALL +SELECT a, b, c FROM t ORDER BY * ``` 等同于: diff --git a/src/Analyzer/Passes/QueryAnalysisPass.cpp b/src/Analyzer/Passes/QueryAnalysisPass.cpp index a2c719606d8..f93f7cf2a25 100644 --- a/src/Analyzer/Passes/QueryAnalysisPass.cpp +++ b/src/Analyzer/Passes/QueryAnalysisPass.cpp @@ -2357,9 +2357,6 @@ void QueryAnalyzer::expandOrderByAll(QueryNode & query_tree_node_typed) throw Exception(ErrorCodes::LOGICAL_ERROR, "Expression nodes list expected 1 projection names. Actual {}", projection_names.size()); - if (Poco::toUpper(projection_names[0]) == "ALL") - throw Exception(ErrorCodes::UNEXPECTED_EXPRESSION, - "Cannot use ORDER BY ALL to sort a column with name 'all', please disable setting `enable_order_by_all` and try again"); } auto sort_node = std::make_shared(node, all_node->getSortDirection(), all_node->getNullsSortDirection()); diff --git a/src/Analyzer/QueryNode.h b/src/Analyzer/QueryNode.h index d8b8741afb2..1b389572e42 100644 --- a/src/Analyzer/QueryNode.h +++ b/src/Analyzer/QueryNode.h @@ -219,13 +219,13 @@ public: is_group_by_all = is_group_by_all_value; } - /// Returns true, if query node has ORDER BY ALL modifier, false otherwise + /// Returns true, if query node has ORDER BY * modifier, false otherwise bool isOrderByAll() const { return is_order_by_all; } - /// Set query node ORDER BY ALL modifier value + /// Set query node ORDER BY * modifier value void setIsOrderByAll(bool is_order_by_all_value) { is_order_by_all = is_order_by_all_value; diff --git a/src/Interpreters/TreeRewriter.cpp b/src/Interpreters/TreeRewriter.cpp index 0a260969cd4..14fbc9ebebb 100644 --- a/src/Interpreters/TreeRewriter.cpp +++ b/src/Interpreters/TreeRewriter.cpp @@ -787,23 +787,6 @@ void expandOrderByAll(ASTSelectQuery * select_query) for (const auto & expr : select_query->select()->children) { - if (auto * identifier = expr->as(); identifier != nullptr) - { - if (identifier->alias.empty()) - { - if (Poco::toUpper(identifier->name()) == "ALL") - throw Exception(ErrorCodes::UNEXPECTED_EXPRESSION, "Cannot use ORDER BY ALL to sort a column with name 'all'"); - } - else - { - if (Poco::toUpper(identifier->alias) == "ALL") - throw Exception(ErrorCodes::UNEXPECTED_EXPRESSION, "Cannot use ORDER BY ALL to sort a column alias with name 'all'"); - } - } - if (auto * function = expr->as(); function != nullptr) - if (Poco::toUpper(function->alias) == "ALL") - throw Exception(ErrorCodes::UNEXPECTED_EXPRESSION, "Cannot use ORDER BY ALL to sort an expression with name 'all'"); - auto elem = std::make_shared(); elem->direction = all_elem->direction; elem->nulls_direction = all_elem->nulls_direction; @@ -1330,7 +1313,7 @@ TreeRewriterResultPtr TreeRewriter::analyzeSelect( if (select_query->group_by_all) expandGroupByAll(select_query); - // expand ORDER BY ALL + // expand ORDER BY * if (select_query->order_by_all) expandOrderByAll(select_query); diff --git a/src/Parsers/ASTSelectQuery.cpp b/src/Parsers/ASTSelectQuery.cpp index 2115de1c124..d38e0933981 100644 --- a/src/Parsers/ASTSelectQuery.cpp +++ b/src/Parsers/ASTSelectQuery.cpp @@ -165,7 +165,7 @@ void ASTSelectQuery::formatImpl(const FormatSettings & s, FormatState & state, F if (order_by_all) { - s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << "ORDER BY ALL" << (s.hilite ? hilite_none : ""); + s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << "ORDER BY *" << (s.hilite ? hilite_none : ""); auto * elem = orderBy()->children[0]->as(); s.ostr << (s.hilite ? hilite_keyword : "") diff --git a/src/Parsers/ParserSelectQuery.cpp b/src/Parsers/ParserSelectQuery.cpp index 641e74b5f18..6397a2a2a55 100644 --- a/src/Parsers/ParserSelectQuery.cpp +++ b/src/Parsers/ParserSelectQuery.cpp @@ -1,21 +1,23 @@ -#include +#include + +#include +#include +#include +#include #include +#include #include -#include #include #include #include -#include +#include #include -#include +#include #include #include -#include -#include -#include -#include #include +#include namespace DB { @@ -290,9 +292,9 @@ bool ParserSelectQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) } else if (order_expression_list->children.size() == 1) { - /// ORDER BY ALL - auto * identifier = order_expression_list->children[0]->as()->children[0]->as(); - if (identifier != nullptr && Poco::toUpper(identifier->name()) == "ALL") + /// ORDER BY * + auto * asterisk = order_expression_list->children[0]->as()->children[0]->as(); + if (asterisk != nullptr) select_query->order_by_all = true; } } diff --git a/tests/queries/0_stateless/02567_and_consistency.sql b/tests/queries/0_stateless/02567_and_consistency.sql index 0eeab99e539..b1fa526e33f 100644 --- a/tests/queries/0_stateless/02567_and_consistency.sql +++ b/tests/queries/0_stateless/02567_and_consistency.sql @@ -5,7 +5,7 @@ FROM ) GROUP BY number HAVING 1 AND sin(sum(number)) -ORDER BY ALL +ORDER BY * SETTINGS enable_optimize_predicate_expression = 0; SELECT '====='; @@ -17,7 +17,7 @@ FROM ) GROUP BY number HAVING 1 AND sin(1) -ORDER BY ALL +ORDER BY * SETTINGS enable_optimize_predicate_expression = 0; SELECT '====='; @@ -29,7 +29,7 @@ FROM ) GROUP BY number HAVING x AND sin(sum(number)) -ORDER BY ALL +ORDER BY * SETTINGS enable_optimize_predicate_expression = 1; SELECT '====='; @@ -41,7 +41,7 @@ FROM ) GROUP BY number HAVING 1 AND sin(sum(number)) -ORDER BY ALL +ORDER BY * SETTINGS enable_optimize_predicate_expression = 0; SELECT '====='; @@ -61,7 +61,7 @@ FROM ) GROUP BY number HAVING 1 AND sin(sum(number)) -ORDER BY ALL +ORDER BY * SETTINGS enable_optimize_predicate_expression = 1; select '#45440'; diff --git a/tests/queries/0_stateless/02884_string_distance_function.sql b/tests/queries/0_stateless/02884_string_distance_function.sql index fddbf41f0e5..95604c6f401 100644 --- a/tests/queries/0_stateless/02884_string_distance_function.sql +++ b/tests/queries/0_stateless/02884_string_distance_function.sql @@ -29,13 +29,13 @@ CREATE TABLE t INSERT INTO t VALUES ('', '') ('abc', '') ('', 'abc') ('abc', 'abc') ('abc', 'ab') ('abc', 'bc') ('clickhouse', 'mouse'); SELECT '-- non-const arguments'; -SELECT 'byteHammingDistance', s1, s2, byteHammingDistance(s1, s2) FROM t ORDER BY ALL; -SELECT 'editDistance', s1, s2, editDistance(s1, s2) FROM t ORDER BY ALL; -SELECT 'damerauLevenshteinDistance', s1, s2, damerauLevenshteinDistance(s1, s2) FROM t ORDER BY ALL; -SELECT 'stringJaccardIndex', s1, s2, stringJaccardIndex(s1, s2) FROM t ORDER BY ALL; -SELECT 'stringJaccardIndexUTF8', s1, s2, stringJaccardIndexUTF8(s1, s2) FROM t ORDER BY ALL; -SELECT 'jaroSimilarity', s1, s2, jaroSimilarity(s1, s2) FROM t ORDER BY ALL; -SELECT 'jaroWinklerSimilarity', s1, s2, jaroWinklerSimilarity(s1, s2) FROM t ORDER BY ALL; +SELECT 'byteHammingDistance', s1, s2, byteHammingDistance(s1, s2) FROM t ORDER BY *; +SELECT 'editDistance', s1, s2, editDistance(s1, s2) FROM t ORDER BY *; +SELECT 'damerauLevenshteinDistance', s1, s2, damerauLevenshteinDistance(s1, s2) FROM t ORDER BY *; +SELECT 'stringJaccardIndex', s1, s2, stringJaccardIndex(s1, s2) FROM t ORDER BY *; +SELECT 'stringJaccardIndexUTF8', s1, s2, stringJaccardIndexUTF8(s1, s2) FROM t ORDER BY *; +SELECT 'jaroSimilarity', s1, s2, jaroSimilarity(s1, s2) FROM t ORDER BY *; +SELECT 'jaroWinklerSimilarity', s1, s2, jaroWinklerSimilarity(s1, s2) FROM t ORDER BY *; SELECT '-- Special UTF-8 tests'; -- We do not perform full UTF8 validation, so sometimes it just returns some result diff --git a/tests/queries/0_stateless/02943_order_by_all.reference b/tests/queries/0_stateless/02943_order_by_all.reference index d91f6dfc4a5..ef399fe8e2d 100644 --- a/tests/queries/0_stateless/02943_order_by_all.reference +++ b/tests/queries/0_stateless/02943_order_by_all.reference @@ -49,39 +49,9 @@ A 2 2 A 3 B \N C --- "ALL" in ORDER BY is case-insensitive +-- Special case: all columns in SELECT clause, ORDER BY * A 2 B 3 C \N D 1 -A 2 -B 3 -C \N -D 1 -A 2 -B 3 -C \N -D 1 -A 2 -B 3 -C \N -D 1 --- If "all" (case-insensitive) appears in the SELECT clause, throw an error because of ambiguity --- If ORDER BY contains "ALL" plus other columns, then "ALL" loses its special meaning -B 3 10 -D 1 20 -A 2 30 -C \N 40 -B 3 10 -D 1 20 -A 2 30 -C \N 40 --- test SELECT * ORDER BY ALL (only works if the SELECT column contains no "all" column) -A 2 30 -B 3 10 -C \N 40 -D 1 20 -A 2 30 -B 3 10 -C \N 40 -D 1 20 +-- "*" must appear stand-alone in ORDER BY diff --git a/tests/queries/0_stateless/02943_order_by_all.sql b/tests/queries/0_stateless/02943_order_by_all.sql index f10184e79b9..2fe628e9b95 100644 --- a/tests/queries/0_stateless/02943_order_by_all.sql +++ b/tests/queries/0_stateless/02943_order_by_all.sql @@ -1,4 +1,4 @@ --- Tests that sort expression ORDER BY ALL +-- Tests that sort expression ORDER BY * DROP TABLE IF EXISTS order_by_all; @@ -6,104 +6,48 @@ CREATE TABLE order_by_all ( a String, b Nullable(Int32), - all UInt64, ) ENGINE = Memory; -INSERT INTO order_by_all VALUES ('B', 3, 10), ('C', NULL, 40), ('D', 1, 20), ('A', 2, 30); +INSERT INTO order_by_all VALUES ('B', 3), ('C', NULL), ('D', 1), ('A', 2); SELECT '-- no modifiers'; SET allow_experimental_analyzer = 0; -SELECT a, b FROM order_by_all ORDER BY ALL; -SELECT b, a FROM order_by_all ORDER BY ALL; +SELECT a, b FROM order_by_all ORDER BY *; +SELECT b, a FROM order_by_all ORDER BY *; SET allow_experimental_analyzer = 1; -SELECT a, b FROM order_by_all ORDER BY ALL; -SELECT b, a FROM order_by_all ORDER BY ALL; +SELECT a, b FROM order_by_all ORDER BY *; +SELECT b, a FROM order_by_all ORDER BY *; SELECT '-- with ASC/DESC modifiers'; SET allow_experimental_analyzer = 0; -SELECT a, b FROM order_by_all ORDER BY ALL ASC; -SELECT a, b FROM order_by_all ORDER BY ALL DESC; +SELECT a, b FROM order_by_all ORDER BY * ASC; +SELECT a, b FROM order_by_all ORDER BY * DESC; SET allow_experimental_analyzer = 1; -SELECT a, b FROM order_by_all ORDER BY ALL ASC; -SELECT a, b FROM order_by_all ORDER BY ALL DESC; +SELECT a, b FROM order_by_all ORDER BY * ASC; +SELECT a, b FROM order_by_all ORDER BY * DESC; SELECT '-- with NULLS FIRST/LAST modifiers'; SET allow_experimental_analyzer = 0; -SELECT b, a FROM order_by_all ORDER BY ALL NULLS FIRST; -SELECT b, a FROM order_by_all ORDER BY ALL NULLS LAST; +SELECT b, a FROM order_by_all ORDER BY * NULLS FIRST; +SELECT b, a FROM order_by_all ORDER BY * NULLS LAST; SET allow_experimental_analyzer = 1; -SELECT b, a FROM order_by_all ORDER BY ALL NULLS FIRST; -SELECT b, a FROM order_by_all ORDER BY ALL NULLS LAST; +SELECT b, a FROM order_by_all ORDER BY * NULLS FIRST; +SELECT b, a FROM order_by_all ORDER BY * NULLS LAST; -SELECT '-- "ALL" in ORDER BY is case-insensitive'; +SELECT '-- Special case: all columns in SELECT clause, ORDER BY *'; +SELECT * FROM order_by_all ORDER BY * NULLS LAST; + +SELECT '-- "*" must appear stand-alone in ORDER BY'; SET allow_experimental_analyzer = 0; -SELECT a, b FROM order_by_all ORDER BY ALL; -SELECT a, b FROM order_by_all ORDER BY all; +SELECT a, b FROM order_by_all ORDER BY *, a; -- { serverError UNKNOWN_IDENTIFIER } SET allow_experimental_analyzer = 1; -SELECT a, b FROM order_by_all ORDER BY ALL; -SELECT a, b FROM order_by_all ORDER BY all; - -SELECT '-- If "all" (case-insensitive) appears in the SELECT clause, throw an error because of ambiguity'; - --- columns - -SET allow_experimental_analyzer = 0; -SELECT a, b, all FROM order_by_all ORDER BY ALL; -- { serverError UNEXPECTED_EXPRESSION } - -SET allow_experimental_analyzer = 1; -SELECT a, b, all FROM order_by_all ORDER BY ALL; -- { serverError UNEXPECTED_EXPRESSION } - --- column aliases - -SET allow_experimental_analyzer = 0; -SELECT a, b AS all FROM order_by_all ORDER BY ALL; -- { serverError UNEXPECTED_EXPRESSION } - -SET allow_experimental_analyzer = 1; -SELECT a, b AS all FROM order_by_all ORDER BY ALL; -- { serverError UNEXPECTED_EXPRESSION } - --- expressions - -SET allow_experimental_analyzer = 0; -SELECT format('{} {}', a, b) AS all FROM order_by_all ORDER BY ALL; -- { serverError UNEXPECTED_EXPRESSION } - -SET allow_experimental_analyzer = 1; -SELECT format('{} {}', a, b) AS all FROM order_by_all ORDER BY ALL; -- { serverError UNEXPECTED_EXPRESSION } - -SELECT '-- If ORDER BY contains "ALL" plus other columns, then "ALL" loses its special meaning'; - -SET allow_experimental_analyzer = 0; -SELECT a, b, all FROM order_by_all ORDER BY all, a; - -SET allow_experimental_analyzer = 1; -SELECT a, b, all FROM order_by_all ORDER BY all, a; - -DROP TABLE order_by_all; - -SELECT '-- test SELECT * ORDER BY ALL (only works if the SELECT column contains no "all" column)'; - -CREATE TABLE order_by_all -( - a String, - b Nullable(Int32), - c UInt64, -) -ENGINE = Memory; - -INSERT INTO order_by_all VALUES ('B', 3, 10), ('C', NULL, 40), ('D', 1, 20), ('A', 2, 30); - -SET allow_experimental_analyzer = 0; -SELECT * FROM order_by_all ORDER BY ALL; - -SET allow_experimental_analyzer = 1; -SELECT * FROM order_by_all ORDER BY ALL; - -DROP TABLE order_by_all; +SELECT a, b FROM order_by_all ORDER BY *, a; -- { serverError UNSUPPORTED_METHOD } diff --git a/tests/queries/0_stateless/02962_join_using_bug_57894.sql b/tests/queries/0_stateless/02962_join_using_bug_57894.sql index 87aef8b1a71..c9570be7053 100644 --- a/tests/queries/0_stateless/02962_join_using_bug_57894.sql +++ b/tests/queries/0_stateless/02962_join_using_bug_57894.sql @@ -11,23 +11,23 @@ INSERT INTO r VALUES (NULL, NULL); SET allow_experimental_analyzer = 0; -SELECT x FROM t FULL JOIN r USING (x) ORDER BY ALL +SELECT x FROM t FULL JOIN r USING (x) ORDER BY * ; -SELECT x FROM t FULL JOIN r USING (x) ORDER BY ALL +SELECT x FROM t FULL JOIN r USING (x) ORDER BY * SETTINGS join_algorithm = 'partial_merge'; -SELECT x FROM t FULL JOIN r USING (x) ORDER BY ALL +SELECT x FROM t FULL JOIN r USING (x) ORDER BY * SETTINGS join_algorithm = 'full_sorting_merge'; SET allow_experimental_analyzer = 1; -SELECT x FROM t FULL JOIN r USING (x) ORDER BY ALL +SELECT x FROM t FULL JOIN r USING (x) ORDER BY * ; -SELECT x FROM t FULL JOIN r USING (x) ORDER BY ALL +SELECT x FROM t FULL JOIN r USING (x) ORDER BY * SETTINGS join_algorithm = 'partial_merge'; -SELECT x FROM t FULL JOIN r USING (x) ORDER BY ALL +SELECT x FROM t FULL JOIN r USING (x) ORDER BY * SETTINGS join_algorithm = 'full_sorting_merge';