From 684ec8adb95277661dc0818e2063d17e23eaf224 Mon Sep 17 00:00:00 2001 From: Zenglin Luo Date: Tue, 8 Jun 2021 19:47:02 +0800 Subject: [PATCH 1/5] [Function] Support date function: yearweek(), week(), makedate(). (#5999) --- be/src/exprs/timestamp_functions.cpp | 42 ++++++++ be/src/exprs/timestamp_functions.h | 13 +++ be/src/runtime/datetime_value.cpp | 19 ++++ be/src/runtime/datetime_value.h | 2 + be/test/exprs/timestamp_functions_test.cpp | 95 +++++++++++++++++++ .../date-time-functions/makedate.md | 45 +++++++++ .../sql-functions/date-time-functions/week.md | 69 ++++++++++++++ .../date-time-functions/yearweek.md | 81 ++++++++++++++++ .../date-time-functions/makedate.md | 46 +++++++++ .../sql-functions/date-time-functions/week.md | 78 +++++++++++++++ .../date-time-functions/yearweek.md | 84 ++++++++++++++++ .../org/apache/doris/rewrite/FEFunctions.java | 37 ++++++++ gensrc/script/doris_builtins_functions.py | 10 ++ 13 files changed, 621 insertions(+) create mode 100644 docs/en/sql-reference/sql-functions/date-time-functions/makedate.md create mode 100644 docs/en/sql-reference/sql-functions/date-time-functions/week.md create mode 100644 docs/en/sql-reference/sql-functions/date-time-functions/yearweek.md create mode 100644 docs/zh-CN/sql-reference/sql-functions/date-time-functions/makedate.md create mode 100644 docs/zh-CN/sql-reference/sql-functions/date-time-functions/week.md create mode 100644 docs/zh-CN/sql-reference/sql-functions/date-time-functions/yearweek.md diff --git a/be/src/exprs/timestamp_functions.cpp b/be/src/exprs/timestamp_functions.cpp index 730791aa7b74f7..a951bb8408e7e1 100644 --- a/be/src/exprs/timestamp_functions.cpp +++ b/be/src/exprs/timestamp_functions.cpp @@ -159,6 +159,36 @@ IntVal TimestampFunctions::week_of_year(FunctionContext* context, const DateTime return IntVal::null(); } +IntVal TimestampFunctions::year_week(FunctionContext *context, const DateTimeVal &ts_val) { + return year_week(context, ts_val, doris_udf::IntVal{0}); +} + +IntVal TimestampFunctions::year_week(FunctionContext *context, const DateTimeVal &ts_val, const doris_udf::IntVal &mode) { + if (ts_val.is_null) { + return IntVal::null(); + } + const DateTimeValue &ts_value = DateTimeValue::from_datetime_val(ts_val); + if (ts_value.is_valid_date()) { + return ts_value.year_week(mysql_week_mode(mode.val)); + } + return IntVal::null(); +} + +IntVal TimestampFunctions::week(FunctionContext *context, const DateTimeVal &ts_val) { + return week(context, ts_val, doris_udf::IntVal{0}); +} + +IntVal TimestampFunctions::week(FunctionContext *context, const DateTimeVal &ts_val, const doris_udf::IntVal& mode) { + if (ts_val.is_null) { + return IntVal::null(); + } + const DateTimeValue &ts_value = DateTimeValue::from_datetime_val(ts_val); + if (ts_value.is_valid_date()) { + return {ts_value.week(mysql_week_mode(mode.val))}; + } + return IntVal::null(); +} + IntVal TimestampFunctions::hour(FunctionContext* context, const DateTimeVal& ts_val) { if (ts_val.is_null) { return IntVal::null(); @@ -183,6 +213,18 @@ IntVal TimestampFunctions::second(FunctionContext* context, const DateTimeVal& t return IntVal(ts_value.second()); } +DateTimeVal TimestampFunctions::make_date(FunctionContext *ctx, const IntVal &year, const IntVal &count) { + if (count.val > 0) { + // year-1-1 + DateTimeValue ts_value{year.val * 10000000000 + 101000000}; + ts_value.set_type(TIME_DATE); + DateTimeVal ts_val; + ts_value.to_datetime_val(&ts_val); + return timestamp_time_op(ctx, ts_val, {count.val - 1}, true); + } + return DateTimeVal::null(); +} + DateTimeVal TimestampFunctions::to_date(FunctionContext* ctx, const DateTimeVal& ts_val) { if (ts_val.is_null) { return DateTimeVal::null(); diff --git a/be/src/exprs/timestamp_functions.h b/be/src/exprs/timestamp_functions.h index a0dffd55091951..17f38f62eb42aa 100644 --- a/be/src/exprs/timestamp_functions.h +++ b/be/src/exprs/timestamp_functions.h @@ -69,6 +69,16 @@ class TimestampFunctions { const doris_udf::DateTimeVal& ts_val); static doris_udf::IntVal week_of_year(doris_udf::FunctionContext* context, const doris_udf::DateTimeVal& ts_val); + static doris_udf::IntVal year_week(doris_udf::FunctionContext *context, + const doris_udf::DateTimeVal &ts_val); + static doris_udf::IntVal year_week(doris_udf::FunctionContext *context, + const doris_udf::DateTimeVal &ts_val, + const doris_udf::IntVal ¶); + static doris_udf::IntVal week(doris_udf::FunctionContext *context, + const doris_udf::DateTimeVal &ts_val); + static doris_udf::IntVal week(doris_udf::FunctionContext *context, + const doris_udf::DateTimeVal &ts_val, + const doris_udf::IntVal &mode); static doris_udf::IntVal hour(doris_udf::FunctionContext* context, const doris_udf::DateTimeVal& ts_val); static doris_udf::IntVal minute(doris_udf::FunctionContext* context, @@ -77,6 +87,9 @@ class TimestampFunctions { const doris_udf::DateTimeVal& ts_val); // Date/time functions. + static doris_udf::DateTimeVal make_date(doris_udf::FunctionContext* ctx, + const doris_udf::IntVal& year, + const doris_udf::IntVal& count); static doris_udf::DateTimeVal to_date(doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val); static doris_udf::IntVal date_diff(doris_udf::FunctionContext* ctx, diff --git a/be/src/runtime/datetime_value.cpp b/be/src/runtime/datetime_value.cpp index 9b583708369d6f..b417b8827cb701 100644 --- a/be/src/runtime/datetime_value.cpp +++ b/be/src/runtime/datetime_value.cpp @@ -947,6 +947,25 @@ uint8_t DateTimeValue::week(uint8_t mode) const { return calc_week(*this, mode, &year); } +uint32_t DateTimeValue::year_week(uint8_t mode) const { + uint32_t year = 0; + // The range of the week in the year_week is 1-53, so the mode WEEK_YEAR is always true. + uint8_t week = calc_week(*this, mode | 2, &year); + // When the mode WEEK_FIRST_WEEKDAY is not set, + // the week in which the last three days of the year fall may belong to the following year. + if (week == 53 && day() >= 29 && !(mode & 4)) { + uint8_t monday_first = mode & WEEK_MONDAY_FIRST; + uint64_t daynr_of_last_day = calc_daynr(_year, 12, 31); + uint8_t weekday_of_last_day = calc_weekday(daynr_of_last_day, !monday_first); + + if (weekday_of_last_day - monday_first < 2) { + ++year; + week = 1; + } + } + return year * 100 + week; +} + uint8_t DateTimeValue::calc_weekday(uint64_t day_nr, bool is_sunday_first_day) { return (day_nr + 5L + (is_sunday_first_day ? 1L : 0L)) % 7; } diff --git a/be/src/runtime/datetime_value.h b/be/src/runtime/datetime_value.h index b48f4ae2b597e0..c0ffb9798bf4c3 100644 --- a/be/src/runtime/datetime_value.h +++ b/be/src/runtime/datetime_value.h @@ -333,6 +333,8 @@ class DateTimeValue { // next week is week 1. uint8_t week(uint8_t) const; + uint32_t year_week(uint8_t mode) const; + // Add interval bool date_add_interval(const TimeInterval& interval, TimeUnit unit); diff --git a/be/test/exprs/timestamp_functions_test.cpp b/be/test/exprs/timestamp_functions_test.cpp index 71d58906e57cac..d888c731d53df6 100644 --- a/be/test/exprs/timestamp_functions_test.cpp +++ b/be/test/exprs/timestamp_functions_test.cpp @@ -176,6 +176,101 @@ TEST_F(TimestampFunctionsTest, week_of_year_test) { delete context; } +TEST_F(TimestampFunctionsTest, year_week_test) { + doris_udf::FunctionContext* context = new doris_udf::FunctionContext(); + + DateTimeValue dtv1(20210101000000); + dtv1.set_type(TIME_DATE); + doris_udf::DateTimeVal tv1; + dtv1.to_datetime_val(&tv1); + ASSERT_EQ(202052, TimestampFunctions::year_week(context, tv1).val); + + DateTimeValue dtv2(20210103000000); + dtv2.set_type(TIME_DATE); + doris_udf::DateTimeVal tv2; + dtv2.to_datetime_val(&tv2); + ASSERT_EQ( 202101, TimestampFunctions::year_week(context, tv2).val); + + DateTimeValue dtv3(20210501000000); + dtv3.set_type(TIME_DATE); + doris_udf::DateTimeVal tv3; + dtv3.to_datetime_val(&tv3); + ASSERT_EQ( 202117, TimestampFunctions::year_week(context, tv3).val); + + DateTimeValue dtv4(20241230000000); + dtv4.set_type(TIME_DATE); + doris_udf::DateTimeVal tv4; + dtv4.to_datetime_val(&tv4); + ASSERT_EQ( 202501, TimestampFunctions::year_week(context, tv4, 1).val); + + DateTimeValue dtv5(20261229121030); + dtv5.set_type(TIME_DATETIME); + doris_udf::DateTimeVal tv5; + dtv5.to_datetime_val(&tv5); + ASSERT_EQ(202653, TimestampFunctions::year_week(context, tv5, 3).val); + delete context; +} + +TEST_F(TimestampFunctionsTest, week_test) { + doris_udf::FunctionContext* context = new doris_udf::FunctionContext(); + + DateTimeValue dtv1(20210101000000); + dtv1.set_type(TIME_DATE); + doris_udf::DateTimeVal tv1; + dtv1.to_datetime_val(&tv1); + ASSERT_EQ(0, TimestampFunctions::week(context, tv1).val); + + DateTimeValue dtv2(20210103000000); + dtv2.set_type(TIME_DATE); + doris_udf::DateTimeVal tv2; + dtv2.to_datetime_val(&tv2); + ASSERT_EQ( 1, TimestampFunctions::week(context, tv2).val); + + DateTimeValue dtv3(20210501000000); + dtv3.set_type(TIME_DATE); + doris_udf::DateTimeVal tv3; + dtv3.to_datetime_val(&tv3); + ASSERT_EQ( 17, TimestampFunctions::week(context, tv3).val); + + DateTimeValue dtv4(20210101000000); + dtv4.set_type(TIME_DATE); + doris_udf::DateTimeVal tv4; + dtv4.to_datetime_val(&tv4); + ASSERT_EQ( 0, TimestampFunctions::week(context, tv4, {1}).val); + + DateTimeValue dtv5(20211201000000); + dtv5.set_type(TIME_DATETIME); + doris_udf::DateTimeVal tv5; + dtv5.to_datetime_val(&tv5); + ASSERT_EQ(48, TimestampFunctions::week(context, tv5, 2).val); + delete context; +} + +TEST_F(TimestampFunctionsTest, make_date_test) { + doris_udf::FunctionContext* context = new doris_udf::FunctionContext(); + + ASSERT_EQ(true, TimestampFunctions::make_date(context, 2021, 0).is_null); + + DateTimeValue dtv1(20210101000000); + dtv1.set_type(TIME_DATE); + doris_udf::DateTimeVal tv1; + dtv1.to_datetime_val(&tv1); + ASSERT_EQ(tv1.packed_time, TimestampFunctions::make_date(context, 2021, 1).packed_time); + + DateTimeValue dtv2(20211027000000); + dtv2.set_type(TIME_DATE); + doris_udf::DateTimeVal tv2; + dtv2.to_datetime_val(&tv2); + ASSERT_EQ(tv2.packed_time, TimestampFunctions::make_date(context, 2021, 300).packed_time); + + DateTimeValue dtv3(20220204000000); + dtv3.set_type(TIME_DATE); + doris_udf::DateTimeVal tv3; + dtv3.to_datetime_val(&tv3); + ASSERT_EQ(tv3.packed_time, TimestampFunctions::make_date(context, 2021, 400).packed_time); + delete context; +} + TEST_F(TimestampFunctionsTest, time_diff_test) { DateTimeValue dt1(20190718120000); dt1.set_type(TIME_DATETIME); diff --git a/docs/en/sql-reference/sql-functions/date-time-functions/makedate.md b/docs/en/sql-reference/sql-functions/date-time-functions/makedate.md new file mode 100644 index 00000000000000..ceea6316dd822d --- /dev/null +++ b/docs/en/sql-reference/sql-functions/date-time-functions/makedate.md @@ -0,0 +1,45 @@ +--- +{ + "title": "makedate", + "language": "en" +} +--- + + + +# makedate +## Description +### Syntax + +`DATE MAKEDATE(INT year, INT dayofyear)` + +Returns a date, given year and day-of-year values. dayofyear must be greater than 0 or the result is NULL. + +## example +``` +mysql> select makedate(2021,1), makedate(2021,100), makedate(2021,400); ++-------------------+---------------------+---------------------+ +| makedate(2021, 1) | makedate(2021, 100) | makedate(2021, 400) | ++-------------------+---------------------+---------------------+ +| 2021-01-01 | 2021-04-10 | 2022-02-04 | ++-------------------+---------------------+---------------------+ +``` +## keyword + MAKEDATE \ No newline at end of file diff --git a/docs/en/sql-reference/sql-functions/date-time-functions/week.md b/docs/en/sql-reference/sql-functions/date-time-functions/week.md new file mode 100644 index 00000000000000..231fd7baabfc2e --- /dev/null +++ b/docs/en/sql-reference/sql-functions/date-time-functions/week.md @@ -0,0 +1,69 @@ +--- +{ + "title": "week", + "language": "en" +} +--- + + + +# week +## Description +### Syntax + +`INT WEEK(DATE date)` +`INT WEEK(DATE date, INT mode)` + +Returns the week number for date.The value of the mode argument defaults to 0. +The following table describes how the mode argument works. ++---------------------------------------------------------------+ +|Mode |First day of week |Range |Week 1 is the first week … | ++---------------------------------------------------------------+ +|0 |Sunday |0-53 |with a Sunday in this year | +|1 |Monday |0-53 |with 4 or more days this year | +|2 |Sunday |1-53 |with a Sunday in this year | +|3 |Monday |1-53 |with 4 or more days this year | +|4 |Sunday |0-53 |with 4 or more days this year | +|5 |Monday |0-53 |with a Monday in this year | +|6 |Sunday |1-53 |with 4 or more days this year | +|7 |Monday |1-53 |with a Monday in this year | ++---------------------------------------------------------------+ + +The parameter is Date or Datetime type + +## example +``` +mysql> select week('2020-1-1'); ++------------------+ +| week('2020-1-1') | ++------------------+ +| 0 | ++------------------+ +``` +``` +mysql> select week('2020-7-1',1); ++---------------------+ +| week('2020-7-1', 1) | ++---------------------+ +| 27 | ++---------------------+ +``` +## keyword +WEEK diff --git a/docs/en/sql-reference/sql-functions/date-time-functions/yearweek.md b/docs/en/sql-reference/sql-functions/date-time-functions/yearweek.md new file mode 100644 index 00000000000000..54b62737ca9aab --- /dev/null +++ b/docs/en/sql-reference/sql-functions/date-time-functions/yearweek.md @@ -0,0 +1,81 @@ +--- +{ + "title": "yearweek", + "language": "en" +} +--- + + + +# yearweek +## Description +### Syntax + +`INT YEARWEEK(DATE date)` +`INT YEARWEEK(DATE date, INT mode)` + +Returns year and week for a date.The value of the mode argument defaults to 0. +When the week of the date belongs to the previous year, the year and week of the previous year are returned; +when the week of the date belongs to the next year, the year of the next year is returned and the week is 1. + +The following table describes how the mode argument works. ++----------------------------------------------------------------+ +|Mode |First day of week |Range |Week 1 is the first week … | ++----------------------------------------------------------------+ +|0 |Sunday |1-53 |with a Sunday in this year | +|1 |Monday |1-53 |with 4 or more days this year | +|2 |Sunday |1-53 |with a Sunday in this year | +|3 |Monday |1-53 |with 4 or more days this year | +|4 |Sunday |1-53 |with 4 or more days this year | +|5 |Monday |1-53 |with a Monday in this year | +|6 |Sunday |1-53 |with 4 or more days this year | +|7 |Monday |1-53 |with a Monday in this year | ++----------------------------------------------------------------+ + +The parameter is Date or Datetime type + +## example +``` +mysql> select yearweek('2021-1-1'); ++----------------------+ +| yearweek('2021-1-1') | ++----------------------+ +| 202052 | ++----------------------+ +``` +``` +mysql> select yearweek('2020-7-1'); ++----------------------+ +| yearweek('2020-7-1') | ++----------------------+ +| 202026 | ++----------------------+ +``` +``` +mysql> select yearweek('2024-12-30',1); ++------------------------------------+ +| yearweek('2024-12-30 00:00:00', 1) | ++------------------------------------+ +| 202501 | ++------------------------------------+ +``` + +## keyword +YEARWEEK diff --git a/docs/zh-CN/sql-reference/sql-functions/date-time-functions/makedate.md b/docs/zh-CN/sql-reference/sql-functions/date-time-functions/makedate.md new file mode 100644 index 00000000000000..2d1f94e7b1ec45 --- /dev/null +++ b/docs/zh-CN/sql-reference/sql-functions/date-time-functions/makedate.md @@ -0,0 +1,46 @@ +--- +{ + "title": "makedate", + "language": "zh-CN" +} +--- + + + +# makedate +## description +### Syntax + +`DATE MAKEDATE(INT year, INT dayofyear)` +返回指定年份和dayofyear构建的日期。dayofyear必须大于0,否则结果为空。 + +## example +``` +mysql> select makedate(2021,1), makedate(2021,100), makedate(2021,400); ++-------------------+---------------------+---------------------+ +| makedate(2021, 1) | makedate(2021, 100) | makedate(2021, 400) | ++-------------------+---------------------+---------------------+ +| 2021-01-01 | 2021-04-10 | 2022-02-04 | ++-------------------+---------------------+---------------------+ +``` + +## keyword + + YEARWEEK diff --git a/docs/zh-CN/sql-reference/sql-functions/date-time-functions/week.md b/docs/zh-CN/sql-reference/sql-functions/date-time-functions/week.md new file mode 100644 index 00000000000000..84b352e27d093b --- /dev/null +++ b/docs/zh-CN/sql-reference/sql-functions/date-time-functions/week.md @@ -0,0 +1,78 @@ +--- +{ + "title": "week", + "language": "zh-CN" +} +--- + + + +# week +## description +### Syntax + +`INT YEARWEEK(DATE date)` +`INT YEARWEEK(DATE date, INT mode)` + +返回指定日期的星期数。mode的值默认为0。 +参数mode的作用参见下面的表格: ++------------------------------------------------------------------------------+ +|Mode |星期的第一天 |星期数的范围 |第一个星期的定义 | ++------------------------------------------------------------------------------+ +|0 |星期日 |0-53 |这一年中的第一个星期日所在的星期 | +|1 |星期一 |0-53 |这一年的日期所占的天数大于等于4天的第一个星期| +|2 |星期日 |1-53 |这一年中的第一个星期日所在的星期 | +|3 |星期一 |1-53 |这一年的日期所占的天数大于等于4天的第一个星期| +|4 |星期日 |0-53 |这一年的日期所占的天数大于等于4天的第一个星期| +|5 |星期一 |0-53 |这一年中的第一个星期一所在的星期 | +|6 |星期日 |1-53 |这一年的日期所占的天数大于等于4天的第一个星期| +|7 |星期一 |1-53 |这一年中的第一个星期一所在的星期 | ++------------------------------------------------------------------------------+ + +参数为Date或者Datetime类型 + +## example +``` +mysql> select yearweek('2021-1-1'); ++----------------------+ +| yearweek('2021-1-1') | ++----------------------+ +| 202052 | ++----------------------+ +``` +``` +mysql> select yearweek('2020-7-1'); ++----------------------+ +| yearweek('2020-7-1') | ++----------------------+ +| 202026 | ++----------------------+ +``` +``` +mysql> select yearweek('2024-12-30',1); ++------------------------------------+ +| yearweek('2024-12-30 00:00:00', 1) | ++------------------------------------+ +| 202501 | ++------------------------------------+ +``` + +## keyword + WEEK diff --git a/docs/zh-CN/sql-reference/sql-functions/date-time-functions/yearweek.md b/docs/zh-CN/sql-reference/sql-functions/date-time-functions/yearweek.md new file mode 100644 index 00000000000000..c5291f953c6268 --- /dev/null +++ b/docs/zh-CN/sql-reference/sql-functions/date-time-functions/yearweek.md @@ -0,0 +1,84 @@ +--- +{ + "title": "yearweek", + "language": "zh-CN" +} +--- + + + +# yearweek +## description +### Syntax + +`INT YEARWEEK(DATE date)` +`INT YEARWEEK(DATE date, INT mode)` + + + +返回指定日期的年份和星期数。mode的值默认为0。 +当日期所在的星期属于上一年时,返回的是上一年的年份和星期数; +当日期所在的星期属于下一年时,返回的是下一年的年份,星期数为1。 +参数mode的作用参见下面的表格: ++-------------------------------------------------------------------------------+ +|Mode |星期的第一天 |星期数的范围 |第一个星期的定义 | ++-------------------------------------------------------------------------------+ +|0 |星期日 |1-53 |这一年中的第一个星期日所在的星期 | +|1 |星期一 |1-53 |这一年的日期所占的天数大于等于4天的第一个星期| +|2 |星期日 |1-53 |这一年中的第一个星期日所在的星期 | +|3 |星期一 |1-53 |这一年的日期所占的天数大于等于4天的第一个星期| +|4 |星期日 |1-53 |这一年的日期所占的天数大于等于4天的第一个星期| +|5 |星期一 |1-53 |这一年中的第一个星期一所在的星期 | +|6 |星期日 |1-53 |这一年的日期所占的天数大于等于4天的第一个星期| +|7 |星期一 |1-53 |这一年中的第一个星期一所在的星期 | ++-------------------------------------------------------------------------------+ + +参数为Date或者Datetime类型 + +## example + +``` +mysql> select yearweek('2021-1-1'); ++----------------------+ +| yearweek('2021-1-1') | ++----------------------+ +| 202052 | ++----------------------+ +``` +``` +mysql> select yearweek('2020-7-1'); ++----------------------+ +| yearweek('2020-7-1') | ++----------------------+ +| 202026 | ++----------------------+ +``` +``` +mysql> select yearweek('2024-12-30',1); ++------------------------------------+ +| yearweek('2024-12-30 00:00:00', 1) | ++------------------------------------+ +| 202501 | ++------------------------------------+ +``` + +## keyword + + YEARWEEK diff --git a/fe/fe-core/src/main/java/org/apache/doris/rewrite/FEFunctions.java b/fe/fe-core/src/main/java/org/apache/doris/rewrite/FEFunctions.java index 17d724106cc890..8464e456555fb2 100755 --- a/fe/fe-core/src/main/java/org/apache/doris/rewrite/FEFunctions.java +++ b/fe/fe-core/src/main/java/org/apache/doris/rewrite/FEFunctions.java @@ -132,6 +132,11 @@ public static DateLiteral dateParse(StringLiteral date, StringLiteral fmtLiteral } } + @FEFunction(name = "makedate", argTypes = { "INT", "INT" }, returnType = "DATETIME") + public static DateLiteral makeDate(LiteralExpr date) throws AnalysisException { + return (DateLiteral) date; + } + @FEFunction(name = "date_sub", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME") public static DateLiteral dateSub(LiteralExpr date, LiteralExpr day) throws AnalysisException { return dateAdd(date, new IntLiteral(-(int) day.getLongValue())); @@ -252,6 +257,38 @@ public static DateLiteral utcTimestamp() throws AnalysisException { Type.DATETIME); } + @FEFunction(name = "yearweek", argTypes = { "DATE" }, returnType = "INT") + public static IntLiteral yearWeek(LiteralExpr arg) throws AnalysisException { + if (arg instanceof IntLiteral) { + return (IntLiteral) arg; + } + return null; + } + + @FEFunction(name = "yearweek", argTypes = { "DATE", "INT" }, returnType = "INT") + public static IntLiteral yearWeekMod(LiteralExpr arg) throws AnalysisException { + if (arg instanceof IntLiteral) { + return (IntLiteral) arg; + } + return null; + } + + @FEFunction(name = "week", argTypes = { "DATE" }, returnType = "INT") + public static IntLiteral week(LiteralExpr arg) throws AnalysisException { + if (arg instanceof IntLiteral) { + return (IntLiteral) arg; + } + return null; + } + + @FEFunction(name = "week", argTypes = { "DATE", "INT" }, returnType = "INT") + public static IntLiteral weekMode(LiteralExpr arg) throws AnalysisException { + if (arg instanceof IntLiteral) { + return (IntLiteral) arg; + } + return null; + } + /** ------------------------------------------------------------------------------ */ diff --git a/gensrc/script/doris_builtins_functions.py b/gensrc/script/doris_builtins_functions.py index 5e773d6bab786d..009c40e7ebeec2 100755 --- a/gensrc/script/doris_builtins_functions.py +++ b/gensrc/script/doris_builtins_functions.py @@ -150,6 +150,14 @@ [['weekofyear'], 'INT', ['DATETIME'], '_ZN5doris18TimestampFunctions12week_of_yearEPN9doris_udf' '15FunctionContextERKNS1_11DateTimeValE'], + [['yearweek'], 'INT', ['DATETIME'], + '_ZN5doris18TimestampFunctions9year_weekEPN9doris_udf15FunctionContextERKNS1_11DateTimeValE'], + [['yearweek'], 'INT', ['DATETIME', 'INT'], + '_ZN5doris18TimestampFunctions9year_weekEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValE'], + [['week'], 'INT', ['DATETIME'], + '_ZN5doris18TimestampFunctions4weekEPN9doris_udf15FunctionContextERKNS1_11DateTimeValE'], + [['week'], 'INT', ['DATETIME', 'INT'], + '_ZN5doris18TimestampFunctions4weekEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValE'], [['hour'], 'INT', ['DATETIME'], '_ZN5doris18TimestampFunctions4hourEPN9doris_udf15FunctionContextERKNS1_11DateTimeValE'], [['minute'], 'INT', ['DATETIME'], @@ -157,6 +165,8 @@ [['second'], 'INT', ['DATETIME'], '_ZN5doris18TimestampFunctions6secondEPN9doris_udf15FunctionContextERKNS1_11DateTimeValE'], + [['makedate'], 'DATETIME', ['INT', 'INT'], + '_ZN5doris18TimestampFunctions9make_dateEPN9doris_udf15FunctionContextERKNS1_6IntValES6_'], [['years_add'], 'DATETIME', ['DATETIME', 'INT'], '_ZN5doris18TimestampFunctions9years_addEPN9doris_udf' '15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValE'], From af224d1ffd2f2fb5a8c1e8c06ffca471134c5f49 Mon Sep 17 00:00:00 2001 From: Zenglin Luo Date: Tue, 8 Jun 2021 20:28:40 +0800 Subject: [PATCH 2/5] Adjusted code format --- be/test/exprs/timestamp_functions_test.cpp | 12 ++++++------ .../sql-functions/date-time-functions/yearweek.md | 2 -- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/be/test/exprs/timestamp_functions_test.cpp b/be/test/exprs/timestamp_functions_test.cpp index d888c731d53df6..3361b35396b8da 100644 --- a/be/test/exprs/timestamp_functions_test.cpp +++ b/be/test/exprs/timestamp_functions_test.cpp @@ -189,19 +189,19 @@ TEST_F(TimestampFunctionsTest, year_week_test) { dtv2.set_type(TIME_DATE); doris_udf::DateTimeVal tv2; dtv2.to_datetime_val(&tv2); - ASSERT_EQ( 202101, TimestampFunctions::year_week(context, tv2).val); + ASSERT_EQ(202101, TimestampFunctions::year_week(context, tv2).val); DateTimeValue dtv3(20210501000000); dtv3.set_type(TIME_DATE); doris_udf::DateTimeVal tv3; dtv3.to_datetime_val(&tv3); - ASSERT_EQ( 202117, TimestampFunctions::year_week(context, tv3).val); + ASSERT_EQ(202117, TimestampFunctions::year_week(context, tv3).val); DateTimeValue dtv4(20241230000000); dtv4.set_type(TIME_DATE); doris_udf::DateTimeVal tv4; dtv4.to_datetime_val(&tv4); - ASSERT_EQ( 202501, TimestampFunctions::year_week(context, tv4, 1).val); + ASSERT_EQ(202501, TimestampFunctions::year_week(context, tv4, 1).val); DateTimeValue dtv5(20261229121030); dtv5.set_type(TIME_DATETIME); @@ -224,19 +224,19 @@ TEST_F(TimestampFunctionsTest, week_test) { dtv2.set_type(TIME_DATE); doris_udf::DateTimeVal tv2; dtv2.to_datetime_val(&tv2); - ASSERT_EQ( 1, TimestampFunctions::week(context, tv2).val); + ASSERT_EQ(1, TimestampFunctions::week(context, tv2).val); DateTimeValue dtv3(20210501000000); dtv3.set_type(TIME_DATE); doris_udf::DateTimeVal tv3; dtv3.to_datetime_val(&tv3); - ASSERT_EQ( 17, TimestampFunctions::week(context, tv3).val); + ASSERT_EQ(17, TimestampFunctions::week(context, tv3).val); DateTimeValue dtv4(20210101000000); dtv4.set_type(TIME_DATE); doris_udf::DateTimeVal tv4; dtv4.to_datetime_val(&tv4); - ASSERT_EQ( 0, TimestampFunctions::week(context, tv4, {1}).val); + ASSERT_EQ(0, TimestampFunctions::week(context, tv4, {1}).val); DateTimeValue dtv5(20211201000000); dtv5.set_type(TIME_DATETIME); diff --git a/docs/zh-CN/sql-reference/sql-functions/date-time-functions/yearweek.md b/docs/zh-CN/sql-reference/sql-functions/date-time-functions/yearweek.md index c5291f953c6268..d45fd322f2bfea 100644 --- a/docs/zh-CN/sql-reference/sql-functions/date-time-functions/yearweek.md +++ b/docs/zh-CN/sql-reference/sql-functions/date-time-functions/yearweek.md @@ -31,8 +31,6 @@ under the License. `INT YEARWEEK(DATE date)` `INT YEARWEEK(DATE date, INT mode)` - - 返回指定日期的年份和星期数。mode的值默认为0。 当日期所在的星期属于上一年时,返回的是上一年的年份和星期数; 当日期所在的星期属于下一年时,返回的是下一年的年份,星期数为1。 From 38e9409d95d3483515a06bc7bbe3ac631c24a21b Mon Sep 17 00:00:00 2001 From: Zenglin Luo Date: Wed, 9 Jun 2021 14:17:01 +0800 Subject: [PATCH 3/5] Add documents to docs/.vuepress/sidebar/zh-CN.js and docs/.vuepress/sidebar/en.js --- docs/.vuepress/sidebar/en.js | 3 +++ docs/.vuepress/sidebar/zh-CN.js | 3 +++ 2 files changed, 6 insertions(+) diff --git a/docs/.vuepress/sidebar/en.js b/docs/.vuepress/sidebar/en.js index 5f0bba4c697c08..75cfe7148a9bbd 100644 --- a/docs/.vuepress/sidebar/en.js +++ b/docs/.vuepress/sidebar/en.js @@ -251,6 +251,7 @@ module.exports = [ "from_days", "from_unixtime", "hour", + "makedate", "minute", "month", "monthname", @@ -264,8 +265,10 @@ module.exports = [ "to_days", "unix_timestamp", "utc_timestamp", + "week", "weekofyear", "year", + "yearweek", ], }, { diff --git a/docs/.vuepress/sidebar/zh-CN.js b/docs/.vuepress/sidebar/zh-CN.js index d05ee281ae4d40..cfbe0a4e7db8ce 100644 --- a/docs/.vuepress/sidebar/zh-CN.js +++ b/docs/.vuepress/sidebar/zh-CN.js @@ -256,6 +256,7 @@ module.exports = [ "from_days", "from_unixtime", "hour", + "makedate", "minute", "month", "monthname", @@ -269,8 +270,10 @@ module.exports = [ "to_days", "unix_timestamp", "utc_timestamp", + "week", "weekofyear", "year", + "yearweek", ], }, { From e369bcc4b83bfb726a9b212df12c326299a8d24e Mon Sep 17 00:00:00 2001 From: Zenglin Luo Date: Wed, 9 Jun 2021 14:37:54 +0800 Subject: [PATCH 4/5] Reformat the tables in the document --- docs/en/sql-reference/sql-functions/date-time-functions/week.md | 2 ++ .../sql-reference/sql-functions/date-time-functions/yearweek.md | 2 ++ .../sql-reference/sql-functions/date-time-functions/week.md | 2 ++ .../sql-reference/sql-functions/date-time-functions/yearweek.md | 2 ++ 4 files changed, 8 insertions(+) diff --git a/docs/en/sql-reference/sql-functions/date-time-functions/week.md b/docs/en/sql-reference/sql-functions/date-time-functions/week.md index 231fd7baabfc2e..df46efcf02923d 100644 --- a/docs/en/sql-reference/sql-functions/date-time-functions/week.md +++ b/docs/en/sql-reference/sql-functions/date-time-functions/week.md @@ -33,6 +33,7 @@ under the License. Returns the week number for date.The value of the mode argument defaults to 0. The following table describes how the mode argument works. +``` +---------------------------------------------------------------+ |Mode |First day of week |Range |Week 1 is the first week … | +---------------------------------------------------------------+ @@ -45,6 +46,7 @@ The following table describes how the mode argument works. |6 |Sunday |1-53 |with 4 or more days this year | |7 |Monday |1-53 |with a Monday in this year | +---------------------------------------------------------------+ +``` The parameter is Date or Datetime type diff --git a/docs/en/sql-reference/sql-functions/date-time-functions/yearweek.md b/docs/en/sql-reference/sql-functions/date-time-functions/yearweek.md index 54b62737ca9aab..bd4d702a9f5024 100644 --- a/docs/en/sql-reference/sql-functions/date-time-functions/yearweek.md +++ b/docs/en/sql-reference/sql-functions/date-time-functions/yearweek.md @@ -36,6 +36,7 @@ When the week of the date belongs to the previous year, the year and week of the when the week of the date belongs to the next year, the year of the next year is returned and the week is 1. The following table describes how the mode argument works. +``` +----------------------------------------------------------------+ |Mode |First day of week |Range |Week 1 is the first week … | +----------------------------------------------------------------+ @@ -48,6 +49,7 @@ The following table describes how the mode argument works. |6 |Sunday |1-53 |with 4 or more days this year | |7 |Monday |1-53 |with a Monday in this year | +----------------------------------------------------------------+ +``` The parameter is Date or Datetime type diff --git a/docs/zh-CN/sql-reference/sql-functions/date-time-functions/week.md b/docs/zh-CN/sql-reference/sql-functions/date-time-functions/week.md index 84b352e27d093b..203af53e1a898b 100644 --- a/docs/zh-CN/sql-reference/sql-functions/date-time-functions/week.md +++ b/docs/zh-CN/sql-reference/sql-functions/date-time-functions/week.md @@ -33,6 +33,7 @@ under the License. 返回指定日期的星期数。mode的值默认为0。 参数mode的作用参见下面的表格: +``` +------------------------------------------------------------------------------+ |Mode |星期的第一天 |星期数的范围 |第一个星期的定义 | +------------------------------------------------------------------------------+ @@ -45,6 +46,7 @@ under the License. |6 |星期日 |1-53 |这一年的日期所占的天数大于等于4天的第一个星期| |7 |星期一 |1-53 |这一年中的第一个星期一所在的星期 | +------------------------------------------------------------------------------+ +``` 参数为Date或者Datetime类型 diff --git a/docs/zh-CN/sql-reference/sql-functions/date-time-functions/yearweek.md b/docs/zh-CN/sql-reference/sql-functions/date-time-functions/yearweek.md index d45fd322f2bfea..12050b9e6a0334 100644 --- a/docs/zh-CN/sql-reference/sql-functions/date-time-functions/yearweek.md +++ b/docs/zh-CN/sql-reference/sql-functions/date-time-functions/yearweek.md @@ -35,6 +35,7 @@ under the License. 当日期所在的星期属于上一年时,返回的是上一年的年份和星期数; 当日期所在的星期属于下一年时,返回的是下一年的年份,星期数为1。 参数mode的作用参见下面的表格: +``` +-------------------------------------------------------------------------------+ |Mode |星期的第一天 |星期数的范围 |第一个星期的定义 | +-------------------------------------------------------------------------------+ @@ -47,6 +48,7 @@ under the License. |6 |星期日 |1-53 |这一年的日期所占的天数大于等于4天的第一个星期| |7 |星期一 |1-53 |这一年中的第一个星期一所在的星期 | +-------------------------------------------------------------------------------+ +``` 参数为Date或者Datetime类型 From 13c4b53b2ac1fd0f7dc523fe58f7a9ff2fa37843 Mon Sep 17 00:00:00 2001 From: Zenglin Luo Date: Wed, 9 Jun 2021 15:52:10 +0800 Subject: [PATCH 5/5] Using makedown's form syntax in documents --- .../sql-reference/sql-functions/date-time-functions/week.md | 6 +----- .../sql-functions/date-time-functions/yearweek.md | 6 +----- .../sql-reference/sql-functions/date-time-functions/week.md | 6 +----- .../sql-functions/date-time-functions/yearweek.md | 6 +----- 4 files changed, 4 insertions(+), 20 deletions(-) diff --git a/docs/en/sql-reference/sql-functions/date-time-functions/week.md b/docs/en/sql-reference/sql-functions/date-time-functions/week.md index df46efcf02923d..03d4d0a1563455 100644 --- a/docs/en/sql-reference/sql-functions/date-time-functions/week.md +++ b/docs/en/sql-reference/sql-functions/date-time-functions/week.md @@ -33,10 +33,8 @@ under the License. Returns the week number for date.The value of the mode argument defaults to 0. The following table describes how the mode argument works. -``` -+---------------------------------------------------------------+ |Mode |First day of week |Range |Week 1 is the first week … | -+---------------------------------------------------------------+ +|:----|:-----------------|:------|:-----------------------------| |0 |Sunday |0-53 |with a Sunday in this year | |1 |Monday |0-53 |with 4 or more days this year | |2 |Sunday |1-53 |with a Sunday in this year | @@ -45,8 +43,6 @@ The following table describes how the mode argument works. |5 |Monday |0-53 |with a Monday in this year | |6 |Sunday |1-53 |with 4 or more days this year | |7 |Monday |1-53 |with a Monday in this year | -+---------------------------------------------------------------+ -``` The parameter is Date or Datetime type diff --git a/docs/en/sql-reference/sql-functions/date-time-functions/yearweek.md b/docs/en/sql-reference/sql-functions/date-time-functions/yearweek.md index bd4d702a9f5024..42e9d51cd4f51d 100644 --- a/docs/en/sql-reference/sql-functions/date-time-functions/yearweek.md +++ b/docs/en/sql-reference/sql-functions/date-time-functions/yearweek.md @@ -36,10 +36,8 @@ When the week of the date belongs to the previous year, the year and week of the when the week of the date belongs to the next year, the year of the next year is returned and the week is 1. The following table describes how the mode argument works. -``` -+----------------------------------------------------------------+ |Mode |First day of week |Range |Week 1 is the first week … | -+----------------------------------------------------------------+ +|:----|:-----------------|:-------|:-----------------------------| |0 |Sunday |1-53 |with a Sunday in this year | |1 |Monday |1-53 |with 4 or more days this year | |2 |Sunday |1-53 |with a Sunday in this year | @@ -48,8 +46,6 @@ The following table describes how the mode argument works. |5 |Monday |1-53 |with a Monday in this year | |6 |Sunday |1-53 |with 4 or more days this year | |7 |Monday |1-53 |with a Monday in this year | -+----------------------------------------------------------------+ -``` The parameter is Date or Datetime type diff --git a/docs/zh-CN/sql-reference/sql-functions/date-time-functions/week.md b/docs/zh-CN/sql-reference/sql-functions/date-time-functions/week.md index 203af53e1a898b..23bebc6157a791 100644 --- a/docs/zh-CN/sql-reference/sql-functions/date-time-functions/week.md +++ b/docs/zh-CN/sql-reference/sql-functions/date-time-functions/week.md @@ -33,10 +33,8 @@ under the License. 返回指定日期的星期数。mode的值默认为0。 参数mode的作用参见下面的表格: -``` -+------------------------------------------------------------------------------+ |Mode |星期的第一天 |星期数的范围 |第一个星期的定义 | -+------------------------------------------------------------------------------+ +|:---|:-------------|:-----------|:--------------------------------------------| |0 |星期日 |0-53 |这一年中的第一个星期日所在的星期 | |1 |星期一 |0-53 |这一年的日期所占的天数大于等于4天的第一个星期| |2 |星期日 |1-53 |这一年中的第一个星期日所在的星期 | @@ -45,8 +43,6 @@ under the License. |5 |星期一 |0-53 |这一年中的第一个星期一所在的星期 | |6 |星期日 |1-53 |这一年的日期所占的天数大于等于4天的第一个星期| |7 |星期一 |1-53 |这一年中的第一个星期一所在的星期 | -+------------------------------------------------------------------------------+ -``` 参数为Date或者Datetime类型 diff --git a/docs/zh-CN/sql-reference/sql-functions/date-time-functions/yearweek.md b/docs/zh-CN/sql-reference/sql-functions/date-time-functions/yearweek.md index 12050b9e6a0334..6878b9aee055b0 100644 --- a/docs/zh-CN/sql-reference/sql-functions/date-time-functions/yearweek.md +++ b/docs/zh-CN/sql-reference/sql-functions/date-time-functions/yearweek.md @@ -35,10 +35,8 @@ under the License. 当日期所在的星期属于上一年时,返回的是上一年的年份和星期数; 当日期所在的星期属于下一年时,返回的是下一年的年份,星期数为1。 参数mode的作用参见下面的表格: -``` -+-------------------------------------------------------------------------------+ |Mode |星期的第一天 |星期数的范围 |第一个星期的定义 | -+-------------------------------------------------------------------------------+ +|:----|:------------|:------------|:--------------------------------------------| |0 |星期日 |1-53 |这一年中的第一个星期日所在的星期 | |1 |星期一 |1-53 |这一年的日期所占的天数大于等于4天的第一个星期| |2 |星期日 |1-53 |这一年中的第一个星期日所在的星期 | @@ -47,8 +45,6 @@ under the License. |5 |星期一 |1-53 |这一年中的第一个星期一所在的星期 | |6 |星期日 |1-53 |这一年的日期所占的天数大于等于4天的第一个星期| |7 |星期一 |1-53 |这一年中的第一个星期一所在的星期 | -+-------------------------------------------------------------------------------+ -``` 参数为Date或者Datetime类型