Support proper syntax for dateDiff

This commit is contained in:
Ivan Blinkov 2018-12-18 17:40:30 +03:00
parent e73bef119c
commit 5abfcfcd48
4 changed files with 73 additions and 0 deletions

View File

@ -698,6 +698,70 @@ bool ParserExtractExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & exp
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)))
return false;
if (pos->type != TokenType::OpeningRoundBracket)
return false;
++pos;
if (ParserKeyword("SECOND").ignore(pos, expected))
interval_name = "second";
else if (ParserKeyword("MINUTE").ignore(pos, expected))
interval_name = "minute";
else if (ParserKeyword("HOUR").ignore(pos, expected))
interval_name = "hour";
else if (ParserKeyword("DAY").ignore(pos, expected))
interval_name = "day";
else if (ParserKeyword("WEEK").ignore(pos, expected))
interval_name = "week";
else if (ParserKeyword("MONTH").ignore(pos, expected))
interval_name = "month";
else if (ParserKeyword("QUARTER").ignore(pos, expected))
interval_name = "quarter";
else if (ParserKeyword("YEAR").ignore(pos, expected))
interval_name = "year";
else
return false;
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 expr_list_args = std::make_shared<ASTExpressionList>();
expr_list_args->children = {std::make_shared<ASTLiteral>(interval_name), left_node, right_node};
auto func_node = std::make_shared<ASTFunction>();
func_node->name = "dateDiff";
func_node->arguments = std::move(expr_list_args);
func_node->children.push_back(func_node->arguments);
node = std::move(func_node);
return true;
}
bool ParserNull::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
@ -999,6 +1063,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)
|| ParserDateDiffExpression().parse(pos, node, expected)
|| ParserSubstringExpression().parse(pos, node, expected)
|| ParserTrimExpression().parse(pos, node, expected)
|| ParserLeftExpression().parse(pos, node, expected)

View File

@ -131,6 +131,12 @@ protected:
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
};
class ParserDateDiffExpression : public IParserBase
{
protected:
const char * getName() const override { return "DATE_DIFF expression"; }
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
};
/** NULL literal.
*/

View File

@ -21,3 +21,4 @@ xxfoo
fooabba
fooabbafoo
foo*
-11

View File

@ -23,3 +23,4 @@ select trim(TRAILING 'x' FROM 'xxfooxx');
select Trim(LEADING 'ab' FROM 'abbafooabba');
select TRIM(both 'ab' FROM 'abbafooabbafooabba');
select trim(LEADING '*[]{}|\\' FROM '\\|[[[}}}*foo*');
select DATE_DIFF(MONTH, toDate('2018-12-18'), toDate('2018-01-01'));