Replace ORDER BY ALL by ORDER BY * to get rid of ambiguities

This commit is contained in:
Robert Schulze 2024-02-15 16:19:56 +00:00
parent e414384727
commit 1edf3b2254
No known key found for this signature in database
GPG Key ID: 26703B55FB13728A
12 changed files with 61 additions and 166 deletions

View File

@ -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.

View File

@ -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 *
```
等同于:

View File

@ -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<SortNode>(node, all_node->getSortDirection(), all_node->getNullsSortDirection());

View File

@ -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;

View File

@ -787,23 +787,6 @@ void expandOrderByAll(ASTSelectQuery * select_query)
for (const auto & expr : select_query->select()->children)
{
if (auto * identifier = expr->as<ASTIdentifier>(); 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<ASTFunction>(); 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<ASTOrderByElement>();
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);

View File

@ -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<ASTOrderByElement>();
s.ostr << (s.hilite ? hilite_keyword : "")

View File

@ -1,21 +1,23 @@
#include <memory>
#include <Parsers/ParserSelectQuery.h>
#include <Parsers/ASTAsterisk.h>
#include <Parsers/ASTExpressionList.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/ASTInterpolateElement.h>
#include <Parsers/ASTLiteral.h>
#include <Parsers/ASTOrderByElement.h>
#include <Parsers/ASTSelectQuery.h>
#include <Parsers/IParserBase.h>
#include <Parsers/CommonParsers.h>
#include <Parsers/ExpressionElementParsers.h>
#include <Parsers/ExpressionListParsers.h>
#include <Parsers/ParserSetQuery.h>
#include <Parsers/IParserBase.h>
#include <Parsers/ParserSampleRatio.h>
#include <Parsers/ParserSelectQuery.h>
#include <Parsers/ParserSetQuery.h>
#include <Parsers/ParserTablesInSelectQuery.h>
#include <Parsers/ParserWithElement.h>
#include <Parsers/ASTOrderByElement.h>
#include <Parsers/ASTExpressionList.h>
#include <Parsers/ASTInterpolateElement.h>
#include <Parsers/ASTIdentifier.h>
#include <Poco/String.h>
#include <memory>
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<ASTOrderByElement>()->children[0]->as<ASTIdentifier>();
if (identifier != nullptr && Poco::toUpper(identifier->name()) == "ALL")
/// ORDER BY *
auto * asterisk = order_expression_list->children[0]->as<ASTOrderByElement>()->children[0]->as<ASTAsterisk>();
if (asterisk != nullptr)
select_query->order_by_all = true;
}
}

View File

@ -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';

View File

@ -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

View File

@ -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

View File

@ -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 }

View File

@ -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';