From 09f117cfb1f8ea74355e73f846efaed76b56de6f Mon Sep 17 00:00:00 2001 From: HeenaBansal2009 Date: Wed, 10 Aug 2022 13:04:07 -0700 Subject: [PATCH] Added test and review comments --- src/Parsers/Kusto/KQL_ReleaseNote.md | 60 +++++++++ .../KustoFunctions/KQLDateTimeFunctions.cpp | 101 +++++++------- .../tests/KQL/gtest_KQL_dateTimeFunctions.cpp | 126 ++++++++++++++++++ 3 files changed, 237 insertions(+), 50 deletions(-) create mode 100644 src/Parsers/tests/KQL/gtest_KQL_dateTimeFunctions.cpp diff --git a/src/Parsers/Kusto/KQL_ReleaseNote.md b/src/Parsers/Kusto/KQL_ReleaseNote.md index b37b991a2a2..0f475654d5f 100644 --- a/src/Parsers/Kusto/KQL_ReleaseNote.md +++ b/src/Parsers/Kusto/KQL_ReleaseNote.md @@ -1,4 +1,64 @@ # August XX, 2022 +- **DateTimeFunctions** +- [startofyear](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/startofyearfunction) + `print startofyear(datetime(2017-01-01 10:10:17), -1)` + `print startofyear(datetime(2017-01-01 10:10:17), 0)` + `print startofyear(datetime(2017-01-01 10:10:17), 1)` +- [weekofyear](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/weekofyearfunction) + `print week_of_year(datetime(2020-12-31))` + `print week_of_year(datetime(2020-06-15))` + `print week_of_year(datetime(1970-01-01))` + `print week_of_year(datetime(2000-01-01))` + +- [startofweek](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/startofweekfunction) + `print startofweek(datetime(2017-01-01 10:10:17), -1)` + `print startofweek(datetime(2017-01-01 10:10:17), 0)` + `print startofweek(datetime(2017-01-01 10:10:17), 1)` + +- [startofmonth](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/startofmonthfunction) + `print startofmonth(datetime(2017-01-01 10:10:17), -1)` + `print startofmonth(datetime(2017-01-01 10:10:17), 0)` + `print startofmonth(datetime(2017-01-01 10:10:17), 1)` + +- [startofday](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/startofdayfunction) + `print startofday(datetime(2017-01-01 10:10:17), -1)` + `print startofday(datetime(2017-01-01 10:10:17), 0)` + `print startofday(datetime(2017-01-01 10:10:17), 1)` + +- [monthofyear](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/monthofyearfunction) + `print monthofyear(datetime("2015-12-14"))` + +- [hourofday](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/hourofdayfunction) + `print hourofday(datetime(2015-12-14 18:54:00))` + +- [getyear](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/getyearfunction) + `print getyear(datetime(2015-10-12))` + +- [getmonth](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/getmonthfunction) + `print getmonth(datetime(2015-10-12))` + +- [dayofyear](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/dayofyearfunction) + `print dayofyear(datetime(2015-12-14))` + +- [dayofmonth](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/dayofmonthfunction) + `print (datetime(2015-12-14))` + +- [unixtime_seconds_todatetime](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/unixtime-seconds-todatetimefunction) + `print unixtime_seconds_todatetime(1546300800)` + +- [dayofweek](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/dayofweekfunction) + `print dayofweek(datetime(2015-12-20))` + +- [now](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/nowfunction) + `print now()` + `print now(2d)` + `print now(-2h)` + `print now(5 microseconds)` + `print now(5 seconds)` + `print now(6minutes)` + `print now(-2d) ` + `print now(time(1d))` + ## KQL implemented features The config setting to allow modify dialect setting. - Set dialect setting in server configuration XML at user level(` users.xml `). This sets the ` dialect ` at server startup and CH will do query parsing for all users with ` default ` profile acording to dialect value. diff --git a/src/Parsers/Kusto/KustoFunctions/KQLDateTimeFunctions.cpp b/src/Parsers/Kusto/KustoFunctions/KQLDateTimeFunctions.cpp index aea1bc3127a..58d8536fb49 100644 --- a/src/Parsers/Kusto/KustoFunctions/KQLDateTimeFunctions.cpp +++ b/src/Parsers/Kusto/KustoFunctions/KQLDateTimeFunctions.cpp @@ -19,134 +19,136 @@ namespace DB { -bool TimeSpan::convertImpl(String &out,IParser::Pos &pos) +bool TimeSpan::convertImpl(String & out, IParser::Pos & pos) { - String res = String(pos->begin,pos->end); + String res = String(pos->begin, pos->end); out = res; return false; } /* -bool DateTime::convertImpl(String &out,IParser::Pos &pos) +bool DateTime::convertImpl(String & out, IParser::Pos & pos) { - String res = String(pos->begin,pos->end); + String res = String(pos->begin, pos->end); out = res; return false; }*/ -bool Ago::convertImpl(String &out,IParser::Pos &pos) +bool Ago::convertImpl(String & out, IParser::Pos & pos) { - String res = String(pos->begin,pos->end); + String res = String(pos->begin, pos->end); out = res; return false; } -bool DatetimeAdd::convertImpl(String &out,IParser::Pos &pos) +bool DatetimeAdd::convertImpl(String & out, IParser::Pos & pos) { - String res = String(pos->begin,pos->end); + String res = String(pos->begin, pos->end); out = res; return false; }; -bool DatetimePart::convertImpl(String &out,IParser::Pos &pos) +bool DatetimePart::convertImpl(String & out, IParser::Pos & pos) { - String res = String(pos->begin,pos->end); + String res = String(pos->begin, pos->end); out = res; return false; } -bool DatetimeDiff::convertImpl(String &out,IParser::Pos &pos) +bool DatetimeDiff::convertImpl(String & out, IParser::Pos & pos) { - String res = String(pos->begin,pos->end); + String res = String(pos->begin, pos->end); out = res; return false; } -bool DayOfMonth::convertImpl(String &out,IParser::Pos &pos) +bool DayOfMonth::convertImpl(String & out, IParser::Pos & pos) { return directMapping(out, pos, "toDayOfMonth"); } -bool DayOfWeek::convertImpl(String &out,IParser::Pos &pos) +bool DayOfWeek::convertImpl(String & out, IParser::Pos & pos) { const String fn_name = getKQLFunctionName(pos); if (fn_name.empty()) return false; ++pos; - out = std::format("toDayOfWeek() + %7"); + const String datetime_str = getConvertedArgument(fn_name, pos); + + out = std::format("toDayOfWeek({})%7",datetime_str); return true; } -bool DayOfYear::convertImpl(String &out,IParser::Pos &pos) +bool DayOfYear::convertImpl(String & out, IParser::Pos & pos) { return directMapping(out, pos, "toDayOfYear"); } -bool EndOfDay::convertImpl(String &out,IParser::Pos &pos) +bool EndOfDay::convertImpl(String & out, IParser::Pos & pos) { - String res = String(pos->begin,pos->end); + String res = String(pos->begin, pos->end); out = res; return false; } -bool EndOfWeek::convertImpl(String &out,IParser::Pos &pos) +bool EndOfWeek::convertImpl(String & out, IParser::Pos & pos) { - String res = String(pos->begin,pos->end); + String res = String(pos->begin, pos->end); out = res; return false; } -bool EndOfYear::convertImpl(String &out,IParser::Pos &pos) +bool EndOfYear::convertImpl(String & out, IParser::Pos & pos) { - String res = String(pos->begin,pos->end); + String res = String(pos->begin, pos->end); out = res; return false; } -bool FormatDateTime::convertImpl(String &out,IParser::Pos &pos) +bool FormatDateTime::convertImpl(String & out, IParser::Pos & pos) { - String res = String(pos->begin,pos->end); + String res = String(pos->begin, pos->end); out = res; return false; } -bool FormatTimeSpan::convertImpl(String &out,IParser::Pos &pos) +bool FormatTimeSpan::convertImpl(String & out, IParser::Pos & pos) { - String res = String(pos->begin,pos->end); + String res = String(pos->begin, pos->end); out = res; return false; } -bool GetMonth::convertImpl(String &out,IParser::Pos &pos) +bool GetMonth::convertImpl(String & out, IParser::Pos & pos) { return directMapping(out, pos, "toMonth"); } -bool GetYear::convertImpl(String &out,IParser::Pos &pos) +bool GetYear::convertImpl(String & out, IParser::Pos & pos) { return directMapping(out, pos, "toYear"); } -bool HoursOfDay::convertImpl(String &out,IParser::Pos &pos) +bool HoursOfDay::convertImpl(String & out, IParser::Pos & pos) { return directMapping(out, pos, "toHour"); } -bool MakeTimeSpan::convertImpl(String &out,IParser::Pos &pos) +bool MakeTimeSpan::convertImpl(String & out, IParser::Pos & pos) { - String res = String(pos->begin,pos->end); + String res = String(pos->begin, pos->end); out = res; return false; } -bool MakeDateTime::convertImpl(String &out,IParser::Pos &pos) +bool MakeDateTime::convertImpl(String & out, IParser::Pos & pos) { - String res = String(pos->begin,pos->end); + String res = String(pos->begin, pos->end); out = res; return false; } -bool Now::convertImpl(String &out,IParser::Pos &pos) +bool Now::convertImpl(String & out, IParser::Pos & pos) { const String fn_name = getKQLFunctionName(pos); if (fn_name.empty()) @@ -163,7 +165,7 @@ bool Now::convertImpl(String &out,IParser::Pos &pos) return true; } -bool StartOfDay::convertImpl(String &out,IParser::Pos &pos) +bool StartOfDay::convertImpl(String & out, IParser::Pos & pos) { const String fn_name = getKQLFunctionName(pos); @@ -184,7 +186,7 @@ bool StartOfDay::convertImpl(String &out,IParser::Pos &pos) return true; } -bool StartOfMonth::convertImpl(String &out,IParser::Pos &pos) +bool StartOfMonth::convertImpl(String & out, IParser::Pos & pos) { const String fn_name = getKQLFunctionName(pos); if (fn_name.empty()) @@ -204,7 +206,7 @@ bool StartOfMonth::convertImpl(String &out,IParser::Pos &pos) return true; } -bool StartOfWeek::convertImpl(String &out,IParser::Pos &pos) +bool StartOfWeek::convertImpl(String & out, IParser::Pos & pos) { const String fn_name = getKQLFunctionName(pos); if (fn_name.empty()) @@ -224,9 +226,9 @@ bool StartOfWeek::convertImpl(String &out,IParser::Pos &pos) return true; } -bool StartOfYear::convertImpl(String &out,IParser::Pos &pos) +bool StartOfYear::convertImpl(String & out, IParser::Pos & pos) { - const String fn_name = getKQLFunctionName(pos); + const String fn_name = getKQLFunctionName(pos); if (fn_name.empty()) return false; @@ -243,30 +245,30 @@ bool StartOfYear::convertImpl(String &out,IParser::Pos &pos) return true; } -bool UnixTimeMicrosecondsToDateTime::convertImpl(String &out,IParser::Pos &pos) +bool UnixTimeMicrosecondsToDateTime::convertImpl(String & out, IParser::Pos & pos) { - String res = String(pos->begin,pos->end); + String res = String(pos->begin, pos->end); out = res; return false; } -bool UnixTimeMillisecondsToDateTime::convertImpl(String &out,IParser::Pos &pos) +bool UnixTimeMillisecondsToDateTime::convertImpl(String & out, IParser::Pos & pos) { - String res = String(pos->begin,pos->end); + String res = String(pos->begin, pos->end); out = res; return false; } -bool UnixTimeNanosecondsToDateTime::convertImpl(String &out,IParser::Pos &pos) +bool UnixTimeNanosecondsToDateTime::convertImpl(String & out, IParser::Pos & pos) { - String res = String(pos->begin,pos->end); + String res = String(pos->begin, pos->end); out = res; return false; } -bool UnixTimeSecondsToDateTime::convertImpl(String &out,IParser::Pos &pos) +bool UnixTimeSecondsToDateTime::convertImpl(String & out, IParser::Pos & pos) { - const String fn_name = getKQLFunctionName(pos); + const String fn_name = getKQLFunctionName(pos); if (fn_name.empty()) return false; @@ -276,9 +278,8 @@ bool UnixTimeSecondsToDateTime::convertImpl(String &out,IParser::Pos &pos) return true; } -bool WeekOfYear::convertImpl(String &out,IParser::Pos &pos) +bool WeekOfYear::convertImpl(String & out, IParser::Pos & pos) { - const String fn_name = getKQLFunctionName(pos); if (fn_name.empty()) return false; @@ -288,7 +289,7 @@ bool WeekOfYear::convertImpl(String &out,IParser::Pos &pos) return true; } -bool MonthOfYear::convertImpl(String &out,IParser::Pos &pos) +bool MonthOfYear::convertImpl(String & out, IParser::Pos & pos) { return directMapping(out, pos, "toMonth"); diff --git a/src/Parsers/tests/KQL/gtest_KQL_dateTimeFunctions.cpp b/src/Parsers/tests/KQL/gtest_KQL_dateTimeFunctions.cpp new file mode 100644 index 00000000000..77ad9714735 --- /dev/null +++ b/src/Parsers/tests/KQL/gtest_KQL_dateTimeFunctions.cpp @@ -0,0 +1,126 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace +{ +using namespace DB; +using namespace std::literals; +} +class ParserDateTimeFuncTest : public ::testing::TestWithParam, ParserTestCase>> +{}; + +TEST_P(ParserDateTimeFuncTest, ParseQuery) +{ const auto & parser = std::get<0>(GetParam()); + const auto & [input_text, expected_ast] = std::get<1>(GetParam()); + ASSERT_NE(nullptr, parser); + if (expected_ast) + { + if (std::string(expected_ast).starts_with("throws")) + { + EXPECT_THROW(parseQuery(*parser, input_text.begin(), input_text.end(), 0, 0), DB::Exception); + } + else + { + ASTPtr ast; + ASSERT_NO_THROW(ast = parseQuery(*parser, input_text.begin(), input_text.end(), 0, 0)); + if (std::string("CREATE USER or ALTER USER query") != parser->getName() + && std::string("ATTACH access entity query") != parser->getName()) + { + EXPECT_EQ(expected_ast, serializeAST(*ast->clone(), false)); + } + else + { + if (input_text.starts_with("ATTACH")) + { + auto salt = (dynamic_cast(ast.get())->auth_data)->getSalt(); + EXPECT_TRUE(std::regex_match(salt, std::regex(expected_ast))); + } + else + { + EXPECT_TRUE(std::regex_match(serializeAST(*ast->clone(), false), std::regex(expected_ast))); + } + } + } + } + else + { + ASSERT_THROW(parseQuery(*parser, input_text.begin(), input_text.end(), 0, 0), DB::Exception); + } +} + +INSTANTIATE_TEST_SUITE_P(ParserKQLQuery, ParserDateTimeFuncTest, + ::testing::Combine( + ::testing::Values(std::make_shared()), + ::testing::ValuesIn(std::initializer_list{ + { + "print week_of_year(datetime(2020-12-31))", + "SELECT toWeek(toDateTime64('2020-12-31', 9, 'UTC'), 3, 'UTC')" + }, + { + "print startofweek(datetime(2017-01-01 10:10:17), -1)", + "SELECT toDateTime64(toStartOfWeek(toDateTime64('2017-01-01 10:10:17', 9, 'UTC')), 9, 'UTC') + toIntervalWeek(-1)" + }, + { + "print startofmonth(datetime(2017-01-01 10:10:17), -1)", + "SELECT toDateTime64(toStartOfMonth(toDateTime64('2017-01-01 10:10:17', 9, 'UTC')), 9, 'UTC') + toIntervalMonth(-1)" + }, + { + "print startofday(datetime(2017-01-01 10:10:17), -1)", + "SELECT toDateTime64(toStartOfDay(toDateTime64('2017-01-01 10:10:17', 9, 'UTC')), 9, 'UTC') + toIntervalDay(-1)" + + }, + { + "print monthofyear(datetime(2015-12-14))", + "SELECT toMonth(toDateTime64('2015-12-14', 9, 'UTC'))" + }, + { + "print hourofday(datetime(2015-12-14 10:54:00))", + "SELECT toHour(toDateTime64('2015-12-14 10:54:00', 9, 'UTC'))" + }, + { + "print getyear(datetime(2015-10-12))", + "SELECT toYear(toDateTime64('2015-10-12', 9, 'UTC'))" + }, + { + "print getmonth(datetime(2015-10-12))", + "SELECT toMonth(toDateTime64('2015-10-12', 9, 'UTC'))" + }, + { + "print dayofyear(datetime(2015-10-12))", + "SELECT toDayOfYear(toDateTime64('2015-10-12', 9, 'UTC'))" + }, + { + "print dayofmonth(datetime(2015-10-12))", + "SELECT toDayOfMonth(toDateTime64('2015-10-12', 9, 'UTC'))" + }, + { + "print unixtime_seconds_todatetime(1546300899)", + "SELECT toDateTime64(1546300899, 9, 'UTC')" + }, + { + "print dayofweek(datetime(2015-12-20))", + "SELECT toDayOfWeek(toDateTime64('2015-12-20', 9, 'UTC')) % 7" + }, + { + "print now()", + "SELECT now64(9, 'UTC')" + } + +})));