mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-25 17:12:03 +00:00
Replace ORDER BY ALL by ORDER BY * to get rid of ambiguities
This commit is contained in:
parent
e414384727
commit
1edf3b2254
@ -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.
|
||||
|
@ -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 *
|
||||
```
|
||||
|
||||
等同于:
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 : "")
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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';
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 }
|
||||
|
@ -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';
|
||||
|
Loading…
Reference in New Issue
Block a user