[scn] support scn_to_str()

This commit is contained in:
yyy-hust
2023-06-27 10:42:28 +00:00
committed by ob-robot
parent 37c0e8008c
commit 5267b750b0
3 changed files with 89 additions and 0 deletions

View File

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

View File

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

View File

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