mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 08:32:02 +00:00
Fix
This commit is contained in:
parent
7be06f894e
commit
512d66a088
@ -162,8 +162,10 @@ ExpressionAnalyzer::ExpressionAnalyzer(
|
|||||||
analyzeAggregation();
|
analyzeAggregation();
|
||||||
}
|
}
|
||||||
|
|
||||||
static ASTPtr checkPositionalArgument(ASTPtr argument, const NamesAndTypesList & columns)
|
static ASTPtr checkPositionalArgument(ASTPtr argument, const ASTSelectQuery * select_query, ASTSelectQuery::Expression expression)
|
||||||
{
|
{
|
||||||
|
auto columns = select_query->select()->children;
|
||||||
|
|
||||||
/// Case when GROUP BY element is position.
|
/// Case when GROUP BY element is position.
|
||||||
/// Do not consider case when GROUP BY element is not a literal, but expression, even if all values are constants.
|
/// Do not consider case when GROUP BY element is not a literal, but expression, even if all values are constants.
|
||||||
if (auto * ast_literal = typeid_cast<const ASTLiteral *>(argument.get()))
|
if (auto * ast_literal = typeid_cast<const ASTLiteral *>(argument.get()))
|
||||||
@ -174,9 +176,19 @@ static ASTPtr checkPositionalArgument(ASTPtr argument, const NamesAndTypesList &
|
|||||||
auto pos = ast_literal->value.get<UInt64>();
|
auto pos = ast_literal->value.get<UInt64>();
|
||||||
if ((0 < pos) && (pos <= columns.size()))
|
if ((0 < pos) && (pos <= columns.size()))
|
||||||
{
|
{
|
||||||
const auto & column_name = std::next(columns.begin(), pos - 1)->name;
|
--pos;
|
||||||
return std::make_shared<ASTIdentifier>(column_name);
|
const auto & column = columns[pos];
|
||||||
|
if (const auto * literal_ast = typeid_cast<const ASTIdentifier *>(column.get()))
|
||||||
|
{
|
||||||
|
return std::make_shared<ASTIdentifier>(literal_ast->name());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Illegal value for positional argument in {}",
|
||||||
|
ASTSelectQuery::expressionToString(expression));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
/// Do not throw if out of bounds, see appendUnusedGroupByColumn.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -257,7 +269,6 @@ void ExpressionAnalyzer::analyzeAggregation()
|
|||||||
{
|
{
|
||||||
NameSet unique_keys;
|
NameSet unique_keys;
|
||||||
ASTs & group_asts = select_query->groupBy()->children;
|
ASTs & group_asts = select_query->groupBy()->children;
|
||||||
const auto & columns = syntax->source_columns;
|
|
||||||
|
|
||||||
for (ssize_t i = 0; i < ssize_t(group_asts.size()); ++i)
|
for (ssize_t i = 0; i < ssize_t(group_asts.size()); ++i)
|
||||||
{
|
{
|
||||||
@ -266,7 +277,7 @@ void ExpressionAnalyzer::analyzeAggregation()
|
|||||||
|
|
||||||
if (getContext()->getSettingsRef().enable_positional_arguments)
|
if (getContext()->getSettingsRef().enable_positional_arguments)
|
||||||
{
|
{
|
||||||
auto new_argument = checkPositionalArgument(group_asts[i], columns);
|
auto new_argument = checkPositionalArgument(group_asts[i], select_query, ASTSelectQuery::Expression::GROUP_BY);
|
||||||
if (new_argument)
|
if (new_argument)
|
||||||
group_asts[i] = new_argument;
|
group_asts[i] = new_argument;
|
||||||
}
|
}
|
||||||
@ -1252,7 +1263,6 @@ ActionsDAGPtr SelectQueryExpressionAnalyzer::appendOrderBy(ExpressionActionsChai
|
|||||||
|
|
||||||
bool with_fill = false;
|
bool with_fill = false;
|
||||||
NameSet order_by_keys;
|
NameSet order_by_keys;
|
||||||
const auto & columns = syntax->source_columns;
|
|
||||||
|
|
||||||
for (auto & child : select_query->orderBy()->children)
|
for (auto & child : select_query->orderBy()->children)
|
||||||
{
|
{
|
||||||
@ -1262,7 +1272,7 @@ ActionsDAGPtr SelectQueryExpressionAnalyzer::appendOrderBy(ExpressionActionsChai
|
|||||||
|
|
||||||
if (getContext()->getSettingsRef().enable_positional_arguments)
|
if (getContext()->getSettingsRef().enable_positional_arguments)
|
||||||
{
|
{
|
||||||
auto new_argument = checkPositionalArgument(ast->children.at(0), columns);
|
auto new_argument = checkPositionalArgument(ast->children.at(0), select_query, ASTSelectQuery::Expression::ORDER_BY);
|
||||||
if (new_argument)
|
if (new_argument)
|
||||||
ast->children[0] = new_argument;
|
ast->children[0] = new_argument;
|
||||||
}
|
}
|
||||||
@ -1317,13 +1327,12 @@ bool SelectQueryExpressionAnalyzer::appendLimitBy(ExpressionActionsChain & chain
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto & children = select_query->limitBy()->children;
|
auto & children = select_query->limitBy()->children;
|
||||||
const auto & columns = syntax->source_columns;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < children.size(); ++i)
|
for (size_t i = 0; i < children.size(); ++i)
|
||||||
{
|
{
|
||||||
if (getContext()->getSettingsRef().enable_positional_arguments)
|
if (getContext()->getSettingsRef().enable_positional_arguments)
|
||||||
{
|
{
|
||||||
auto new_argument = checkPositionalArgument(children[i], columns);
|
auto new_argument = checkPositionalArgument(children[i], select_query, ASTSelectQuery::Expression::LIMIT_BY);
|
||||||
if (new_argument)
|
if (new_argument)
|
||||||
children[i] = new_argument;
|
children[i] = new_argument;
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,43 @@ public:
|
|||||||
SETTINGS
|
SETTINGS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static String expressionToString(Expression expr)
|
||||||
|
{
|
||||||
|
switch (expr)
|
||||||
|
{
|
||||||
|
case Expression::WITH:
|
||||||
|
return "WITH";
|
||||||
|
case Expression::SELECT:
|
||||||
|
return "SELECT";
|
||||||
|
case Expression::TABLES:
|
||||||
|
return "TABLES";
|
||||||
|
case Expression::PREWHERE:
|
||||||
|
return "PREWHERE";
|
||||||
|
case Expression::WHERE:
|
||||||
|
return "WHERE";
|
||||||
|
case Expression::GROUP_BY:
|
||||||
|
return "GROUP BY";
|
||||||
|
case Expression::HAVING:
|
||||||
|
return "HAVING";
|
||||||
|
case Expression::WINDOW:
|
||||||
|
return "WINDOW";
|
||||||
|
case Expression::ORDER_BY:
|
||||||
|
return "ORDER BY";
|
||||||
|
case Expression::LIMIT_BY_OFFSET:
|
||||||
|
return "LIMIT BY OFFSET";
|
||||||
|
case Expression::LIMIT_BY_LENGTH:
|
||||||
|
return "LIMIT BY LENGTH";
|
||||||
|
case Expression::LIMIT_BY:
|
||||||
|
return "LIMIT BY";
|
||||||
|
case Expression::LIMIT_OFFSET:
|
||||||
|
return "LIMIT OFFSET";
|
||||||
|
case Expression::LIMIT_LENGTH:
|
||||||
|
return "LIMIT LENGTH";
|
||||||
|
case Expression::SETTINGS:
|
||||||
|
return "SETTINGS";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Get the text that identifies this element. */
|
/** Get the text that identifies this element. */
|
||||||
String getID(char) const override { return "SelectQuery"; }
|
String getID(char) const override { return "SelectQuery"; }
|
||||||
|
|
||||||
|
@ -1,90 +1,50 @@
|
|||||||
-- { echo }
|
-- { echo }
|
||||||
set enable_positional_arguments = 1;
|
select x3, x2, x1 from test order by 1;
|
||||||
drop table if exists test;
|
1 100 100
|
||||||
create table test (col1 Int32, col2 Int32, col3 Int32) engine = Memory();
|
10 1 10
|
||||||
insert into test select number, number, 5 from numbers(2);
|
100 10 1
|
||||||
insert into test select number, number, 4 from numbers(2);
|
select x3, x2, x1 from test order by x3;
|
||||||
insert into test select number, number, 3 from numbers(2);
|
1 100 100
|
||||||
insert into test select number, number, 2 from numbers(2);
|
10 1 10
|
||||||
insert into test select number, number, 1 from numbers(2);
|
100 10 1
|
||||||
select * from test where col1 = 1 order by 3 desc;
|
select x3, x2, x1 from test order by 1 desc;
|
||||||
1 1 5
|
100 10 1
|
||||||
1 1 4
|
10 1 10
|
||||||
1 1 3
|
1 100 100
|
||||||
1 1 2
|
select x3, x2, x1 from test order by x3 desc;
|
||||||
1 1 1
|
100 10 1
|
||||||
select * from test where col2 = 1 order by 3 asc;
|
10 1 10
|
||||||
1 1 1
|
1 100 100
|
||||||
1 1 2
|
insert into test values (1, 10, 200), (10, 1, 200), (100, 100, 1);
|
||||||
1 1 3
|
select x3, x2 from test group by x3, x2;
|
||||||
1 1 4
|
200 1
|
||||||
1 1 5
|
10 1
|
||||||
insert into test select number, number+1, 1 from numbers(2);
|
200 10
|
||||||
insert into test select number, number+1, 2 from numbers(2);
|
1 100
|
||||||
insert into test select number, number+1, 3 from numbers(2);
|
100 10
|
||||||
insert into test select number, number+1, 4 from numbers(2);
|
select x3, x2 from test group by 1, 2;
|
||||||
insert into test select number, number+1, 5 from numbers(2);
|
200 1
|
||||||
select * from test order by col1, col2, col3 asc limit 2 by col2;
|
10 1
|
||||||
0 0 1
|
200 10
|
||||||
0 0 2
|
1 100
|
||||||
0 1 1
|
100 10
|
||||||
0 1 2
|
select x1, x2, x3 from test order by x3 limit 1 by x3;
|
||||||
1 2 1
|
100 100 1
|
||||||
1 2 2
|
10 1 10
|
||||||
select * from test order by 1, 2, 3 asc limit 2 by 2;
|
1 10 100
|
||||||
0 0 1
|
1 10 200
|
||||||
0 0 2
|
select x1, x2, x3 from test order by 3 limit 1 by 3;
|
||||||
0 1 1
|
100 100 1
|
||||||
0 1 2
|
10 1 10
|
||||||
1 2 1
|
1 10 100
|
||||||
1 2 2
|
1 10 200
|
||||||
select col1, col2 from test group by col1, col2 order by col1, col2;
|
select x1, x2, x3 from test order by x3 limit 1 by x1;
|
||||||
0 0
|
100 100 1
|
||||||
0 1
|
10 1 10
|
||||||
1 1
|
1 10 100
|
||||||
1 2
|
select x1, x2, x3 from test order by 3 limit 1 by 1;
|
||||||
select col1, col2 from test group by 1, 2 order by 1, 2;
|
100 100 1
|
||||||
0 0
|
10 1 10
|
||||||
0 1
|
1 10 100
|
||||||
1 1
|
select max(x3), max(x2), max(x1) from test group by 1; -- { serverError 43 }
|
||||||
1 2
|
select max(x1) from test order by 1; -- { serverError 43 }
|
||||||
select col2, col3 from test group by col3, col2 order by col3, col2;
|
|
||||||
0 1
|
|
||||||
1 1
|
|
||||||
2 1
|
|
||||||
0 2
|
|
||||||
1 2
|
|
||||||
2 2
|
|
||||||
0 3
|
|
||||||
1 3
|
|
||||||
2 3
|
|
||||||
0 4
|
|
||||||
1 4
|
|
||||||
2 4
|
|
||||||
0 5
|
|
||||||
1 5
|
|
||||||
2 5
|
|
||||||
select col2, col3 from test group by 3, 2 order by 3, 2;
|
|
||||||
0 1
|
|
||||||
1 1
|
|
||||||
2 1
|
|
||||||
0 2
|
|
||||||
1 2
|
|
||||||
2 2
|
|
||||||
0 3
|
|
||||||
1 3
|
|
||||||
2 3
|
|
||||||
0 4
|
|
||||||
1 4
|
|
||||||
2 4
|
|
||||||
0 5
|
|
||||||
1 5
|
|
||||||
2 5
|
|
||||||
select col2 from test group by 2 order by 2;
|
|
||||||
0
|
|
||||||
1
|
|
||||||
2
|
|
||||||
select col2 + 100 from test group by 2 order by 2;
|
|
||||||
100
|
|
||||||
101
|
|
||||||
102
|
|
||||||
|
@ -1,32 +1,26 @@
|
|||||||
-- { echo }
|
|
||||||
set enable_positional_arguments = 1;
|
set enable_positional_arguments = 1;
|
||||||
|
|
||||||
drop table if exists test;
|
drop table if exists test;
|
||||||
create table test (col1 Int32, col2 Int32, col3 Int32) engine = Memory();
|
create table test(x1 Int, x2 Int, x3 Int) engine=Memory();
|
||||||
|
insert into test values (1, 10, 100), (10, 1, 10), (100, 100, 1);
|
||||||
|
|
||||||
insert into test select number, number, 5 from numbers(2);
|
-- { echo }
|
||||||
insert into test select number, number, 4 from numbers(2);
|
select x3, x2, x1 from test order by 1;
|
||||||
insert into test select number, number, 3 from numbers(2);
|
select x3, x2, x1 from test order by x3;
|
||||||
insert into test select number, number, 2 from numbers(2);
|
|
||||||
insert into test select number, number, 1 from numbers(2);
|
|
||||||
|
|
||||||
select * from test where col1 = 1 order by 3 desc;
|
select x3, x2, x1 from test order by 1 desc;
|
||||||
select * from test where col2 = 1 order by 3 asc;
|
select x3, x2, x1 from test order by x3 desc;
|
||||||
|
|
||||||
insert into test select number, number+1, 1 from numbers(2);
|
insert into test values (1, 10, 200), (10, 1, 200), (100, 100, 1);
|
||||||
insert into test select number, number+1, 2 from numbers(2);
|
select x3, x2 from test group by x3, x2;
|
||||||
insert into test select number, number+1, 3 from numbers(2);
|
select x3, x2 from test group by 1, 2;
|
||||||
insert into test select number, number+1, 4 from numbers(2);
|
|
||||||
insert into test select number, number+1, 5 from numbers(2);
|
|
||||||
|
|
||||||
select * from test order by col1, col2, col3 asc limit 2 by col2;
|
select x1, x2, x3 from test order by x3 limit 1 by x3;
|
||||||
select * from test order by 1, 2, 3 asc limit 2 by 2;
|
select x1, x2, x3 from test order by 3 limit 1 by 3;
|
||||||
|
select x1, x2, x3 from test order by x3 limit 1 by x1;
|
||||||
|
select x1, x2, x3 from test order by 3 limit 1 by 1;
|
||||||
|
|
||||||
select col1, col2 from test group by col1, col2 order by col1, col2;
|
select max(x3), max(x2), max(x1) from test group by 1; -- { serverError 43 }
|
||||||
select col1, col2 from test group by 1, 2 order by 1, 2;
|
select max(x1) from test order by 1; -- { serverError 43 }
|
||||||
|
|
||||||
select col2, col3 from test group by col3, col2 order by col3, col2;
|
|
||||||
select col2, col3 from test group by 3, 2 order by 3, 2;
|
|
||||||
|
|
||||||
select col2 from test group by 2 order by 2;
|
|
||||||
select col2 + 100 from test group by 2 order by 2;
|
|
||||||
|
Loading…
Reference in New Issue
Block a user