Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions be/src/exprs/timestamp_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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<DAY>(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();
Expand Down
13 changes: 13 additions & 0 deletions be/src/exprs/timestamp_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 &para);
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,
Expand All @@ -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,
Expand Down
19 changes: 19 additions & 0 deletions be/src/runtime/datetime_value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 2 additions & 0 deletions be/src/runtime/datetime_value.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
95 changes: 95 additions & 0 deletions be/test/exprs/timestamp_functions_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions docs/.vuepress/sidebar/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ module.exports = [
"from_days",
"from_unixtime",
"hour",
"makedate",
"minute",
"month",
"monthname",
Expand All @@ -264,8 +265,10 @@ module.exports = [
"to_days",
"unix_timestamp",
"utc_timestamp",
"week",
"weekofyear",
"year",
"yearweek",
],
},
{
Expand Down
3 changes: 3 additions & 0 deletions docs/.vuepress/sidebar/zh-CN.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ module.exports = [
"from_days",
"from_unixtime",
"hour",
"makedate",
"minute",
"month",
"monthname",
Expand All @@ -269,8 +270,10 @@ module.exports = [
"to_days",
"unix_timestamp",
"utc_timestamp",
"week",
"weekofyear",
"year",
"yearweek",
],
},
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
{
"title": "makedate",
"language": "en"
}
---

<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->

# 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
67 changes: 67 additions & 0 deletions docs/en/sql-reference/sql-functions/date-time-functions/week.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
{
"title": "week",
"language": "en"
}
---

<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->

# 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
Loading