Added test and review comments

This commit is contained in:
HeenaBansal2009 2022-08-10 13:04:07 -07:00 committed by Yong Wang
parent 232e4c73f9
commit 09f117cfb1
3 changed files with 237 additions and 50 deletions

View File

@ -1,4 +1,64 @@
# August XX, 2022 # 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 ## KQL implemented features
The config setting to allow modify dialect setting. 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. - 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.

View File

@ -19,134 +19,136 @@
namespace DB 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; out = res;
return false; 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; out = res;
return false; 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; out = res;
return false; 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; out = res;
return false; 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; out = res;
return false; 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; out = res;
return false; return false;
} }
bool DayOfMonth::convertImpl(String &out,IParser::Pos &pos) bool DayOfMonth::convertImpl(String & out, IParser::Pos & pos)
{ {
return directMapping(out, pos, "toDayOfMonth"); 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); const String fn_name = getKQLFunctionName(pos);
if (fn_name.empty()) if (fn_name.empty())
return false; return false;
++pos; ++pos;
out = std::format("toDayOfWeek() + %7"); const String datetime_str = getConvertedArgument(fn_name, pos);
out = std::format("toDayOfWeek({})%7",datetime_str);
return true; return true;
} }
bool DayOfYear::convertImpl(String &out,IParser::Pos &pos) bool DayOfYear::convertImpl(String & out, IParser::Pos & pos)
{ {
return directMapping(out, pos, "toDayOfYear"); 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; out = res;
return false; 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; out = res;
return false; 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; out = res;
return false; 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; out = res;
return false; 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; out = res;
return false; return false;
} }
bool GetMonth::convertImpl(String &out,IParser::Pos &pos) bool GetMonth::convertImpl(String & out, IParser::Pos & pos)
{ {
return directMapping(out, pos, "toMonth"); 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"); 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"); 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; out = res;
return false; 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; out = res;
return false; return false;
} }
bool Now::convertImpl(String &out,IParser::Pos &pos) bool Now::convertImpl(String & out, IParser::Pos & pos)
{ {
const String fn_name = getKQLFunctionName(pos); const String fn_name = getKQLFunctionName(pos);
if (fn_name.empty()) if (fn_name.empty())
@ -163,7 +165,7 @@ bool Now::convertImpl(String &out,IParser::Pos &pos)
return true; return true;
} }
bool StartOfDay::convertImpl(String &out,IParser::Pos &pos) bool StartOfDay::convertImpl(String & out, IParser::Pos & pos)
{ {
const String fn_name = getKQLFunctionName(pos); const String fn_name = getKQLFunctionName(pos);
@ -184,7 +186,7 @@ bool StartOfDay::convertImpl(String &out,IParser::Pos &pos)
return true; return true;
} }
bool StartOfMonth::convertImpl(String &out,IParser::Pos &pos) bool StartOfMonth::convertImpl(String & out, IParser::Pos & pos)
{ {
const String fn_name = getKQLFunctionName(pos); const String fn_name = getKQLFunctionName(pos);
if (fn_name.empty()) if (fn_name.empty())
@ -204,7 +206,7 @@ bool StartOfMonth::convertImpl(String &out,IParser::Pos &pos)
return true; return true;
} }
bool StartOfWeek::convertImpl(String &out,IParser::Pos &pos) bool StartOfWeek::convertImpl(String & out, IParser::Pos & pos)
{ {
const String fn_name = getKQLFunctionName(pos); const String fn_name = getKQLFunctionName(pos);
if (fn_name.empty()) if (fn_name.empty())
@ -224,9 +226,9 @@ bool StartOfWeek::convertImpl(String &out,IParser::Pos &pos)
return true; 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()) if (fn_name.empty())
return false; return false;
@ -243,30 +245,30 @@ bool StartOfYear::convertImpl(String &out,IParser::Pos &pos)
return true; 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; out = res;
return false; 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; out = res;
return false; 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; out = res;
return false; 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()) if (fn_name.empty())
return false; return false;
@ -276,9 +278,8 @@ bool UnixTimeSecondsToDateTime::convertImpl(String &out,IParser::Pos &pos)
return true; return true;
} }
bool WeekOfYear::convertImpl(String &out,IParser::Pos &pos) bool WeekOfYear::convertImpl(String & out, IParser::Pos & pos)
{ {
const String fn_name = getKQLFunctionName(pos); const String fn_name = getKQLFunctionName(pos);
if (fn_name.empty()) if (fn_name.empty())
return false; return false;
@ -288,7 +289,7 @@ bool WeekOfYear::convertImpl(String &out,IParser::Pos &pos)
return true; return true;
} }
bool MonthOfYear::convertImpl(String &out,IParser::Pos &pos) bool MonthOfYear::convertImpl(String & out, IParser::Pos & pos)
{ {
return directMapping(out, pos, "toMonth"); return directMapping(out, pos, "toMonth");

View File

@ -0,0 +1,126 @@
#include <Parsers/tests/gtest_common.h>
#include <IO/WriteBufferFromOStream.h>
#include <Interpreters/applyTableOverride.h>
#include <Parsers/ASTCreateQuery.h>
#include <Parsers/ASTFunction.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/Access/ASTCreateUserQuery.h>
#include <Parsers/Access/ParserCreateUserQuery.h>
#include <Parsers/ParserAlterQuery.h>
#include <Parsers/ParserCreateQuery.h>
#include <Parsers/ParserOptimizeQuery.h>
#include <Parsers/ParserQueryWithOutput.h>
#include <Parsers/ParserAttachAccessEntity.h>
#include <Parsers/formatAST.h>
#include <Parsers/parseQuery.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <string_view>
#include <regex>
#include <gtest/gtest.h>
namespace
{
using namespace DB;
using namespace std::literals;
}
class ParserDateTimeFuncTest : public ::testing::TestWithParam<std::tuple<std::shared_ptr<DB::IParser>, 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<const ASTCreateUserQuery *>(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<DB::ParserKQLQuery>()),
::testing::ValuesIn(std::initializer_list<ParserTestCase>{
{
"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')"
}
})));