[scn] support scn_to_str()
This commit is contained in:
41
deps/oblib/src/lib/timezone/ob_time_convert.cpp
vendored
41
deps/oblib/src/lib/timezone/ob_time_convert.cpp
vendored
@ -625,6 +625,47 @@ int ObTimeConverter::str_to_scn_value(const ObString &str,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObTimeConverter::scn_to_str(const uint64_t scn_val,
|
||||
const ObTimeZoneInfo *sys_tz_info,
|
||||
char *buf, int64_t buf_len, int64_t &pos)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(sys_tz_info) || OB_ISNULL(buf) || OB_UNLIKELY(buf_len <= 0)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid arguments", KP(sys_tz_info), KP(buf), K(buf_len));
|
||||
} else {
|
||||
const int64_t utc_timestamp = scn_val / 1000;
|
||||
int64_t dt_value = 0;
|
||||
if (OB_FAIL(ObTimeConverter::timestamp_to_datetime(utc_timestamp,
|
||||
sys_tz_info,
|
||||
dt_value))) {
|
||||
LOG_WARN("failed to convert timestamp to datetime", K(ret));
|
||||
} else if (OB_UNLIKELY(dt_value > DATETIME_MAX_VAL || dt_value < DATETIME_MIN_VAL)) {
|
||||
ret = OB_OPERATE_OVERFLOW;
|
||||
LOG_WARN("overflow", K(utc_timestamp), K(dt_value), K(scn_val), K(sys_tz_info));
|
||||
} else {
|
||||
const int32_t value_ns = scn_val % 1000;
|
||||
ObOTimestampData ot_data;
|
||||
ot_data.time_us_ = dt_value;
|
||||
ot_data.time_ctx_.tail_nsec_ = value_ns;
|
||||
const int16_t MAX_NS_SCALE = 9;
|
||||
const ObObjType type = ObTimestampNanoType;
|
||||
ObString otimestamp_format("YYYY-MM-DD HH24:MI:SS.FF9");
|
||||
const ObDataTypeCastParams dtc_params(sys_tz_info/*not used during otimestamp_to_str with ObTimestampNanoType*/,
|
||||
DEFAULT_NLS_DATE_FORMAT,
|
||||
otimestamp_format,
|
||||
DEFAULT_NLS_TIMESTAMP_TZ_FORMAT,
|
||||
CS_TYPE_INVALID,
|
||||
CS_TYPE_INVALID,
|
||||
CS_TYPE_UTF8MB4_GENERAL_CI);
|
||||
if (OB_FAIL(otimestamp_to_str(ot_data, dtc_params, MAX_NS_SCALE, type, buf, buf_len, pos))) {
|
||||
LOG_WARN("fail to cast otimestamp to str", K(utc_timestamp), K(dt_value), K(scn_val), K(sys_tz_info));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief calcs tz offset value by time zone name from the input ob_time, fills the result back to ob_time
|
||||
* @param in: cvrt_ctx
|
||||
|
||||
@ -400,6 +400,11 @@ public:
|
||||
const ObString &nlf_format,
|
||||
const bool is_oracle_mode,
|
||||
uint64_t &scn_value);
|
||||
//convert a scn to timestamp str with ns
|
||||
//invoker need to gurantee scn_val is valid
|
||||
static int scn_to_str(const uint64_t scn_val,
|
||||
const ObTimeZoneInfo *sys_tz_info,
|
||||
char *buf, int64_t buf_len, int64_t &pos);
|
||||
//ob_time store local time
|
||||
static int str_to_tz_offset(const ObTimeConvertCtx &cvrt_ctx, ObTime &ob_time);
|
||||
//ob_time store local time
|
||||
|
||||
@ -3200,8 +3200,51 @@ TEST(ObTimeConvertTest, interval)
|
||||
|
||||
}
|
||||
|
||||
TEST(ObTimeConvertTest, scn_to_str)
|
||||
{
|
||||
// timezone with offset only.
|
||||
ObString tz_str;
|
||||
ObTimeZoneInfo tz_info;
|
||||
char tz_buf[50] = {0};
|
||||
tz_str.assign_buffer(tz_buf, 50);
|
||||
strcpy(tz_buf, "+8:00");
|
||||
tz_str.set_length(static_cast<int32_t>(strlen(tz_buf)));
|
||||
tz_info.set_timezone(tz_str);
|
||||
|
||||
const int64_t BUF_LEN = 100;
|
||||
char buf[BUF_LEN] = {0};
|
||||
int64_t pos = 0;
|
||||
uint64_t scn_val = 9223372036854775808UL;
|
||||
|
||||
ASSERT_EQ(OB_INVALID_ARGUMENT, ObTimeConverter::scn_to_str(scn_val, NULL, buf, BUF_LEN, pos));
|
||||
ASSERT_EQ(OB_INVALID_ARGUMENT, ObTimeConverter::scn_to_str(scn_val, &tz_info, NULL, BUF_LEN, pos));
|
||||
ASSERT_EQ(OB_INVALID_ARGUMENT, ObTimeConverter::scn_to_str(scn_val, &tz_info, buf, 0, pos));
|
||||
|
||||
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::scn_to_str(scn_val, &tz_info, buf, BUF_LEN, pos));
|
||||
OB_LOG(INFO, "YYY +8:00", K(scn_val), K(tz_buf), K(buf));
|
||||
|
||||
pos= 0;
|
||||
scn_val = 1687780338123456789;
|
||||
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::scn_to_str(scn_val, &tz_info, buf, BUF_LEN, pos));
|
||||
OB_LOG(INFO, "YYY +8:00", K(scn_val), K(tz_buf), K(buf));
|
||||
ASSERT_TRUE(0 == strcmp(buf, "2023-06-26 19:52:18.123456789"));
|
||||
|
||||
|
||||
strcpy(tz_buf, "-08:00");
|
||||
tz_str.assign(tz_buf, static_cast<int32_t>(strlen(tz_buf)));
|
||||
tz_info.set_timezone(tz_str);
|
||||
|
||||
pos= 0;
|
||||
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::scn_to_str(scn_val, &tz_info, buf, BUF_LEN, pos));
|
||||
OB_LOG(INFO, "YYY -08:00", K(scn_val), K(tz_buf), K(buf));
|
||||
ASSERT_TRUE(0 == strcmp(buf, "2023-06-26 03:52:18.123456789"));
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
system("rm -f test_time_convert.log");
|
||||
OB_LOGGER.set_file_name("test_time_convert.log", true);
|
||||
OB_LOGGER.set_log_level("INFO");
|
||||
::testing::InitGoogleTest(&argc,argv);
|
||||
return RUN_ALL_TESTS();
|
||||
|
||||
Reference in New Issue
Block a user