Skip to content

Commit

Permalink
Support Time Function (apache#62)
Browse files Browse the repository at this point in the history
  • Loading branch information
HappenLee committed Jul 1, 2021
1 parent 6a41a16 commit 71be210
Show file tree
Hide file tree
Showing 18 changed files with 738 additions and 295 deletions.
31 changes: 27 additions & 4 deletions be/src/exprs/timestamp_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,29 @@ bool TimestampFunctions::check_format(const StringVal& format, DateTimeValue& t)
return false;
}

std::string TimestampFunctions::convert_format(const std::string& format) {
switch (format.size()) {
case 8:
if (strncmp(format.c_str(), "yyyyMMdd", 8) == 0) {
return std::string("%Y%m%d");
}
break;
case 10:
if (strncmp(format.c_str(), "yyyy-MM-dd", 10) == 0) {
return std::string("%Y-%m-%d");
}
break;
case 19:
if (strncmp(format.c_str(), "yyyy-MM-dd HH:mm:ss", 19) == 0) {
return std::string("%Y-%m-%d %H:%i:%s");
}
break;
default:
break;
}
return format;
}

StringVal TimestampFunctions::convert_format(FunctionContext* ctx, const StringVal& format) {
switch (format.len) {
case 8:
Expand Down Expand Up @@ -521,10 +544,10 @@ DateTimeVal from_olap_datetime(uint64_t datetime) {
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)
#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)
Expand Down
2 changes: 2 additions & 0 deletions be/src/exprs/timestamp_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,8 @@ class TimestampFunctions {
// Todo(kks): remove this method when 0.12 release
static StringVal convert_format(doris_udf::FunctionContext* ctx, const StringVal& format);

static std::string convert_format(const std::string& format);

// Issue a warning for a bad format string.
static void report_bad_format(const StringVal* format);

Expand Down
12 changes: 4 additions & 8 deletions be/src/runtime/datetime_value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,15 @@
#include "util/timezone_utils.h"

namespace doris {

const uint64_t log_10_int[] = {1, 10, 100, 1000,
10000UL, 100000UL, 1000000UL, 10000000UL,
100000000UL, 1000000000UL, 10000000000UL, 100000000000UL};

static int s_days_in_month[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static const char* s_month_name[] = {"", "January", "February", "March", "April",
"May", "June", "July", "August", "September",
"October", "November", "December", NULL};

static const char* s_ab_month_name[] = {"", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL};
static const char* s_day_name[] = {"Monday", "Tuesday", "Wednesday", "Thursday",
"Friday", "Saturday", "Sunday", NULL};

static const char* s_ab_day_name[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", NULL};

uint8_t mysql_week_mode(uint32_t mode) {
Expand Down Expand Up @@ -1154,7 +1150,7 @@ bool DateTimeValue::from_date_format_str(const char* format, int format_len, con
date_part_used = true;
break;
case 'M':
int_value = check_word(s_month_name, val, val_end, &val);
int_value = check_word(const_cast<const char**>(s_month_name), val, val_end, &val);
if (int_value < 0) {
return false;
}
Expand Down Expand Up @@ -1249,7 +1245,7 @@ bool DateTimeValue::from_date_format_str(const char* format, int format_len, con
break;
// Weekday
case 'W':
int_value = check_word(s_day_name, val, val_end, &val);
int_value = check_word(const_cast<const char**>(s_day_name), val, val_end, &val);
if (int_value < 0) {
return false;
}
Expand Down
120 changes: 72 additions & 48 deletions be/src/runtime/datetime_value.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,28 @@ const int TIME_MAX_SECOND = 59;
const int TIME_MAX_VALUE = 10000 * TIME_MAX_HOUR + 100 * TIME_MAX_MINUTE + TIME_MAX_SECOND;
const int TIME_MAX_VALUE_SECONDS = 3600 * TIME_MAX_HOUR + 60 * TIME_MAX_MINUTE + TIME_MAX_SECOND;

constexpr size_t const_length(const char* str) {
return (str == nullptr || *str == 0) ? 0 : const_length(str + 1) + 1;
}

constexpr size_t max_char_length(const char* const* name, size_t end) {
size_t res = 0;
for (int i = 0; i < end; ++i) {
res = std::max(const_length(name[i]), res);
}
return res;
}

static constexpr const char* s_month_name[] = {
"", "January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December", NULL};

static constexpr const char* s_day_name[] = {"Monday", "Tuesday", "Wednesday", "Thursday",
"Friday", "Saturday", "Sunday", NULL};

static constexpr size_t MAX_DAY_NAME_LEN = max_char_length(s_day_name, std::size(s_day_name));
static constexpr size_t MAX_MONTH_NAME_LEN = max_char_length(s_month_name, std::size(s_month_name));

uint8_t mysql_week_mode(uint32_t mode);

class DateTimeValue {
Expand Down Expand Up @@ -258,57 +280,59 @@ class DateTimeValue {
template <TimeUnit unit>
static int64_t datetime_diff(const DateTimeValue& ts_value1, const DateTimeValue& ts_value2) {
switch (unit) {
case YEAR: {
int year = (ts_value2.year() - ts_value1.year());
if (year > 0) {
year -= (ts_value2.to_int64() % 10000000000 - ts_value1.to_int64() % 10000000000) < 0;
} 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) {
month -= (ts_value2.to_int64() % 100000000 - ts_value1.to_int64() % 100000000) < 0;
} 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) {
day -= ts_value2.time_part_diff(ts_value1) < 0;
} 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) {
day -= ts_value2.time_part_diff(ts_value1) < 0;
} else if (day < 0) {
day += ts_value2.time_part_diff(ts_value1) > 0;
}
return day;
case YEAR: {
int year = (ts_value2.year() - ts_value1.year());
if (year > 0) {
year -= (ts_value2.to_int64() % 10000000000 - ts_value1.to_int64() % 10000000000) <
0;
} else if (year < 0) {
year += (ts_value2.to_int64() % 10000000000 - ts_value1.to_int64() % 10000000000) >
0;
}
case HOUR: {
int64_t second = ts_value2.second_diff(ts_value1);
int64_t hour = second / 60 / 60;
return hour;
return year;
}
case MONTH: {
int month = (ts_value2.year() - ts_value1.year()) * 12 +
(ts_value2.month() - ts_value1.month());
if (month > 0) {
month -= (ts_value2.to_int64() % 100000000 - ts_value1.to_int64() % 100000000) < 0;
} else if (month < 0) {
month += (ts_value2.to_int64() % 100000000 - ts_value1.to_int64() % 100000000) > 0;
}
case MINUTE: {
int64_t second = ts_value2.second_diff(ts_value1);
int64_t minute = second / 60;
return minute;
return month;
}
case WEEK: {
int day = ts_value2.daynr() - ts_value1.daynr();
if (day > 0) {
day -= ts_value2.time_part_diff(ts_value1) < 0;
} else if (day < 0) {
day += ts_value2.time_part_diff(ts_value1) > 0;
}
case SECOND: {
int64_t second = ts_value2.second_diff(ts_value1);
return second;
return day / 7;
}
case DAY: {
int day = ts_value2.daynr() - ts_value1.daynr();
if (day > 0) {
day -= ts_value2.time_part_diff(ts_value1) < 0;
} else if (day < 0) {
day += ts_value2.time_part_diff(ts_value1) > 0;
}
return day;
}
case HOUR: {
int64_t second = ts_value2.second_diff(ts_value1);
int64_t hour = second / 60 / 60;
return hour;
}
case MINUTE: {
int64_t second = ts_value2.second_diff(ts_value1);
int64_t minute = second / 60;
return minute;
}
case SECOND: {
int64_t second = ts_value2.second_diff(ts_value1);
return second;
}
}
// Rethink the default return value
return 0;
Expand All @@ -328,7 +352,7 @@ class DateTimeValue {

int year() const { return _year; }
int month() const { return _month; }
int quarter() const { return (_month - 1) / 3 + 1; }
int quarter() const { return (_month - 1) / 3 + 1; }
int day() const { return _day; }
int hour() const { return _hour; }
int minute() const { return _minute; }
Expand Down
2 changes: 2 additions & 0 deletions be/src/vec/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ set(VEC_FILES
functions/time_of_function.cpp
functions/if.cpp
functions/function_date_or_datetime_computation.cpp
functions/function_date_or_datetime_to_string.cpp
functions/function_datetime_string_to_string.cpp
sink/mysql_result_writer.cpp
sink/result_sink.cpp
sink/vdata_stream_sender.cpp
Expand Down
Loading

0 comments on commit 71be210

Please sign in to comment.