mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-26 17:41:59 +00:00
Fix broken aliases during parsing of special operators
This commit is contained in:
parent
dd93d5d872
commit
00ac3231b2
@ -303,7 +303,7 @@ namespace
|
||||
ASTPtr expr_node;
|
||||
ASTPtr type_node;
|
||||
|
||||
if (ParserExpression().parse(pos, expr_node, expected))
|
||||
if (ParserExpressionWithOptionalAlias(true /*allow_alias_without_as_keyword*/).parse(pos, expr_node, expected))
|
||||
{
|
||||
if (ParserKeyword("AS").ignore(pos, expected))
|
||||
{
|
||||
@ -315,7 +315,7 @@ namespace
|
||||
}
|
||||
else if (ParserToken(TokenType::Comma).ignore(pos, expected))
|
||||
{
|
||||
if (ParserExpression().parse(pos, type_node, expected))
|
||||
if (ParserExpressionWithOptionalAlias(true /*allow_alias_without_as_keyword*/).parse(pos, type_node, expected))
|
||||
{
|
||||
node = makeASTFunction("CAST", expr_node, type_node);
|
||||
return true;
|
||||
@ -335,7 +335,7 @@ namespace
|
||||
ASTPtr start_node;
|
||||
ASTPtr length_node;
|
||||
|
||||
if (!ParserExpression().parse(pos, expr_node, expected))
|
||||
if (!ParserExpressionWithOptionalAlias(true /*allow_alias_without_as_keyword*/).parse(pos, expr_node, expected))
|
||||
return false;
|
||||
|
||||
if (pos->type != TokenType::Comma)
|
||||
@ -348,7 +348,7 @@ namespace
|
||||
++pos;
|
||||
}
|
||||
|
||||
if (!ParserExpression().parse(pos, start_node, expected))
|
||||
if (!ParserExpressionWithOptionalAlias(true /*allow_alias_without_as_keyword*/).parse(pos, start_node, expected))
|
||||
return false;
|
||||
|
||||
if (pos->type != TokenType::ClosingRoundBracket)
|
||||
@ -363,7 +363,7 @@ namespace
|
||||
++pos;
|
||||
}
|
||||
|
||||
if (!ParserExpression().parse(pos, length_node, expected))
|
||||
if (!ParserExpressionWithOptionalAlias(true /*allow_alias_without_as_keyword*/).parse(pos, length_node, expected))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -378,7 +378,7 @@ namespace
|
||||
|
||||
bool parseTrim(bool trim_left, bool trim_right, IParser::Pos & pos, ASTPtr & node, Expected & expected)
|
||||
{
|
||||
/// Handles all possible TRIM/LTRIM/RTRIM call variants
|
||||
/// Handles all possible TRIM/LTRIM/RTRIM call variants ([[LEADING|TRAILING|BOTH] trim_character FROM] input_string)
|
||||
|
||||
std::string func_name;
|
||||
bool char_override = false;
|
||||
@ -412,7 +412,7 @@ namespace
|
||||
|
||||
if (char_override)
|
||||
{
|
||||
if (!ParserExpression().parse(pos, to_remove, expected))
|
||||
if (!ParserExpressionWithOptionalAlias(true /*allow_alias_without_as_keyword*/).parse(pos, to_remove, expected))
|
||||
return false;
|
||||
if (!ParserKeyword("FROM").ignore(pos, expected))
|
||||
return false;
|
||||
@ -429,7 +429,7 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
if (!ParserExpression().parse(pos, expr_node, expected))
|
||||
if (!ParserExpressionWithOptionalAlias(true /*allow_alias_without_as_keyword*/).parse(pos, expr_node, expected))
|
||||
return false;
|
||||
|
||||
/// Convert to regexp replace function call
|
||||
@ -506,6 +506,9 @@ namespace
|
||||
|
||||
bool parseExtract(IParser::Pos & pos, ASTPtr & node, Expected & expected)
|
||||
{
|
||||
/// First try to match with date extract operator EXTRACT(part FROM date)
|
||||
/// Then with function extract(haystack, pattern)
|
||||
|
||||
IParser::Pos begin = pos;
|
||||
IntervalKind interval_kind;
|
||||
|
||||
@ -514,7 +517,7 @@ namespace
|
||||
ASTPtr expr;
|
||||
|
||||
ParserKeyword s_from("FROM");
|
||||
ParserExpression elem_parser;
|
||||
ParserExpressionWithOptionalAlias elem_parser(true /*allow_alias_without_as_keyword*/);
|
||||
|
||||
if (s_from.ignore(pos, expected) && elem_parser.parse(pos, expr, expected))
|
||||
{
|
||||
@ -526,7 +529,7 @@ namespace
|
||||
pos = begin;
|
||||
|
||||
ASTPtr expr_list;
|
||||
if (!ParserExpressionList(false, false).parse(pos, expr_list, expected))
|
||||
if (!ParserExpressionList(true /*allow_alias_without_as_keyword*/).parse(pos, expr_list, expected))
|
||||
return false;
|
||||
|
||||
auto res = std::make_shared<ASTFunction>();
|
||||
@ -539,8 +542,11 @@ namespace
|
||||
|
||||
bool parsePosition(IParser::Pos & pos, ASTPtr & node, Expected & expected)
|
||||
{
|
||||
/// First try to match with position(needle IN haystack)
|
||||
/// Then with position(haystack, needle[, start_pos])
|
||||
|
||||
ASTPtr expr_list_node;
|
||||
if (!ParserExpressionList(false, false).parse(pos, expr_list_node, expected))
|
||||
if (!ParserExpressionList(true /*allow_alias_without_as_keyword*/).parse(pos, expr_list_node, expected))
|
||||
return false;
|
||||
|
||||
ASTExpressionList * expr_list = typeid_cast<ASTExpressionList *>(expr_list_node.get());
|
||||
@ -568,6 +574,9 @@ namespace
|
||||
|
||||
bool parseDateAdd(const char * function_name, IParser::Pos & pos, ASTPtr & node, Expected & expected)
|
||||
{
|
||||
/// First to match with function(unit, offset, timestamp)
|
||||
/// Then with function(offset, timestamp)
|
||||
|
||||
ASTPtr timestamp_node;
|
||||
ASTPtr offset_node;
|
||||
|
||||
@ -575,19 +584,18 @@ namespace
|
||||
ASTPtr interval_func_node;
|
||||
if (parseIntervalKind(pos, expected, interval_kind))
|
||||
{
|
||||
/// function(unit, offset, timestamp)
|
||||
if (pos->type != TokenType::Comma)
|
||||
return false;
|
||||
++pos;
|
||||
|
||||
if (!ParserExpression().parse(pos, offset_node, expected))
|
||||
if (!ParserExpressionWithOptionalAlias(true /*allow_alias_without_as_keyword*/).parse(pos, offset_node, expected))
|
||||
return false;
|
||||
|
||||
if (pos->type != TokenType::Comma)
|
||||
return false;
|
||||
++pos;
|
||||
|
||||
if (!ParserExpression().parse(pos, timestamp_node, expected))
|
||||
if (!ParserExpressionWithOptionalAlias(true /*allow_alias_without_as_keyword*/).parse(pos, timestamp_node, expected))
|
||||
return false;
|
||||
auto interval_expr_list_args = std::make_shared<ASTExpressionList>();
|
||||
interval_expr_list_args->children = {offset_node};
|
||||
@ -600,7 +608,7 @@ namespace
|
||||
else
|
||||
{
|
||||
ASTPtr expr_list;
|
||||
if (!ParserExpressionList(false, false).parse(pos, expr_list, expected))
|
||||
if (!ParserExpressionList(true /*allow_alias_without_as_keyword*/).parse(pos, expr_list, expected))
|
||||
return false;
|
||||
|
||||
auto res = std::make_shared<ASTFunction>();
|
||||
@ -617,14 +625,36 @@ namespace
|
||||
|
||||
bool parseDateDiff(IParser::Pos & pos, ASTPtr & node, Expected & expected)
|
||||
{
|
||||
/// First to match with dateDiff(unit, startdate, enddate, [timezone])
|
||||
/// Then with dateDiff('unit', startdate, enddate, [timezone])
|
||||
|
||||
ASTPtr left_node;
|
||||
ASTPtr right_node;
|
||||
|
||||
IntervalKind interval_kind;
|
||||
if (!parseIntervalKind(pos, expected, interval_kind))
|
||||
if (parseIntervalKind(pos, expected, interval_kind))
|
||||
{
|
||||
if (pos->type != TokenType::Comma)
|
||||
return false;
|
||||
++pos;
|
||||
|
||||
if (!ParserExpressionWithOptionalAlias(true /*allow_alias_without_as_keyword*/).parse(pos, left_node, expected))
|
||||
return false;
|
||||
|
||||
if (pos->type != TokenType::Comma)
|
||||
return false;
|
||||
++pos;
|
||||
|
||||
if (!ParserExpressionWithOptionalAlias(true /*allow_alias_without_as_keyword*/).parse(pos, right_node, expected))
|
||||
return false;
|
||||
|
||||
node = makeASTFunction("dateDiff", std::make_shared<ASTLiteral>(interval_kind.toDateDiffUnit()), left_node, right_node);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ASTPtr expr_list;
|
||||
if (!ParserExpressionList(false, false).parse(pos, expr_list, expected))
|
||||
if (!ParserExpressionList(true /*allow_alias_without_as_keyword*/).parse(pos, expr_list, expected))
|
||||
return false;
|
||||
|
||||
auto res = std::make_shared<ASTFunction>();
|
||||
@ -632,24 +662,7 @@ namespace
|
||||
res->arguments = expr_list;
|
||||
res->children.push_back(res->arguments);
|
||||
node = std::move(res);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pos->type != TokenType::Comma)
|
||||
return false;
|
||||
++pos;
|
||||
|
||||
if (!ParserExpression().parse(pos, left_node, expected))
|
||||
return false;
|
||||
|
||||
if (pos->type != TokenType::Comma)
|
||||
return false;
|
||||
++pos;
|
||||
|
||||
if (!ParserExpression().parse(pos, right_node, expected))
|
||||
return false;
|
||||
|
||||
node = makeASTFunction("dateDiff", std::make_shared<ASTLiteral>(interval_kind.toDateDiffUnit()), left_node, right_node);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,35 @@
|
||||
1234 1234 UInt32
|
||||
1234 1234 UInt32
|
||||
1234 1234
|
||||
1234 1234
|
||||
234 1234 2 3
|
||||
234 1234 2 3
|
||||
234 1234 2
|
||||
234 1234 2
|
||||
234 1234 2 3
|
||||
234 1234 2 3
|
||||
bca a abca
|
||||
bca a abca
|
||||
abc a abca
|
||||
abc a abca
|
||||
bc a abca
|
||||
bc a abca
|
||||
5 2019-05-05
|
||||
5 2019-05-05
|
||||
123 1234 123
|
||||
123 1234 123
|
||||
1 123 1234
|
||||
0 123 1234
|
||||
0 123 1234
|
||||
2019-05-06 1 2019-05-05
|
||||
2019-05-06 1 2019-05-05
|
||||
2019-05-06 1 2019-05-05
|
||||
2019-05-06 1 2019-05-05
|
||||
2019-05-04 1 2019-05-05
|
||||
2019-05-04 1 2019-05-05
|
||||
2019-05-04 1 2019-05-05
|
||||
2019-05-04 1 2019-05-05
|
||||
1 2019-05-05 2019-05-06
|
||||
1 2019-05-05 2019-05-06
|
||||
1 2019-05-05 2019-05-06
|
||||
1 2019-05-05 2019-05-06
|
@ -0,0 +1,92 @@
|
||||
-- CAST expression
|
||||
|
||||
SELECT cast('1234' AS lhs, 'UInt32' AS rhs), lhs, rhs;
|
||||
SELECT cast('1234' lhs, 'UInt32' rhs), lhs, rhs;
|
||||
SELECT cast('1234' lhs AS UInt32), lhs;
|
||||
SELECT cast('1234' AS lhs AS UInt32), lhs;
|
||||
|
||||
-- SUBSTRING expression
|
||||
|
||||
-- SUBSTRING(expr, start, length)
|
||||
|
||||
SELECT substring('1234' AS arg_1, 2 AS arg_2, 3 AS arg_3), arg_1, arg_2, arg_3;
|
||||
SELECT substring('1234' arg_1, 2 arg_2, 3 arg_3), arg_1, arg_2, arg_3;
|
||||
|
||||
-- SUBSTRING(expr FROM start)
|
||||
|
||||
SELECT substring('1234' AS arg_1 FROM 2 AS arg_2), arg_1, arg_2;
|
||||
SELECT substring('1234' arg_1 FROM 2 arg_2), arg_1, arg_2;
|
||||
|
||||
-- SUBSTRING(expr FROM start FOR length)
|
||||
|
||||
SELECT substring('1234' AS arg_1 FROM 2 AS arg_2 FOR 3 AS arg_3), arg_1, arg_2, arg_3;
|
||||
SELECT substring('1234' arg_1 FROM 2 arg_2 FOR 3 arg_3), arg_1, arg_2, arg_3;
|
||||
|
||||
|
||||
-- TRIM expression ([[LEADING|TRAILING|BOTH] trim_character FROM] input_string)
|
||||
|
||||
SELECT trim(LEADING 'a' AS arg_1 FROM 'abca' AS arg_2), arg_1, arg_2;
|
||||
SELECT trim(LEADING 'a' arg_1 FROM 'abca' arg_2), arg_1, arg_2;
|
||||
|
||||
SELECT trim(TRAILING 'a' AS arg_1 FROM 'abca' AS arg_2), arg_1, arg_2;
|
||||
SELECT trim(TRAILING 'a' arg_1 FROM 'abca' arg_2), arg_1, arg_2;
|
||||
|
||||
SELECT trim(BOTH 'a' AS arg_1 FROM 'abca' AS arg_2), arg_1, arg_2;
|
||||
SELECT trim(BOTH 'a' arg_1 FROM 'abca' arg_2), arg_1, arg_2;
|
||||
|
||||
-- EXTRACT expression
|
||||
|
||||
-- EXTRACT(part FROM date)
|
||||
|
||||
SELECT EXTRACT(DAY FROM toDate('2019-05-05') as arg_1), arg_1;
|
||||
SELECT EXTRACT(DAY FROM toDate('2019-05-05') arg_1), arg_1;
|
||||
|
||||
-- Function extract(haystack, pattern)
|
||||
|
||||
SELECT extract('1234' AS arg_1, '123' AS arg_2), arg_1, arg_2;
|
||||
SELECT extract('1234' arg_1, '123' arg_2), arg_1, arg_2;
|
||||
|
||||
-- POSITION expression
|
||||
|
||||
-- position(needle IN haystack)
|
||||
|
||||
SELECT position(('123' AS arg_1) IN ('1234' AS arg_2)), arg_1, arg_2;
|
||||
|
||||
-- position(haystack, needle[, start_pos])
|
||||
|
||||
SELECT position('123' AS arg_1, '1234' AS arg_2), arg_1, arg_2;
|
||||
SELECT position('123' arg_1, '1234' arg_2), arg_1, arg_2;
|
||||
|
||||
-- dateAdd, dateSub expressions
|
||||
|
||||
-- function(unit, offset, timestamp)
|
||||
|
||||
SELECT dateAdd(DAY, 1 AS arg_1, toDate('2019-05-05') AS arg_2), arg_1, arg_2;
|
||||
SELECT dateAdd(DAY, 1 arg_1, toDate('2019-05-05') arg_2), arg_1, arg_2;
|
||||
|
||||
-- function(offset, timestamp)
|
||||
|
||||
SELECT dateAdd(DAY, 1 AS arg_1, toDate('2019-05-05') AS arg_2), arg_1, arg_2;
|
||||
SELECT dateAdd(DAY, 1 arg_1, toDate('2019-05-05') arg_2), arg_1, arg_2;
|
||||
|
||||
-- function(unit, offset, timestamp)
|
||||
|
||||
SELECT dateSub(DAY, 1 AS arg_1, toDate('2019-05-05') AS arg_2), arg_1, arg_2;
|
||||
SELECT dateSub(DAY, 1 arg_1, toDate('2019-05-05') arg_2), arg_1, arg_2;
|
||||
|
||||
-- function(offset, timestamp)
|
||||
|
||||
SELECT dateSub(DAY, 1 AS arg_1, toDate('2019-05-05') AS arg_2), arg_1, arg_2;
|
||||
SELECT dateSub(DAY, 1 arg_1, toDate('2019-05-05') arg_2), arg_1, arg_2;
|
||||
|
||||
-- dateDiff expression
|
||||
|
||||
-- dateDiff(unit, startdate, enddate, [timezone])
|
||||
|
||||
SELECT dateDiff(DAY, toDate('2019-05-05') AS arg_1, toDate('2019-05-06') AS arg_2), arg_1, arg_2;
|
||||
SELECT dateDiff(DAY, toDate('2019-05-05') arg_1, toDate('2019-05-06') arg_2), arg_1, arg_2;
|
||||
|
||||
-- dateDiff('unit', startdate, enddate, [timezone])
|
||||
|
||||
SELECT dateDiff('DAY', toDate('2019-05-05') AS arg_1, toDate('2019-05-06') AS arg_2), arg_1, arg_2;
|
||||
SELECT dateDiff('DAY', toDate('2019-05-05') arg_1, toDate('2019-05-06') arg_2), arg_1, arg_2;
|
Loading…
Reference in New Issue
Block a user