You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by mo...@apache.org on 2020/10/09 08:06:00 UTC
[incubator-doris] branch master updated: [Feature] Add time_round
builtin functions (#4640)
This is an automated email from the ASF dual-hosted git repository.
morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-doris.git
The following commit(s) were added to refs/heads/master by this push:
new f3cdf16 [Feature] Add time_round builtin functions (#4640)
f3cdf16 is described below
commit f3cdf167d12d4fd0a466e6a9f2f8b22cf97afe07
Author: ccoffline <45...@users.noreply.github.com>
AuthorDate: Fri Oct 9 16:05:51 2020 +0800
[Feature] Add time_round builtin functions (#4640)
#4619
Add time_round functions that provides `time_floor` & `time_ceil` at each time unit.
Fix two related bugs.
- #4618
- Fix `struct TimeInterval` to use `int64_t` instead of `int32_t`, in case when the second diff overflow
---
be/src/exprs/timestamp_functions.cpp | 129 ++++++++++++++-
be/src/exprs/timestamp_functions.h | 174 +++++++++++++++++++++
be/src/runtime/datetime_value.h | 16 +-
be/test/exprs/timestamp_functions_test.cpp | 117 +++++++++-----
docs/.vuepress/sidebar/en.js | 1 +
docs/.vuepress/sidebar/zh-CN.js | 1 +
.../date-time-functions/time_round.md | 86 ++++++++++
.../date-time-functions/time_round.md | 86 ++++++++++
gensrc/script/doris_builtins_functions.py | 113 +++++++++++++
9 files changed, 669 insertions(+), 54 deletions(-)
diff --git a/be/src/exprs/timestamp_functions.cpp b/be/src/exprs/timestamp_functions.cpp
index ea12b52..79faee0 100644
--- a/be/src/exprs/timestamp_functions.cpp
+++ b/be/src/exprs/timestamp_functions.cpp
@@ -398,36 +398,36 @@ BigIntVal TimestampFunctions::timestamp_diff(FunctionContext* ctx, const DateTim
switch (unit) {
case YEAR: {
int year = (ts_value2.year() - ts_value1.year());
- if (year >= 0) {
+ if (year > 0) {
year -= (ts_value2.to_int64() % 10000000000 - ts_value1.to_int64() % 10000000000) < 0;
- } else {
+ } else if (year < 0) {
year += (ts_value2.to_int64() % 10000000000 - ts_value1.to_int64() % 10000000000) > 0;
}
return year;
}
case MONTH: {
int month = (ts_value2.year() - ts_value1.year()) * 12 + (ts_value2.month() - ts_value1.month());
- if (month >= 0) {
+ if (month > 0) {
month -= (ts_value2.to_int64() % 100000000 - ts_value1.to_int64() % 100000000) < 0;
- } else {
+ } else if (month < 0) {
month += (ts_value2.to_int64() % 100000000 - ts_value1.to_int64() % 100000000) > 0;
}
return month;
}
case WEEK: {
int day = ts_value2.daynr() - ts_value1.daynr();
- if (day >= 0) {
+ if (day > 0) {
day -= ts_value2.time_part_diff(ts_value1) < 0;
- } else {
+ } else if (day < 0) {
day += ts_value2.time_part_diff(ts_value1) > 0;
}
return day / 7;
}
case DAY: {
int day = ts_value2.daynr() - ts_value1.daynr();
- if (day >= 0) {
+ if (day > 0) {
day -= ts_value2.time_part_diff(ts_value1) < 0;
- } else {
+ } else if (day < 0) {
day += ts_value2.time_part_diff(ts_value1) > 0;
}
return day;
@@ -496,6 +496,119 @@ void TimestampFunctions::format_close(
}
}
+DateTimeVal from_olap_datetime(uint64_t datetime) {
+ DateTimeValue ts_value;
+ if (!ts_value.from_olap_datetime(datetime)) {
+ return DateTimeVal::null();
+ }
+
+ DateTimeVal ts_val;
+ ts_value.to_datetime_val(&ts_val);
+ return ts_val;
+}
+
+#define _TR_4(TYPE, type, UNIT, unit) \
+ DateTimeVal TimestampFunctions::unit##_##type( \
+ FunctionContext* ctx, const DateTimeVal& ts_val, \
+ const IntVal& period, const DateTimeVal& origin) { \
+ return time_round<UNIT, TYPE>(ctx, ts_val, period, origin); \
+ } \
+ DateTimeVal TimestampFunctions::unit##_##type( \
+ FunctionContext* ctx, const DateTimeVal& ts_val, const DateTimeVal& origin) { \
+ return time_round<UNIT, TYPE>(ctx, ts_val, IntVal(1), origin); \
+ }
+
+#define _TR_5(TYPE, type, UNIT, unit, ORIGIN) \
+ DateTimeVal TimestampFunctions::unit##_##type( \
+ FunctionContext* ctx, const DateTimeVal& ts_val) { \
+ return time_round<UNIT, TYPE>(ctx, ts_val, IntVal(1), ORIGIN); \
+ } \
+ DateTimeVal TimestampFunctions::unit##_##type( \
+ FunctionContext* ctx, const DateTimeVal& ts_val, const IntVal& period) { \
+ return time_round<UNIT, TYPE>(ctx, ts_val, period, ORIGIN); \
+ }
+
+#define FLOOR 0
+#define CEIL 1
+
+static const DateTimeVal FIRST_DAY = from_olap_datetime(19700101000000);
+static const DateTimeVal FIRST_SUNDAY = from_olap_datetime(19700104000000);
+
+#define TIME_ROUND(UNIT, unit, ORIGIN) \
+ _TR_4(FLOOR, floor, UNIT, unit) _TR_4(CEIL, ceil, UNIT, unit) \
+ _TR_5(FLOOR, floor, UNIT, unit, ORIGIN) _TR_5(CEIL, ceil, UNIT, unit, ORIGIN)
+
+TIME_ROUND(YEAR, year, FIRST_DAY)
+TIME_ROUND(MONTH, month, FIRST_DAY)
+TIME_ROUND(WEEK, week, FIRST_SUNDAY)
+TIME_ROUND(DAY, day, FIRST_DAY)
+TIME_ROUND(HOUR, hour, FIRST_DAY)
+TIME_ROUND(MINUTE, minute, FIRST_DAY)
+TIME_ROUND(SECOND, second, FIRST_DAY)
+
+template <TimeUnit unit, bool type>
+DateTimeVal TimestampFunctions::time_round(
+ FunctionContext* ctx, const DateTimeVal& ts_val,
+ const IntVal& period, const DateTimeVal& origin) {
+ if (ts_val.is_null || period.is_null || period.val < 1 || origin.is_null) {
+ return DateTimeVal::null();
+ }
+
+ DateTimeValue ts1 = DateTimeValue::from_datetime_val(origin);
+ DateTimeValue ts2 = DateTimeValue::from_datetime_val(ts_val);
+ int64_t diff;
+ switch (unit) {
+ case YEAR: {
+ int year = (ts2.year() - ts1.year());
+ diff = year - (ts2.to_int64() % 10000000000 < ts1.to_int64() % 10000000000);
+ break;
+ }
+ case MONTH: {
+ int month = (ts2.year() - ts1.year()) * 12 + (ts2.month() - ts1.month());
+ diff = month - (ts2.to_int64() % 100000000 < ts1.to_int64() % 100000000);
+ break;
+ }
+ case WEEK: {
+ int week = ts2.daynr() / 7 - ts1.daynr() / 7;
+ diff = week - (ts2.daynr() % 7 < ts1.daynr() % 7 + (ts2.time_part_diff(ts1) < 0));
+ break;
+ }
+ case DAY: {
+ int day = ts2.daynr() - ts1.daynr();
+ diff = day - (ts2.time_part_diff(ts1) < 0);
+ break;
+ }
+ case HOUR: {
+ int hour = (ts2.daynr() - ts1.daynr()) * 24 + (ts2.hour() - ts1.hour());
+ diff = hour - ((ts2.minute() * 60 + ts2.second()) < (ts1.minute() * 60 - ts1.second()));
+ break;
+ }
+ case MINUTE: {
+ int minute = (ts2.daynr() - ts1.daynr()) * 24 * 60 +
+ (ts2.hour() - ts1.hour()) * 60 + (ts2.minute() - ts1.minute());
+ diff = minute - (ts2.second() < ts1.second());
+ break;
+ }
+ case SECOND: {
+ diff = ts2.second_diff(ts1);
+ break;
+ }
+ default:
+ return DateTimeVal::null();
+ }
+ int64_t count = period.val;
+ int64_t step = diff - (diff % count + count) % count + (type == FLOOR ? 0 : count);
+ bool is_neg = step < 0;
+
+ TimeInterval interval(unit, is_neg ? -step : step, is_neg);
+ if (!ts1.date_add_interval(interval, unit)) {
+ return DateTimeVal::null();
+ }
+ DateTimeVal new_ts_val;
+ ts1.to_datetime_val(&new_ts_val);
+ return new_ts_val;
+}
+
StringVal TimestampFunctions::date_format(
FunctionContext* ctx, const DateTimeVal& ts_val, const StringVal& format) {
if (ts_val.is_null || format.is_null) {
diff --git a/be/src/exprs/timestamp_functions.h b/be/src/exprs/timestamp_functions.h
index 502436b..5aeafee 100644
--- a/be/src/exprs/timestamp_functions.h
+++ b/be/src/exprs/timestamp_functions.h
@@ -166,6 +166,180 @@ public:
static doris_udf::BigIntVal seconds_diff(
doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val1, const doris_udf::DateTimeVal& ts_val2);
+ // Period functions.
+ template <TimeUnit unit, bool type>
+ static doris_udf::DateTimeVal time_round(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period, const doris_udf::DateTimeVal& origin);
+
+ static doris_udf::DateTimeVal year_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val);
+ static doris_udf::DateTimeVal year_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period);
+ static doris_udf::DateTimeVal year_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::DateTimeVal& origin);
+ static doris_udf::DateTimeVal year_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period, const doris_udf::DateTimeVal& origin);
+
+ static doris_udf::DateTimeVal year_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val);
+ static doris_udf::DateTimeVal year_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period);
+ static doris_udf::DateTimeVal year_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::DateTimeVal& origin);
+ static doris_udf::DateTimeVal year_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period, const doris_udf::DateTimeVal& origin);
+
+ static doris_udf::DateTimeVal month_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val);
+ static doris_udf::DateTimeVal month_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period);
+ static doris_udf::DateTimeVal month_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::DateTimeVal& origin);
+ static doris_udf::DateTimeVal month_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period, const doris_udf::DateTimeVal& origin);
+
+ static doris_udf::DateTimeVal month_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val);
+ static doris_udf::DateTimeVal month_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period);
+ static doris_udf::DateTimeVal month_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::DateTimeVal& origin);
+ static doris_udf::DateTimeVal month_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period, const doris_udf::DateTimeVal& origin);
+
+ static doris_udf::DateTimeVal week_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val);
+ static doris_udf::DateTimeVal week_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period);
+ static doris_udf::DateTimeVal week_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::DateTimeVal& origin);
+ static doris_udf::DateTimeVal week_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period, const doris_udf::DateTimeVal& origin);
+
+ static doris_udf::DateTimeVal week_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val);
+ static doris_udf::DateTimeVal week_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period);
+ static doris_udf::DateTimeVal week_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::DateTimeVal& origin);
+ static doris_udf::DateTimeVal week_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period, const doris_udf::DateTimeVal& origin);
+
+ static doris_udf::DateTimeVal day_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val);
+ static doris_udf::DateTimeVal day_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period);
+ static doris_udf::DateTimeVal day_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::DateTimeVal& origin);
+ static doris_udf::DateTimeVal day_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period, const doris_udf::DateTimeVal& origin);
+
+ static doris_udf::DateTimeVal day_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val);
+ static doris_udf::DateTimeVal day_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period);
+ static doris_udf::DateTimeVal day_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::DateTimeVal& origin);
+ static doris_udf::DateTimeVal day_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period, const doris_udf::DateTimeVal& origin);
+
+ static doris_udf::DateTimeVal hour_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val);
+ static doris_udf::DateTimeVal hour_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period);
+ static doris_udf::DateTimeVal hour_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::DateTimeVal& origin);
+ static doris_udf::DateTimeVal hour_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period, const doris_udf::DateTimeVal& origin);
+
+ static doris_udf::DateTimeVal hour_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val);
+ static doris_udf::DateTimeVal hour_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period);
+ static doris_udf::DateTimeVal hour_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::DateTimeVal& origin);
+ static doris_udf::DateTimeVal hour_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period, const doris_udf::DateTimeVal& origin);
+
+ static doris_udf::DateTimeVal minute_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val);
+ static doris_udf::DateTimeVal minute_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period);
+ static doris_udf::DateTimeVal minute_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::DateTimeVal& origin);
+ static doris_udf::DateTimeVal minute_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period, const doris_udf::DateTimeVal& origin);
+
+ static doris_udf::DateTimeVal minute_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val);
+ static doris_udf::DateTimeVal minute_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period);
+ static doris_udf::DateTimeVal minute_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::DateTimeVal& origin);
+ static doris_udf::DateTimeVal minute_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period, const doris_udf::DateTimeVal& origin);
+
+ static doris_udf::DateTimeVal second_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val);
+ static doris_udf::DateTimeVal second_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period);
+ static doris_udf::DateTimeVal second_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::DateTimeVal& origin);
+ static doris_udf::DateTimeVal second_floor(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period, const doris_udf::DateTimeVal& origin);
+
+ static doris_udf::DateTimeVal second_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val);
+ static doris_udf::DateTimeVal second_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period);
+ static doris_udf::DateTimeVal second_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::DateTimeVal& origin);
+ static doris_udf::DateTimeVal second_ceil(
+ doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& ts_val,
+ const doris_udf::IntVal& period, const doris_udf::DateTimeVal& origin);
+
// TimeZone correlation functions.
static doris_udf::DateTimeVal timestamp(
doris_udf::FunctionContext* ctx, const doris_udf::DateTimeVal& val);
diff --git a/be/src/runtime/datetime_value.h b/be/src/runtime/datetime_value.h
index 3310eca..9471ee0 100644
--- a/be/src/runtime/datetime_value.h
+++ b/be/src/runtime/datetime_value.h
@@ -57,13 +57,13 @@ enum TimeUnit {
};
struct TimeInterval {
- int32_t year;
- int32_t month;
- int32_t day;
- int32_t hour;
- int32_t minute;
- int32_t second;
- int32_t microsecond;
+ int64_t year;
+ int64_t month;
+ int64_t day;
+ int64_t hour;
+ int64_t minute;
+ int64_t second;
+ int64_t microsecond;
bool is_neg;
TimeInterval() :
@@ -71,7 +71,7 @@ struct TimeInterval {
hour(0), minute(0), second(0), microsecond(0), is_neg(false) {
}
- TimeInterval(TimeUnit unit, int count, bool is_neg_param) :
+ TimeInterval(TimeUnit unit, int64_t count, bool is_neg_param) :
year(0), month(0), day(0),
hour(0), minute(0), second(0), microsecond(0), is_neg(is_neg_param) {
switch (unit) {
diff --git a/be/test/exprs/timestamp_functions_test.cpp b/be/test/exprs/timestamp_functions_test.cpp
index cc343ac..09e7637 100644
--- a/be/test/exprs/timestamp_functions_test.cpp
+++ b/be/test/exprs/timestamp_functions_test.cpp
@@ -31,6 +31,13 @@
namespace doris {
class FunctionContextImpl;
+doris_udf::DateTimeVal datetime_val(int64_t value) {
+ DateTimeValue dt(value);
+ doris_udf::DateTimeVal tv;
+ dt.to_datetime_val(&tv);
+ return tv;
+}
+
class TimestampFunctionsTest : public testing::Test {
public:
TimestampFunctionsTest() { }
@@ -136,55 +143,89 @@ TEST_F(TimestampFunctionsTest, convert_tz_test) {
delete context;
}
+#define ASSERT_DIFF(unit, diff, tv1, tv2) \
+ ASSERT_EQ(diff, TimestampFunctions::unit##s_diff(context, datetime_val(tv1), datetime_val(tv2)).val); \
+ ASSERT_EQ(-(diff), TimestampFunctions::unit##s_diff(context, datetime_val(tv2), datetime_val(tv1)).val);
TEST_F(TimestampFunctionsTest, timestampdiff_test) {
doris_udf::FunctionContext *context = new doris_udf::FunctionContext();
- DateTimeValue dt1(20120824000001);
- doris_udf::DateTimeVal tv1;
- dt1.to_datetime_val(&tv1);
- DateTimeValue dt2(20120830000000);
- doris_udf::DateTimeVal tv2;
- dt2.to_datetime_val(&tv2);
+ int64_t tv1 = 20120824000001;
+ int64_t tv2 = 20120830000000;
+
+ //YEAR
+ ASSERT_DIFF(year, 0, tv2, tv1);
+ ASSERT_DIFF(year, 1, tv1, 20100930000000);
+ //MONTH
+ ASSERT_DIFF(month, 0, tv2, tv1);
+ ASSERT_DIFF(month, 0, tv2, tv1);
+ ASSERT_DIFF(month, 0, 20120924000000, tv1);
+ ASSERT_DIFF(month, 1, tv1, 20120631000000);
+ //WEEK
+ ASSERT_DIFF(week, 0, tv2, tv1);
+ //DAY
+ ASSERT_DIFF(day, 5, tv2, tv1);
+ ASSERT_DIFF(day, 6, 20120830000001, tv1);
+ ASSERT_DIFF(day, 8, 20120901000001, tv1);
+ ASSERT_DIFF(day, 0, 20120823000005, tv1);
+ ASSERT_DIFF(day, 0, 20120824000001, tv1);
+
+ //HOUR
+ ASSERT_DIFF(hour, 143, tv2, tv1);
+ //MINUTE
+ ASSERT_DIFF(minute, 8639, tv2, tv1);
+ //SECOND
+ ASSERT_DIFF(second, 518399, tv2, tv1);
+
+ delete context;
+}
+
+#define ASSERT_ROUND(unit, floor, ceil, ...) \
+ ASSERT_EQ(datetime_val(floor).packed_time, TimestampFunctions::unit##_floor(context, __VA_ARGS__).packed_time); \
+ ASSERT_EQ(datetime_val(ceil).packed_time, TimestampFunctions::unit##_ceil(context, __VA_ARGS__).packed_time);
+TEST_F(TimestampFunctionsTest, time_round_test) {
+ doris_udf::FunctionContext *context = new doris_udf::FunctionContext();
+ doris_udf::DateTimeVal tv = datetime_val(20120824132901);
+ doris_udf::IntVal three(3);
+ doris_udf::DateTimeVal wednesday = datetime_val(20200916000000);
//YEAR
- ASSERT_EQ(0, TimestampFunctions::years_diff(context, tv2, tv1).val);
- DateTimeValue dt_year(20100930000000);
- doris_udf::DateTimeVal tv_year;
- dt_year.to_datetime_val(&tv_year);
- ASSERT_EQ(-1, TimestampFunctions::years_diff(context, tv_year, tv1).val);
+ ASSERT_ROUND(year, 20120101000000, 20130101000000, tv);
+ ASSERT_ROUND(year, 20110916000000, 20120916000000, tv, wednesday);
+ ASSERT_ROUND(year, 20110916000000, 20140916000000, tv, three, wednesday);
+
//MONTH
- ASSERT_EQ(0, TimestampFunctions::months_diff(context, tv2, tv1).val);
- DateTimeValue dt3(20120924000000);
- doris_udf::DateTimeVal tv3;
- dt3.to_datetime_val(&tv3);
- ASSERT_EQ(0, TimestampFunctions::months_diff(context, tv3, tv1).val);
- DateTimeValue dt_month(20120631000000);
- doris_udf::DateTimeVal tv_month;
- dt_month.to_datetime_val(&tv_month);
- ASSERT_EQ(-1, TimestampFunctions::months_diff(context, tv_month, tv1).val);
+ ASSERT_ROUND(month, 20120801000000, 20120901000000, tv);
+ ASSERT_ROUND(month, 20120701000000, 20121001000000, tv, three);
+
//WEEK
- ASSERT_EQ(0, TimestampFunctions::weeks_diff(context, tv2, tv1).val);
+ ASSERT_ROUND(week, 20120819000000, 20120826000000, tv);
+ ASSERT_ROUND(week, 20120822000000, 20120829000000, tv, wednesday);
+ ASSERT_ROUND(week, 20120808000000, 20120829000000, tv, three, wednesday);
+
+ doris_udf::DateTimeVal tv1 = datetime_val(20200202130920);
+ doris_udf::DateTimeVal monday = datetime_val(20200106000000);
+ ASSERT_ROUND(week, 20200202000000, 20200209000000, tv1);
+ ASSERT_ROUND(week, 20200127000000, 20200203000000, tv1, monday);
+
//DAY
- ASSERT_EQ(5, TimestampFunctions::days_diff(context, tv2, tv1).val);
- DateTimeValue dt4(20120830000001);
- doris_udf::DateTimeVal tv4;
- dt4.to_datetime_val(&tv4);
- ASSERT_EQ(6, TimestampFunctions::days_diff(context, tv4, tv1).val);
- DateTimeValue dt5(20120901000001);
- doris_udf::DateTimeVal tv5;
- dt5.to_datetime_val(&tv5);
- ASSERT_EQ(8, TimestampFunctions::days_diff(context, tv5, tv1).val);
-
- DateTimeValue dt_day(20120823000005);
- doris_udf::DateTimeVal tv_day;
- dt_day.to_datetime_val(&tv_day);
- ASSERT_EQ(0, TimestampFunctions::days_diff(context, tv_day, tv1).val);
+ doris_udf::DateTimeVal noon = datetime_val(19700101120000);
+ ASSERT_ROUND(day, 20120824000000, 20120825000000, tv);
+ ASSERT_ROUND(day, 20120824120000, 20120825120000, tv, noon);
//HOUR
- ASSERT_EQ(143, TimestampFunctions::hours_diff(context, tv2, tv1).val);
+ doris_udf::DateTimeVal random = datetime_val(29380329113953);
+ ASSERT_ROUND(hour, 20120824120000, 20120824150000, tv, three);
+ ASSERT_ROUND(hour, 20120824113953, 20120824143953, tv, three, random);
+
//MINUTE
- ASSERT_EQ(8639, TimestampFunctions::minutes_diff(context, tv2, tv1).val);
+ doris_udf::IntVal val90(90);
+ ASSERT_ROUND(minute, 20120824132900, 20120824133000, tv);
+ ASSERT_ROUND(minute, 20120824120000, 20120824133000, tv, val90);
+ ASSERT_ROUND(minute, 20120824130953, 20120824143953, tv, val90, random);
+
//SECOND
- ASSERT_EQ(518399, TimestampFunctions::seconds_diff(context, tv2, tv1).val);
+ ASSERT_ROUND(second, 20120824132900, 20120824132903, tv, three);
+ ASSERT_ROUND(second, 20120824132830, 20120824133000, tv, val90);
+
delete context;
}
diff --git a/docs/.vuepress/sidebar/en.js b/docs/.vuepress/sidebar/en.js
index 0d07657..c51ce50 100644
--- a/docs/.vuepress/sidebar/en.js
+++ b/docs/.vuepress/sidebar/en.js
@@ -241,6 +241,7 @@ module.exports = [
"now",
"second",
"str_to_date",
+ "time_round",
"timediff",
"timestampadd",
"timestampdiff",
diff --git a/docs/.vuepress/sidebar/zh-CN.js b/docs/.vuepress/sidebar/zh-CN.js
index 2d694e7..76038b2 100644
--- a/docs/.vuepress/sidebar/zh-CN.js
+++ b/docs/.vuepress/sidebar/zh-CN.js
@@ -248,6 +248,7 @@ module.exports = [
"now",
"second",
"str_to_date",
+ "time_round",
"timediff",
"timestampadd",
"timestampdiff",
diff --git a/docs/en/sql-reference/sql-functions/date-time-functions/time_round.md b/docs/en/sql-reference/sql-functions/date-time-functions/time_round.md
new file mode 100644
index 0000000..9fb70f8
--- /dev/null
+++ b/docs/en/sql-reference/sql-functions/date-time-functions/time_round.md
@@ -0,0 +1,86 @@
+---
+{
+ "title": "time_round",
+ "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.
+-->
+
+# time_round
+## description
+### Syntax
+
+`DATETIME TIME_ROUND(DATETIME expr)`
+
+`DATETIME TIME_ROUND(DATETIME expr, INT period)`
+
+`DATETIME TIME_ROUND(DATETIME expr, DATETIME origin)`
+
+`DATETIME TIME_ROUND(DATETIME expr, INT period, DATETIME origin)`
+
+The function name `TIME_ROUND` consists of two parts,Each part consists of the following optional values.
+- `TIME`: `SECOND`, `MINUTE`, `HOUR`, `DAY`, `WEEK`, `MONTH`, `YEAR`
+- `ROUND`: `FLOOR`, `CEIL`
+
+Returns the upper/lower bound of `expr`.
+
+- `period` specifies how many `TIME` units, the default is `1`.
+- `origin` specifies the start time of the period, the default is `1970-01-01T00:00:00`, the start time of `WEEK` is Sunday, which is `1970-01-04T00:00:00`. Could be larger than `expr`.
+- Please try to choose common `period`, such as 3 `MONTH`, 90 `MINUTE`. If you set a uncommon `period`, please also specify `origin`.
+
+## example
+
+```
+
+MySQL> SELECT YEAR_FLOOR('20200202000000');
++------------------------------+
+| year_floor('20200202000000') |
++------------------------------+
+| 2020-01-01 00:00:00 |
++------------------------------+
+
+
+MySQL> SELECT MONTH_CEIL(CAST('2020-02-02 13:09:20' AS DATETIME), 3); --quarter
++--------------------------------------------------------+
+| month_ceil(CAST('2020-02-02 13:09:20' AS DATETIME), 3) |
++--------------------------------------------------------+
+| 2020-04-01 00:00:00 |
++--------------------------------------------------------+
+
+
+MySQL> SELECT WEEK_CEIL('2020-02-02 13:09:20', '2020-01-06'); --monday
++---------------------------------------------------------+
+| week_ceil('2020-02-02 13:09:20', '2020-01-06 00:00:00') |
++---------------------------------------------------------+
+| 2020-02-03 00:00:00 |
++---------------------------------------------------------+
+
+
+MySQL> SELECT MONTH_CEIL(CAST('2020-02-02 13:09:20' AS DATETIME), 3, CAST('1970-01-09 00:00:00' AS DATETIME)); --next rent day
++-------------------------------------------------------------------------------------------------+
+| month_ceil(CAST('2020-02-02 13:09:20' AS DATETIME), 3, CAST('1970-01-09 00:00:00' AS DATETIME)) |
++-------------------------------------------------------------------------------------------------+
+| 2020-04-09 00:00:00 |
++-------------------------------------------------------------------------------------------------+
+
+```
+## keyword
+TIME_ROUND
diff --git a/docs/zh-CN/sql-reference/sql-functions/date-time-functions/time_round.md b/docs/zh-CN/sql-reference/sql-functions/date-time-functions/time_round.md
new file mode 100644
index 0000000..2e8d142
--- /dev/null
+++ b/docs/zh-CN/sql-reference/sql-functions/date-time-functions/time_round.md
@@ -0,0 +1,86 @@
+---
+{
+ "title": "time_round",
+ "language": "zh-CN"
+}
+---
+
+<!--
+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.
+-->
+
+# time_round
+## description
+### Syntax
+
+`DATETIME TIME_ROUND(DATETIME expr)`
+
+`DATETIME TIME_ROUND(DATETIME expr, INT period)`
+
+`DATETIME TIME_ROUND(DATETIME expr, DATETIME origin)`
+
+`DATETIME TIME_ROUND(DATETIME expr, INT period, DATETIME origin)`
+
+函数名 `TIME_ROUND` 由两部分组成,每部分由以下可选值组成
+- `TIME`: `SECOND`, `MINUTE`, `HOUR`, `DAY`, `WEEK`, `MONTH`, `YEAR`
+- `ROUND`: `FLOOR`, `CEIL`
+
+返回 `expr` 的上/下界。
+
+- `period` 指定每个周期有多少个 `TIME` 单位组成,默认为 `1`。
+- `origin` 指定周期的开始时间,默认为 `1970-01-01T00:00:00`,`WEEK` 的默认开始时间为 `1970-01-04T00:00:00`,即周日。可以比 `expr` 大。
+- 请尽量选择常见 `period`,如 3 `MONTH`,90 `MINUTE` 等,如设置了非常用 `period`,请同时指定 `origin`。
+
+## example
+
+```
+
+MySQL> SELECT YEAR_FLOOR('20200202000000');
++------------------------------+
+| year_floor('20200202000000') |
++------------------------------+
+| 2020-01-01 00:00:00 |
++------------------------------+
+
+
+MySQL> SELECT MONTH_CEIL(CAST('2020-02-02 13:09:20' AS DATETIME), 3); --quarter
++--------------------------------------------------------+
+| month_ceil(CAST('2020-02-02 13:09:20' AS DATETIME), 3) |
++--------------------------------------------------------+
+| 2020-04-01 00:00:00 |
++--------------------------------------------------------+
+
+
+MySQL> SELECT WEEK_CEIL('2020-02-02 13:09:20', '2020-01-06'); --monday
++---------------------------------------------------------+
+| week_ceil('2020-02-02 13:09:20', '2020-01-06 00:00:00') |
++---------------------------------------------------------+
+| 2020-02-03 00:00:00 |
++---------------------------------------------------------+
+
+
+MySQL> SELECT MONTH_CEIL(CAST('2020-02-02 13:09:20' AS DATETIME), 3, CAST('1970-01-09 00:00:00' AS DATETIME)); --next rent day
++-------------------------------------------------------------------------------------------------+
+| month_ceil(CAST('2020-02-02 13:09:20' AS DATETIME), 3, CAST('1970-01-09 00:00:00' AS DATETIME)) |
++-------------------------------------------------------------------------------------------------+
+| 2020-04-09 00:00:00 |
++-------------------------------------------------------------------------------------------------+
+
+```
+## keyword
+TIME_ROUND
diff --git a/gensrc/script/doris_builtins_functions.py b/gensrc/script/doris_builtins_functions.py
index bd44884..c281cfe 100755
--- a/gensrc/script/doris_builtins_functions.py
+++ b/gensrc/script/doris_builtins_functions.py
@@ -260,6 +260,119 @@ visible_functions = [
[['seconds_diff'], 'BIGINT', ['DATETIME', 'DATETIME'],
'_ZN5doris18TimestampFunctions12seconds_diffEPN9doris_udf15FunctionContextERKNS1_11DateTimeValES6_'],
+ [['year_floor'], 'DATETIME', ['DATETIME'],
+ '_ZN5doris18TimestampFunctions10year_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValE'],
+ [['year_floor'], 'DATETIME', ['DATETIME', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions10year_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValES6_'],
+ [['year_floor'], 'DATETIME', ['DATETIME', 'INT'],
+ '_ZN5doris18TimestampFunctions10year_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValE'],
+ [['year_floor'], 'DATETIME', ['DATETIME', 'INT', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions10year_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValES6_'],
+ [['year_ceil'], 'DATETIME', ['DATETIME'],
+ '_ZN5doris18TimestampFunctions9year_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValE'],
+ [['year_ceil'], 'DATETIME', ['DATETIME', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions9year_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValES6_'],
+ [['year_ceil'], 'DATETIME', ['DATETIME', 'INT'],
+ '_ZN5doris18TimestampFunctions9year_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValE'],
+ [['year_ceil'], 'DATETIME', ['DATETIME', 'INT', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions9year_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValES6_'],
+ [['month_floor'], 'DATETIME', ['DATETIME'],
+ '_ZN5doris18TimestampFunctions11month_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValE'],
+ [['month_floor'], 'DATETIME', ['DATETIME', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions11month_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValES6_'],
+ [['month_floor'], 'DATETIME', ['DATETIME', 'INT'],
+ '_ZN5doris18TimestampFunctions11month_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValE'],
+ [['month_floor'], 'DATETIME', ['DATETIME', 'INT', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions11month_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValES6_'],
+ [['month_ceil'], 'DATETIME', ['DATETIME'],
+ '_ZN5doris18TimestampFunctions10month_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValE'],
+ [['month_ceil'], 'DATETIME', ['DATETIME', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions10month_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValES6_'],
+ [['month_ceil'], 'DATETIME', ['DATETIME', 'INT'],
+ '_ZN5doris18TimestampFunctions10month_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValE'],
+ [['month_ceil'], 'DATETIME', ['DATETIME', 'INT', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions10month_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValES6_'],
+ [['week_floor'], 'DATETIME', ['DATETIME'],
+ '_ZN5doris18TimestampFunctions10week_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValE'],
+ [['week_floor'], 'DATETIME', ['DATETIME', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions10week_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValES6_'],
+ [['week_floor'], 'DATETIME', ['DATETIME', 'INT'],
+ '_ZN5doris18TimestampFunctions10week_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValE'],
+ [['week_floor'], 'DATETIME', ['DATETIME', 'INT', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions10week_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValES6_'],
+ [['week_ceil'], 'DATETIME', ['DATETIME'],
+ '_ZN5doris18TimestampFunctions9week_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValE'],
+ [['week_ceil'], 'DATETIME', ['DATETIME', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions9week_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValES6_'],
+ [['week_ceil'], 'DATETIME', ['DATETIME', 'INT'],
+ '_ZN5doris18TimestampFunctions9week_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValE'],
+ [['week_ceil'], 'DATETIME', ['DATETIME', 'INT', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions9week_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValES6_'],
+ [['day_floor'], 'DATETIME', ['DATETIME'],
+ '_ZN5doris18TimestampFunctions9day_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValE'],
+ [['day_floor'], 'DATETIME', ['DATETIME', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions9day_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValES6_'],
+ [['day_floor'], 'DATETIME', ['DATETIME', 'INT'],
+ '_ZN5doris18TimestampFunctions9day_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValE'],
+ [['day_floor'], 'DATETIME', ['DATETIME', 'INT', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions9day_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValES6_'],
+ [['day_ceil'], 'DATETIME', ['DATETIME'],
+ '_ZN5doris18TimestampFunctions8day_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValE'],
+ [['day_ceil'], 'DATETIME', ['DATETIME', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions8day_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValES6_'],
+ [['day_ceil'], 'DATETIME', ['DATETIME', 'INT'],
+ '_ZN5doris18TimestampFunctions8day_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValE'],
+ [['day_ceil'], 'DATETIME', ['DATETIME', 'INT', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions8day_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValES6_'],
+ [['hour_floor'], 'DATETIME', ['DATETIME'],
+ '_ZN5doris18TimestampFunctions10hour_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValE'],
+ [['hour_floor'], 'DATETIME', ['DATETIME', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions10hour_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValES6_'],
+ [['hour_floor'], 'DATETIME', ['DATETIME', 'INT'],
+ '_ZN5doris18TimestampFunctions10hour_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValE'],
+ [['hour_floor'], 'DATETIME', ['DATETIME', 'INT', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions10hour_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValES6_'],
+ [['hour_ceil'], 'DATETIME', ['DATETIME'],
+ '_ZN5doris18TimestampFunctions9hour_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValE'],
+ [['hour_ceil'], 'DATETIME', ['DATETIME', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions9hour_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValES6_'],
+ [['hour_ceil'], 'DATETIME', ['DATETIME', 'INT'],
+ '_ZN5doris18TimestampFunctions9hour_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValE'],
+ [['hour_ceil'], 'DATETIME', ['DATETIME', 'INT', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions9hour_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValES6_'],
+ [['minute_floor'], 'DATETIME', ['DATETIME'],
+ '_ZN5doris18TimestampFunctions12minute_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValE'],
+ [['minute_floor'], 'DATETIME', ['DATETIME', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions12minute_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValES6_'],
+ [['minute_floor'], 'DATETIME', ['DATETIME', 'INT'],
+ '_ZN5doris18TimestampFunctions12minute_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValE'],
+ [['minute_floor'], 'DATETIME', ['DATETIME', 'INT', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions12minute_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValES6_'],
+ [['minute_ceil'], 'DATETIME', ['DATETIME'],
+ '_ZN5doris18TimestampFunctions11minute_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValE'],
+ [['minute_ceil'], 'DATETIME', ['DATETIME', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions11minute_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValES6_'],
+ [['minute_ceil'], 'DATETIME', ['DATETIME', 'INT'],
+ '_ZN5doris18TimestampFunctions11minute_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValE'],
+ [['minute_ceil'], 'DATETIME', ['DATETIME', 'INT', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions11minute_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValES6_'],
+ [['second_floor'], 'DATETIME', ['DATETIME'],
+ '_ZN5doris18TimestampFunctions12second_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValE'],
+ [['second_floor'], 'DATETIME', ['DATETIME', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions12second_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValES6_'],
+ [['second_floor'], 'DATETIME', ['DATETIME', 'INT'],
+ '_ZN5doris18TimestampFunctions12second_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValE'],
+ [['second_floor'], 'DATETIME', ['DATETIME', 'INT', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions12second_floorEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValES6_'],
+ [['second_ceil'], 'DATETIME', ['DATETIME'],
+ '_ZN5doris18TimestampFunctions11second_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValE'],
+ [['second_ceil'], 'DATETIME', ['DATETIME', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions11second_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValES6_'],
+ [['second_ceil'], 'DATETIME', ['DATETIME', 'INT'],
+ '_ZN5doris18TimestampFunctions11second_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValE'],
+ [['second_ceil'], 'DATETIME', ['DATETIME', 'INT', 'DATETIME'],
+ '_ZN5doris18TimestampFunctions11second_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValES6_'],
+
# Math builtin functions
[['pi'], 'DOUBLE', [],
'_ZN5doris13MathFunctions2piEPN9doris_udf15FunctionContextE'],
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org