mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
Introduce DATE_ADD/DATE_SUB/TIMESTAMP_ADD/TIMESTAMP_SUB #3705
This commit is contained in:
parent
f88b497555
commit
0352c5a57c
@ -66,6 +66,31 @@ public:
|
||||
|
||||
ParserInterval() : interval_kind(IntervalKind::Incorrect) {}
|
||||
|
||||
const char * getToIntervalKindFunctionName()
|
||||
{
|
||||
switch (interval_kind)
|
||||
{
|
||||
case ParserInterval::IntervalKind::Second:
|
||||
return "toIntervalSecond";
|
||||
case ParserInterval::IntervalKind::Minute:
|
||||
return "toIntervalMinute";
|
||||
case ParserInterval::IntervalKind::Hour:
|
||||
return "toIntervalHour";
|
||||
case ParserInterval::IntervalKind::Day:
|
||||
return "toIntervalDay";
|
||||
case ParserInterval::IntervalKind::Week:
|
||||
return "toIntervalWeek";
|
||||
case ParserInterval::IntervalKind::Month:
|
||||
return "toIntervalMonth";
|
||||
case ParserInterval::IntervalKind::Quarter:
|
||||
return "toIntervalQuarter";
|
||||
case ParserInterval::IntervalKind::Year:
|
||||
return "toIntervalYear";
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
const char * getName() const override { return "interval"; }
|
||||
|
||||
|
@ -714,13 +714,78 @@ bool ParserExtractExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & exp
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParserDateAddExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
{
|
||||
const char * function_name = nullptr;
|
||||
ASTPtr left_node;
|
||||
ASTPtr right_node;
|
||||
|
||||
if (ParserKeyword("DATEADD").ignore(pos, expected) || ParserKeyword("DATE_ADD").ignore(pos, expected)
|
||||
|| ParserKeyword("TIMESTAMPADD").ignore(pos, expected) || ParserKeyword("TIMESTAMP_ADD").ignore(pos, expected))
|
||||
function_name = "plus";
|
||||
else if (ParserKeyword("DATESUB").ignore(pos, expected) || ParserKeyword("DATE_SUB").ignore(pos, expected)
|
||||
|| ParserKeyword("TIMESTAMPSUB").ignore(pos, expected) || ParserKeyword("TIMESTAMP_SUB").ignore(pos, expected))
|
||||
function_name = "minus";
|
||||
else
|
||||
return false;
|
||||
|
||||
if (pos->type != TokenType::OpeningRoundBracket)
|
||||
return false;
|
||||
++pos;
|
||||
|
||||
ParserInterval interval_parser;
|
||||
if (!interval_parser.ignore(pos, expected))
|
||||
return false;
|
||||
|
||||
const char * interval_function_name = interval_parser.getToIntervalKindFunctionName();
|
||||
|
||||
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;
|
||||
|
||||
if (pos->type != TokenType::ClosingRoundBracket)
|
||||
return false;
|
||||
++pos;
|
||||
|
||||
auto interval_expr_list_args = std::make_shared<ASTExpressionList>();
|
||||
interval_expr_list_args->children = {left_node};
|
||||
|
||||
auto interval_func_node = std::make_shared<ASTFunction>();
|
||||
interval_func_node->name = interval_function_name;
|
||||
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>();
|
||||
expr_list_args->children = {right_node, interval_func_node};
|
||||
|
||||
auto func_node = std::make_shared<ASTFunction>();
|
||||
func_node->name = function_name;
|
||||
func_node->arguments = std::move(expr_list_args);
|
||||
func_node->children.push_back(func_node->arguments);
|
||||
|
||||
node = std::move(func_node);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParserDateDiffExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
{
|
||||
const char * interval_name = nullptr;
|
||||
ASTPtr left_node;
|
||||
ASTPtr right_node;
|
||||
|
||||
if (!(ParserKeyword("DATEDIFF").ignore(pos, expected) || ParserKeyword("DATE_DIFF").ignore(pos, expected)))
|
||||
if (!(ParserKeyword("DATEDIFF").ignore(pos, expected) || ParserKeyword("DATE_DIFF").ignore(pos, expected)
|
||||
|| ParserKeyword("TIMESTAMPDIFF").ignore(pos, expected) || ParserKeyword("TIMESTAMP_DIFF").ignore(pos, expected)))
|
||||
return false;
|
||||
|
||||
if (pos->type != TokenType::OpeningRoundBracket)
|
||||
@ -1093,6 +1158,7 @@ bool ParserExpressionElement::parseImpl(Pos & pos, ASTPtr & node, Expected & exp
|
||||
|| ParserLiteral().parse(pos, node, expected)
|
||||
|| ParserCastExpression().parse(pos, node, expected)
|
||||
|| ParserExtractExpression().parse(pos, node, expected)
|
||||
|| ParserDateAddExpression().parse(pos, node, expected)
|
||||
|| ParserDateDiffExpression().parse(pos, node, expected)
|
||||
|| ParserSubstringExpression().parse(pos, node, expected)
|
||||
|| ParserTrimExpression().parse(pos, node, expected)
|
||||
|
@ -131,6 +131,13 @@ protected:
|
||||
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
|
||||
};
|
||||
|
||||
class ParserDateAddExpression : public IParserBase
|
||||
{
|
||||
protected:
|
||||
const char * getName() const override { return "DATE_ADD expression"; }
|
||||
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
|
||||
};
|
||||
|
||||
class ParserDateDiffExpression : public IParserBase
|
||||
{
|
||||
protected:
|
||||
|
@ -607,41 +607,13 @@ bool ParserIntervalOperatorExpression::parseImpl(Pos & pos, ASTPtr & node, Expec
|
||||
if (!ParserExpressionWithOptionalAlias(false).parse(pos, expr, expected))
|
||||
return false;
|
||||
|
||||
const char * function_name = nullptr;
|
||||
|
||||
ParserInterval interval_parser;
|
||||
if (!interval_parser.ignore(pos, expected))
|
||||
return false;
|
||||
|
||||
switch (interval_parser.interval_kind)
|
||||
{
|
||||
case ParserInterval::IntervalKind::Second:
|
||||
function_name = "toIntervalSecond";
|
||||
break;
|
||||
case ParserInterval::IntervalKind::Minute:
|
||||
function_name = "toIntervalMinute";
|
||||
break;
|
||||
case ParserInterval::IntervalKind::Hour:
|
||||
function_name = "toIntervalHour";
|
||||
break;
|
||||
case ParserInterval::IntervalKind::Day:
|
||||
function_name = "toIntervalDay";
|
||||
break;
|
||||
case ParserInterval::IntervalKind::Week:
|
||||
function_name = "toIntervalWeek";
|
||||
break;
|
||||
case ParserInterval::IntervalKind::Month:
|
||||
function_name = "toIntervalMonth";
|
||||
break;
|
||||
case ParserInterval::IntervalKind::Quarter:
|
||||
function_name = "toIntervalQuarter";
|
||||
break;
|
||||
case ParserInterval::IntervalKind::Year:
|
||||
function_name = "toIntervalYear";
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
const char * function_name = interval_parser.getToIntervalKindFunctionName();
|
||||
|
||||
/// the function corresponding to the operator
|
||||
auto function = std::make_shared<ASTFunction>();
|
||||
|
||||
|
@ -23,3 +23,5 @@ fooabbafoo
|
||||
foo*
|
||||
-11
|
||||
-3
|
||||
2021-01-01
|
||||
2018-07-18 01:02:03
|
||||
|
@ -25,3 +25,5 @@ select TRIM(both 'ab' FROM 'abbafooabbafooabba');
|
||||
select trim(LEADING '*[]{}|\\' FROM '\\|[[[}}}*foo*');
|
||||
select DATE_DIFF(MONTH, toDate('2018-12-18'), toDate('2018-01-01'));
|
||||
select DATE_DIFF(QQ, toDate('2018-12-18'), toDate('2018-01-01'));
|
||||
select DATE_ADD(YEAR, 3, toDate('2018-01-01'));
|
||||
select timestamp_sub(SQL_TSI_MONTH, 5, toDateTime('2018-12-18 01:02:03'));
|
||||
|
Loading…
Reference in New Issue
Block a user