[Feature](function) support sec_to_time (#62797)
This commit is contained in:
parent
731ff88162
commit
b05e7ded50
|
|
@ -3897,6 +3897,39 @@ StatusOr<ColumnPtr> TimeFunctions::time_format(FunctionContext* context, const s
|
|||
return builder.build(ColumnHelper::is_all_const(columns));
|
||||
}
|
||||
|
||||
constexpr static const int64_t MAX_TIME = 3023999L;
|
||||
|
||||
static int64_t from_seconds_with_limit(int64_t time) {
|
||||
if (time > MAX_TIME) {
|
||||
return MAX_TIME;
|
||||
}
|
||||
if (time < -MAX_TIME) {
|
||||
return -MAX_TIME;
|
||||
}
|
||||
return time;
|
||||
}
|
||||
|
||||
StatusOr<ColumnPtr> TimeFunctions::sec_to_time(FunctionContext* context, const starrocks::Columns& columns) {
|
||||
const auto& bigint_column = columns[0];
|
||||
|
||||
RETURN_IF_COLUMNS_ONLY_NULL(columns);
|
||||
|
||||
auto bigint_viewer = ColumnViewer<TYPE_BIGINT>(bigint_column);
|
||||
const size_t size = bigint_column->size();
|
||||
auto builder = ColumnBuilder<TYPE_TIME>(size);
|
||||
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
if (bigint_viewer.is_null(i)) {
|
||||
builder.append_null();
|
||||
continue;
|
||||
}
|
||||
auto time = static_cast<double>(from_seconds_with_limit(bigint_viewer.value(i)));
|
||||
builder.append(time);
|
||||
}
|
||||
|
||||
return builder.build(ColumnHelper::is_all_const(columns));
|
||||
}
|
||||
|
||||
} // namespace starrocks
|
||||
|
||||
#include "gen_cpp/opcode/TimeFunctions.inc"
|
||||
|
|
|
|||
|
|
@ -766,6 +766,14 @@ public:
|
|||
*/
|
||||
DEFINE_VECTORIZED_FN(time_to_sec);
|
||||
|
||||
/**
|
||||
* return time
|
||||
* @param: [int]
|
||||
* @paramType columns: [BinaryColumn]
|
||||
* @return Int64Column
|
||||
*/
|
||||
DEFINE_VECTORIZED_FN(sec_to_time);
|
||||
|
||||
/**
|
||||
* Returns the date of the first specified DOW (day of week) that occurs after the input date.
|
||||
* @param: [timestamp, dow]
|
||||
|
|
|
|||
|
|
@ -4727,4 +4727,79 @@ TEST_F(TimeFunctionsTest, hourFromUnixTime) {
|
|||
}
|
||||
}
|
||||
|
||||
} // namespace starrocks
|
||||
// Tests for sec_to_time function
|
||||
TEST_F(TimeFunctionsTest, secToTimeTest) {
|
||||
{
|
||||
auto int_value = ColumnHelper::create_column(TypeDescriptor(TYPE_BIGINT), false);
|
||||
|
||||
int_value->append_datum(0L);
|
||||
int_value->append_datum(1L);
|
||||
int_value->append_datum(60L);
|
||||
int_value->append_datum(3600L);
|
||||
int_value->append_datum(36000L);
|
||||
int_value->append_datum(86399L);
|
||||
int_value->append_datum(3024000L);
|
||||
int_value->append_datum(4000000L);
|
||||
|
||||
Columns columns;
|
||||
columns.emplace_back(int_value);
|
||||
|
||||
ColumnPtr result = TimeFunctions::sec_to_time(_utils->get_fn_ctx(), columns).value();
|
||||
auto v = ColumnHelper::cast_to<TYPE_TIME>(result);
|
||||
|
||||
EXPECT_EQ(8, result->size());
|
||||
EXPECT_EQ(0, v->get_data()[0]);
|
||||
EXPECT_EQ(1, v->get_data()[1]);
|
||||
EXPECT_EQ(60, v->get_data()[2]);
|
||||
EXPECT_EQ(3600, v->get_data()[3]);
|
||||
EXPECT_EQ(36000, v->get_data()[4]);
|
||||
EXPECT_EQ(86399, v->get_data()[5]);
|
||||
EXPECT_EQ(3023999, v->get_data()[6]);
|
||||
EXPECT_EQ(3023999, v->get_data()[7]);
|
||||
}
|
||||
{
|
||||
auto int_value = ColumnHelper::create_column(TypeDescriptor(TYPE_BIGINT), false);
|
||||
|
||||
int_value->append_datum(-0L);
|
||||
int_value->append_datum(-1L);
|
||||
int_value->append_datum(-60L);
|
||||
int_value->append_datum(-3600L);
|
||||
int_value->append_datum(-36000L);
|
||||
int_value->append_datum(-86399L);
|
||||
int_value->append_datum(-3024000L);
|
||||
int_value->append_datum(-4000000L);
|
||||
|
||||
Columns columns;
|
||||
columns.emplace_back(int_value);
|
||||
|
||||
ColumnPtr result = TimeFunctions::sec_to_time(_utils->get_fn_ctx(), columns).value();
|
||||
auto v = ColumnHelper::cast_to<TYPE_TIME>(result);
|
||||
|
||||
EXPECT_EQ(8, result->size());
|
||||
EXPECT_EQ(0, v->get_data()[0]);
|
||||
EXPECT_EQ(-1, v->get_data()[1]);
|
||||
EXPECT_EQ(-60, v->get_data()[2]);
|
||||
EXPECT_EQ(-3600, v->get_data()[3]);
|
||||
EXPECT_EQ(-36000, v->get_data()[4]);
|
||||
EXPECT_EQ(-86399, v->get_data()[5]);
|
||||
EXPECT_EQ(-3023999, v->get_data()[6]);
|
||||
EXPECT_EQ(-3023999, v->get_data()[7]);
|
||||
}
|
||||
|
||||
{
|
||||
// Create null column
|
||||
auto null_value = ColumnHelper::create_column(TypeDescriptor(TYPE_BIGINT), true);
|
||||
|
||||
(void)null_value->append_nulls(1);
|
||||
|
||||
Columns columns;
|
||||
columns.emplace_back(null_value);
|
||||
|
||||
ColumnPtr result = TimeFunctions::sec_to_time(_utils->get_fn_ctx(), columns).value();
|
||||
|
||||
EXPECT_EQ(1, result->size());
|
||||
ASSERT_TRUE(result->is_nullable());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace starrocks
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
displayed_sidebar: docs
|
||||
---
|
||||
|
||||
# sec_to_time
|
||||
|
||||
## Description
|
||||
|
||||
The SEC_TO_TIME function converts a value in seconds into a TIME type, returning the result in the format HH:MM:SS.
|
||||
The input seconds represent the time elapsed since the start of a day (00:00:00).
|
||||
|
||||
## Syntax
|
||||
|
||||
```Haskell
|
||||
TIME sec_to_time(BIGINT sec)
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
`sec`: It must be of the INT type.
|
||||
|
||||
## Return value
|
||||
|
||||
Returns a TIME value in the format HH:MM:SS, representing the time calculated from the start of a day (00:00:00).
|
||||
If sec is NULL, the function returns NULL.
|
||||
|
||||
## Examples
|
||||
|
||||
```plain text
|
||||
select sec_to_time(43994);
|
||||
+-----------------------------+
|
||||
| sec_to_time(43994) |
|
||||
+-----------------------------+
|
||||
| '12:13:14'|
|
||||
+-----------------------------+
|
||||
```
|
||||
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
---
|
||||
displayed_sidebar: docs
|
||||
---
|
||||
|
||||
# sec_to_time
|
||||
|
||||
## 功能
|
||||
|
||||
SEC_TO_TIME 函数将一个以秒为单位的值转换为 TIME 类型,返回格式为 HH:MM:SS。输入的秒数表示从一天的起点时间(00:00:00)开始计算的时间。
|
||||
|
||||
## 语法
|
||||
|
||||
```Haskell
|
||||
TIME sec_to_time(BIGINT sec)
|
||||
```
|
||||
|
||||
## 参数说明
|
||||
|
||||
`sec`:必填,输入的秒数,表示从一天起点时间(00:00:00)开始计算的秒数,支持正整数或负整数类型。
|
||||
|
||||
## 返回值说明
|
||||
|
||||
必填,输入的秒数,表示从一天起点时间(00:00:00)开始计算的秒数,支持正整数或负整数类型。
|
||||
如果输入的 sec 为 NULL,函数返回 NULL。
|
||||
|
||||
## 示例
|
||||
|
||||
```plain text
|
||||
select sec_to_time(43994);
|
||||
+-----------------------------+
|
||||
| sec_to_time(43994) |
|
||||
+-----------------------------+
|
||||
| '12:13:14'|
|
||||
+-----------------------------+
|
||||
```
|
||||
|
|
@ -131,6 +131,7 @@ public class FunctionSet {
|
|||
public static final String QUARTER = "quarter";
|
||||
public static final String TIMESTAMP = "timestamp";
|
||||
public static final String TIME_TO_SEC = "time_to_sec";
|
||||
public static final String SEC_TO_TIME = "sec_to_time";
|
||||
public static final String STR2DATE = "str2date";
|
||||
public static final String MICROSECONDS_ADD = "microseconds_add";
|
||||
public static final String MICROSECONDS_SUB = "microseconds_sub";
|
||||
|
|
|
|||
|
|
@ -323,4 +323,15 @@ public class AnalyzeFunctionTest {
|
|||
analyzeFail("select array_generate(1, 5, 'a')");
|
||||
analyzeFail("select array_generate(1, 2, 3, 4)");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecToTime() throws Exception {
|
||||
analyzeFail("select sec_to_time()");
|
||||
analyzeSuccess("select sec_to_time(0)");
|
||||
analyzeSuccess("select sec_to_time(1)");
|
||||
analyzeSuccess("select sec_to_time(-1)");
|
||||
analyzeSuccess("select sec_to_time(3024000)");
|
||||
analyzeSuccess("select sec_to_time(-3024000)");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -565,6 +565,7 @@ vectorized_functions = [
|
|||
[50262, 'to_iso8601', True, False, 'VARCHAR', ['DATETIME'], 'TimeFunctions::datetime_to_iso8601'],
|
||||
[50263, 'to_iso8601', True, False, 'VARCHAR', ['DATE'], 'TimeFunctions::date_to_iso8601'],
|
||||
[50250, 'time_to_sec', True, False, 'BIGINT', ['TIME'], 'TimeFunctions::time_to_sec'],
|
||||
[50251, 'sec_to_time', True, False, 'TIME', ['BIGINT'], 'TimeFunctions::sec_to_time'],
|
||||
|
||||
# unix timestamp extended version to int64
|
||||
# be sure to put before int32 version, so fe will find signature in order.
|
||||
|
|
|
|||
|
|
@ -984,4 +984,31 @@ select timestampadd(MILLISECOND, 1, '2019-01-02 00:00:00');
|
|||
select timestampdiff(MILLISECOND, '2003-02-01 00:00:00', '2003-05-01 12:05:55');
|
||||
-- result:
|
||||
7733155000
|
||||
-- !result
|
||||
-- !result
|
||||
|
||||
-- name: sec_to_time
|
||||
select sec_to_time(NULL);
|
||||
-- result:
|
||||
NULL
|
||||
-- !result
|
||||
select sec_to_time(0);
|
||||
-- result:
|
||||
00:00:00
|
||||
-- !result
|
||||
select sec_to_time(1);
|
||||
-- result:
|
||||
00:00:01
|
||||
-- !result
|
||||
select sec_to_time(-1);
|
||||
-- result:
|
||||
-00:00:01
|
||||
-- !result
|
||||
select sec_to_time(3024000);
|
||||
-- result:
|
||||
839:59:59
|
||||
-- !result
|
||||
select sec_to_time(-3024000);
|
||||
-- result:
|
||||
-839:59:59
|
||||
-- !result
|
||||
|
||||
|
|
|
|||
|
|
@ -327,3 +327,12 @@ select timestampadd(MILLISECOND, 1, '2019-01-02 00:00:00');
|
|||
|
||||
-- name: test_timestamp_diff
|
||||
select timestampdiff(MILLISECOND, '2003-02-01 00:00:00', '2003-05-01 12:05:55');
|
||||
|
||||
|
||||
-- name: sec_to_time
|
||||
select sec_to_time(NULL);
|
||||
select sec_to_time(0);
|
||||
select sec_to_time(1);
|
||||
select sec_to_time(-1);
|
||||
select sec_to_time(3024000);
|
||||
select sec_to_time(-3024000);
|
||||
|
|
|
|||
Loading…
Reference in New Issue