Add timestampadd/timestampdiff function (#2725)
This commit is contained in:
@ -351,6 +351,106 @@ DateTimeVal TimestampFunctions::timestamp_time_op(
|
||||
return new_ts_val;
|
||||
}
|
||||
|
||||
BigIntVal TimestampFunctions::years_diff(
|
||||
FunctionContext* ctx, const DateTimeVal& ts_val1, const DateTimeVal& ts_val2) {
|
||||
return timestamp_diff<YEAR>(ctx, ts_val1, ts_val2);
|
||||
}
|
||||
|
||||
BigIntVal TimestampFunctions::months_diff(
|
||||
FunctionContext* ctx, const DateTimeVal& ts_val1, const DateTimeVal& ts_val2) {
|
||||
return timestamp_diff<MONTH>(ctx, ts_val1, ts_val2);
|
||||
}
|
||||
|
||||
BigIntVal TimestampFunctions::weeks_diff(
|
||||
FunctionContext* ctx, const DateTimeVal& ts_val1, const DateTimeVal& ts_val2) {
|
||||
return timestamp_diff<WEEK>(ctx, ts_val1, ts_val2);
|
||||
}
|
||||
|
||||
BigIntVal TimestampFunctions::days_diff(
|
||||
FunctionContext* ctx, const DateTimeVal& ts_val1, const DateTimeVal& ts_val2) {
|
||||
return timestamp_diff<DAY>(ctx, ts_val1, ts_val2);
|
||||
}
|
||||
|
||||
BigIntVal TimestampFunctions::hours_diff(
|
||||
FunctionContext* ctx, const DateTimeVal& ts_val1, const DateTimeVal& ts_val2) {
|
||||
return timestamp_diff<HOUR>(ctx, ts_val1, ts_val2);
|
||||
}
|
||||
|
||||
BigIntVal TimestampFunctions::minutes_diff(
|
||||
FunctionContext* ctx, const DateTimeVal& ts_val1, const DateTimeVal& ts_val2) {
|
||||
return timestamp_diff<MINUTE>(ctx, ts_val1, ts_val2);
|
||||
}
|
||||
|
||||
BigIntVal TimestampFunctions::seconds_diff(
|
||||
FunctionContext* ctx, const DateTimeVal& ts_val1, const DateTimeVal& ts_val2) {
|
||||
return timestamp_diff<SECOND>(ctx, ts_val1, ts_val2);
|
||||
}
|
||||
|
||||
template <TimeUnit unit>
|
||||
BigIntVal TimestampFunctions::timestamp_diff(FunctionContext* ctx, const DateTimeVal& ts_val2, const DateTimeVal& ts_val1) {
|
||||
if (ts_val1.is_null || ts_val2.is_null) {
|
||||
return BigIntVal::null();
|
||||
}
|
||||
|
||||
DateTimeValue ts_value1 = DateTimeValue::from_datetime_val(ts_val1);
|
||||
DateTimeValue ts_value2 = DateTimeValue::from_datetime_val(ts_val2);
|
||||
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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;
|
||||
}
|
||||
default:
|
||||
return BigIntVal::null();
|
||||
}
|
||||
}
|
||||
|
||||
StringVal TimestampFunctions::date_format(
|
||||
FunctionContext* ctx, const DateTimeVal& ts_val, const StringVal& format) {
|
||||
if (ts_val.is_null || format.is_null) {
|
||||
|
||||
Reference in New Issue
Block a user