mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
fix
update test fix
This commit is contained in:
parent
7b69592e49
commit
b931a3c9da
@ -789,6 +789,7 @@ bool ParserDateAddExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & exp
|
|||||||
++pos;
|
++pos;
|
||||||
|
|
||||||
IntervalKind interval_kind;
|
IntervalKind interval_kind;
|
||||||
|
ASTPtr interval_func_node;
|
||||||
if (parseIntervalKind(pos, expected, interval_kind))
|
if (parseIntervalKind(pos, expected, interval_kind))
|
||||||
{
|
{
|
||||||
/// function(unit, offset, timestamp)
|
/// function(unit, offset, timestamp)
|
||||||
@ -805,6 +806,13 @@ bool ParserDateAddExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & exp
|
|||||||
|
|
||||||
if (!ParserExpression().parse(pos, timestamp_node, expected))
|
if (!ParserExpression().parse(pos, timestamp_node, expected))
|
||||||
return false;
|
return false;
|
||||||
|
auto interval_expr_list_args = std::make_shared<ASTExpressionList>();
|
||||||
|
interval_expr_list_args->children = {offset_node};
|
||||||
|
|
||||||
|
interval_func_node = std::make_shared<ASTFunction>();
|
||||||
|
interval_func_node->as<ASTFunction &>().name = interval_kind.toNameOfFunctionToIntervalDataType();
|
||||||
|
interval_func_node->as<ASTFunction &>().arguments = std::move(interval_expr_list_args);
|
||||||
|
interval_func_node->as<ASTFunction &>().children.push_back(interval_func_node->as<ASTFunction &>().arguments);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -816,27 +824,13 @@ bool ParserDateAddExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & exp
|
|||||||
return false;
|
return false;
|
||||||
++pos;
|
++pos;
|
||||||
|
|
||||||
if (!ParserKeyword("INTERVAL").ignore(pos, expected))
|
if (!ParserIntervalOperatorExpression{}.parse(pos, interval_func_node, expected))
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!ParserExpression().parse(pos, offset_node, expected))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!parseIntervalKind(pos, expected, interval_kind))
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (pos->type != TokenType::ClosingRoundBracket)
|
if (pos->type != TokenType::ClosingRoundBracket)
|
||||||
return false;
|
return false;
|
||||||
++pos;
|
++pos;
|
||||||
|
|
||||||
auto interval_expr_list_args = std::make_shared<ASTExpressionList>();
|
|
||||||
interval_expr_list_args->children = {offset_node};
|
|
||||||
|
|
||||||
auto interval_func_node = std::make_shared<ASTFunction>();
|
|
||||||
interval_func_node->name = interval_kind.toNameOfFunctionToIntervalDataType();
|
|
||||||
interval_func_node->arguments = std::move(interval_expr_list_args);
|
|
||||||
interval_func_node->children.push_back(interval_func_node->arguments);
|
|
||||||
|
|
||||||
auto expr_list_args = std::make_shared<ASTExpressionList>();
|
auto expr_list_args = std::make_shared<ASTExpressionList>();
|
||||||
expr_list_args->children = {timestamp_node, interval_func_node};
|
expr_list_args->children = {timestamp_node, interval_func_node};
|
||||||
|
|
||||||
|
@ -645,12 +645,45 @@ bool ParserTimestampOperatorExpression::parseImpl(Pos & pos, ASTPtr & node, Expe
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ParserIntervalOperatorExpression::stringToIntervalKind(const String & literal, ASTPtr & number, IntervalKind & interval_kind)
|
bool ParserIntervalOperatorExpression::parseArgumentAndIntervalKind(
|
||||||
|
Pos & pos, ASTPtr & expr, IntervalKind & interval_kind, Expected & expected)
|
||||||
{
|
{
|
||||||
|
auto begin = pos;
|
||||||
|
auto init_expected = expected;
|
||||||
|
ASTPtr string_literal;
|
||||||
|
//// A String literal followed INTERVAL keyword,
|
||||||
|
/// the literal can be a part of an expression or
|
||||||
|
/// include Number and INTERVAL TYPE at the same time
|
||||||
|
if (ParserStringLiteral{}.parse(pos, string_literal, expected))
|
||||||
|
{
|
||||||
|
String literal;
|
||||||
|
if (string_literal->as<ASTLiteral &>().value.tryGet(literal))
|
||||||
|
{
|
||||||
Tokens tokens(literal.data(), literal.data() + literal.size());
|
Tokens tokens(literal.data(), literal.data() + literal.size());
|
||||||
Pos pos(tokens, 0);
|
Pos token_pos(tokens, 0);
|
||||||
Expected expected;
|
Expected token_expected;
|
||||||
return (ParserNumber().parse(pos, number, expected) && parseIntervalKind(pos, expected, interval_kind));
|
|
||||||
|
if (!ParserNumber{}.parse(token_pos, expr, token_expected))
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/// case: INTERVAL '1' HOUR
|
||||||
|
/// back to begin
|
||||||
|
if (!token_pos.isValid())
|
||||||
|
{
|
||||||
|
pos = begin;
|
||||||
|
expected = init_expected;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/// case: INTERVAL '1 HOUR'
|
||||||
|
return parseIntervalKind(token_pos, token_expected, interval_kind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// case: INTERVAL expr HOUR
|
||||||
|
if (!ParserExpressionWithOptionalAlias(false).parse(pos, expr, expected))
|
||||||
|
return false;
|
||||||
|
return parseIntervalKind(pos, expected, interval_kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ParserIntervalOperatorExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
bool ParserIntervalOperatorExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||||
@ -661,44 +694,9 @@ bool ParserIntervalOperatorExpression::parseImpl(Pos & pos, ASTPtr & node, Expec
|
|||||||
if (!ParserKeyword("INTERVAL").ignore(pos, expected))
|
if (!ParserKeyword("INTERVAL").ignore(pos, expected))
|
||||||
return next_parser.parse(pos, node, expected);
|
return next_parser.parse(pos, node, expected);
|
||||||
|
|
||||||
ASTPtr string_literal;
|
|
||||||
if (ParserStringLiteral().parse(pos, string_literal, expected))
|
|
||||||
{
|
|
||||||
String literal;
|
|
||||||
if (string_literal->as<ASTLiteral &>().value.tryGet<String>(literal))
|
|
||||||
{
|
|
||||||
IntervalKind interval_kind;
|
|
||||||
ASTPtr number;
|
|
||||||
|
|
||||||
/// parse function arguments and interval kind from string literal
|
|
||||||
if (!stringToIntervalKind(literal, number, interval_kind))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
auto function = std::make_shared<ASTFunction>();
|
|
||||||
|
|
||||||
auto exp_list = std::make_shared<ASTExpressionList>();
|
|
||||||
|
|
||||||
function->name = interval_kind.toNameOfFunctionToIntervalDataType();
|
|
||||||
function->arguments = exp_list;
|
|
||||||
function->children.push_back(exp_list);
|
|
||||||
|
|
||||||
exp_list->children.push_back(number);
|
|
||||||
|
|
||||||
node = function;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPtr expr;
|
ASTPtr expr;
|
||||||
/// Any expression can be inside, because operator surrounds it.
|
|
||||||
if (!ParserExpressionWithOptionalAlias(false).parse(pos, expr, expected))
|
|
||||||
{
|
|
||||||
pos = begin;
|
|
||||||
return next_parser.parse(pos, node, expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
IntervalKind interval_kind;
|
IntervalKind interval_kind;
|
||||||
if (!parseIntervalKind(pos, expected, interval_kind))
|
if (!parseArgumentAndIntervalKind(pos, expr, interval_kind, expected))
|
||||||
{
|
{
|
||||||
pos = begin;
|
pos = begin;
|
||||||
return next_parser.parse(pos, node, expected);
|
return next_parser.parse(pos, node, expected);
|
||||||
|
@ -233,7 +233,7 @@ protected:
|
|||||||
|
|
||||||
const char * getName() const override { return "INTERVAL operator expression"; }
|
const char * getName() const override { return "INTERVAL operator expression"; }
|
||||||
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
|
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
|
||||||
bool stringToIntervalKind(const String & literal, ASTPtr & number, IntervalKind & interval_kind);
|
bool parseArgumentAndIntervalKind(Pos & pos, ASTPtr & expr, IntervalKind & interval_kind, Expected & expected);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ParserAdditiveExpression : public IParserBase
|
class ParserAdditiveExpression : public IParserBase
|
||||||
|
@ -4,3 +4,22 @@
|
|||||||
2
|
2
|
||||||
2
|
2
|
||||||
2
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
|
2009-02-14 00:31:30
|
||||||
|
2009-02-14 00:31:30
|
||||||
|
2009-02-14 00:31:30
|
||||||
|
2009-02-15 23:31:30
|
||||||
|
2009-02-15 23:31:30
|
||||||
|
2009-02-15 23:31:30
|
||||||
|
@ -1,6 +1,25 @@
|
|||||||
|
SELECT INTERVAL 2 year;
|
||||||
|
SELECT INTERVAL '2' year;
|
||||||
|
SELECT INTERVAL '2 year';
|
||||||
|
SELECT INTERVAL 2 month;
|
||||||
|
SELECT INTERVAL '2' month;
|
||||||
|
SELECT INTERVAL '2 month';
|
||||||
|
SELECT INTERVAL 2 week;
|
||||||
|
SELECT INTERVAL '2' week;
|
||||||
|
SELECT INTERVAL '2 week';
|
||||||
SELECT INTERVAL 2 day;
|
SELECT INTERVAL 2 day;
|
||||||
|
SELECT INTERVAL '2' day;
|
||||||
SELECT INTERVAL '2 day';
|
SELECT INTERVAL '2 day';
|
||||||
SELECT INTERVAL 2 hour;
|
SELECT INTERVAL 2 hour;
|
||||||
|
SELECT INTERVAL '2' hour;
|
||||||
SELECT INTERVAL '2 hour';
|
SELECT INTERVAL '2 hour';
|
||||||
SELECT INTERVAL 2 minute;
|
SELECT INTERVAL 2 minute;
|
||||||
|
SELECT INTERVAL '2' minute;
|
||||||
SELECT INTERVAL '2 minute';
|
SELECT INTERVAL '2 minute';
|
||||||
|
SELECT INTERVAL '2' AS n minute;
|
||||||
|
SELECT DATE_ADD(hour, '1', toDateTime(1234567890, 'UTC'));
|
||||||
|
SELECT DATE_ADD(hour, 1, toDateTime(1234567890, 'UTC'));
|
||||||
|
SELECT DATE_ADD(hour, (SELECT 1), toDateTime(1234567890, 'UTC'));
|
||||||
|
SELECT DATE_ADD(toDateTime(1234567890, 'UTC'), INTERVAL 2 day);
|
||||||
|
SELECT DATE_ADD(toDateTime(1234567890, 'UTC'), INTERVAL '2 day');
|
||||||
|
SELECT DATE_ADD(toDateTime(1234567890, 'UTC'), INTERVAL '2' day);
|
||||||
|
Loading…
Reference in New Issue
Block a user