[Feature](function) support sec_to_time (#62797)

This commit is contained in:
lyw 2025-10-11 17:28:48 +08:00 committed by GitHub
parent 731ff88162
commit b05e7ded50
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 239 additions and 2 deletions

View File

@ -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"

View File

@ -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]

View File

@ -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

View File

@ -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'|
+-----------------------------+
```

View File

@ -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'|
+-----------------------------+
```

View File

@ -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";

View File

@ -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)");
}
}

View File

@ -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.

View File

@ -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

View File

@ -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);