Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
大炮V587
oceanbase
提交
676c105d
O
oceanbase
项目概览
大炮V587
/
oceanbase
与 Fork 源项目一致
Fork自
oceanbase / oceanbase
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
oceanbase
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
676c105d
编写于
12月 06, 2022
作者:
O
obdev
提交者:
ob-robot
1月 12, 2023
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix bug about second and microsecond function and update cases
上级
4d38a86d
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
59 addition
and
46 deletion
+59
-46
deps/oblib/src/lib/timezone/ob_time_convert.cpp
deps/oblib/src/lib/timezone/ob_time_convert.cpp
+31
-25
deps/oblib/src/lib/timezone/ob_time_convert.h
deps/oblib/src/lib/timezone/ob_time_convert.h
+4
-3
src/sql/engine/expr/ob_datum_cast.cpp
src/sql/engine/expr/ob_datum_cast.cpp
+18
-16
src/sql/engine/expr/ob_expr_time.h
src/sql/engine/expr/ob_expr_time.h
+6
-2
未找到文件。
deps/oblib/src/lib/timezone/ob_time_convert.cpp
浏览文件 @
676c105d
...
...
@@ -140,7 +140,6 @@ static const int32_t DAYS_PER_YEAR[2]=
#define EPOCH_WDAY 4 // 1970-1-1 is thursday.
#define LEAP_YEAR_COUNT(y) ((y) / 4 - (y) / 100 + (y) / 400)
#define IS_LEAP_YEAR(y) ((((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) ? 1 : 0)
#define TIME_MAX_VAL (3020399 * 1000000LL) // 838:59:59 .
#define YEAR_MAX_YEAR 2155
#define YEAR_MIN_YEAR 1901
#define YEAR_BASE_YEAR 1900
...
...
@@ -793,7 +792,7 @@ int ObTimeConverter::str_to_date(const ObString &str, int32_t &value,
return
ret
;
}
int
ObTimeConverter
::
str_to_time
(
const
ObString
&
str
,
int64_t
&
value
,
int16_t
*
scale
)
int
ObTimeConverter
::
str_to_time
(
const
ObString
&
str
,
int64_t
&
value
,
int16_t
*
scale
,
const
ObScale
&
time_scale
)
{
int
ret
=
OB_SUCCESS
;
ObTime
ob_time
(
DT_TYPE_TIME
);
...
...
@@ -801,14 +800,14 @@ int ObTimeConverter::str_to_time(const ObString &str, int64_t &value, int16_t *s
LOG_WARN
(
"failed to convert string to time"
,
K
(
ret
),
K
(
str
));
if
(
OB_ERR_TRUNCATED_WRONG_VALUE
==
ret
)
{
value
=
ob_time_to_time
(
ob_time
);
time_overflow_trunc
(
value
);
time_overflow_trunc
(
value
,
time_scale
);
if
(
DT_MODE_NEG
&
ob_time
.
mode_
)
{
value
=
-
value
;
}
}
}
else
{
value
=
ob_time_to_time
(
ob_time
);
ret
=
time_overflow_trunc
(
value
);
ret
=
time_overflow_trunc
(
value
,
time_scale
);
if
(
DT_MODE_NEG
&
ob_time
.
mode_
)
{
value
=
-
value
;
}
...
...
@@ -1710,39 +1709,45 @@ int ObTimeConverter::int_to_ob_time_with_date(int64_t int64, ObTime &ob_time, bo
return
ret
;
}
int
ObTimeConverter
::
int_to_ob_time_without_date
(
int64_t
int64
,
ObTime
&
ob_time
)
int
ObTimeConverter
::
int_to_ob_time_without_date
(
int64_t
time_second
,
ObTime
&
ob_time
,
int64_t
nano_second
)
{
int
ret
=
OB_SUCCESS
;
int32_t
*
parts
=
ob_time
.
parts_
;
ObDTMode
mode
=
DT_TYPE_TIME
;
if
(
int64
<
0
)
{
if
(
time_second
<
0
)
{
ob_time
.
mode_
|=
DT_MODE_NEG
;
if
(
INT64_MIN
==
int64
)
{
int64
=
INT64_MAX
;
if
(
INT64_MIN
==
time_second
)
{
time_second
=
INT64_MAX
;
}
else
{
int64
=
-
int64
;
time_second
=
-
time_second
;
}
}
if
(
int64
/
power_of_10
[
4
]
<
power_of_10
[
6
])
{
if
(
time_second
/
power_of_10
[
4
]
<
power_of_10
[
6
])
{
// [H]HHMMSS, like 123:45:56.
parts
[
DT_SEC
]
=
static_cast
<
int32_t
>
(
int64
%
power_of_10
[
2
]);
int64
/=
power_of_10
[
2
];
parts
[
DT_MIN
]
=
static_cast
<
int32_t
>
(
int64
%
power_of_10
[
2
]);
int64
/=
power_of_10
[
2
];
parts
[
DT_HOUR
]
=
static_cast
<
int32_t
>
(
int64
%
power_of_10
[
6
]);
if
(
nano_second
)
{
parts
[
DT_USEC
]
=
static_cast
<
int32_t
>
((
nano_second
+
500
)
/
power_of_10
[
3
]);
}
parts
[
DT_SEC
]
=
static_cast
<
int32_t
>
(
time_second
%
power_of_10
[
2
]);
time_second
/=
power_of_10
[
2
];
parts
[
DT_MIN
]
=
static_cast
<
int32_t
>
(
time_second
%
power_of_10
[
2
]);
time_second
/=
power_of_10
[
2
];
parts
[
DT_HOUR
]
=
static_cast
<
int32_t
>
(
time_second
%
power_of_10
[
6
]);
if
(
OB_FAIL
(
validate_time
(
ob_time
)))
{
LOG_WARN
(
"time integer is invalid"
,
K
(
ret
),
K
(
int64
));
LOG_WARN
(
"time integer is invalid"
,
K
(
ret
),
K
(
time_second
));
}
}
else
if
(
int64
/
power_of_10
[
6
]
<
power_of_10
[
8
])
{
}
else
if
(
time_second
/
power_of_10
[
6
]
<
power_of_10
[
8
])
{
// HHHHMMDDHHMMSS.
mode
=
DT_TYPE_DATETIME
;
parts
[
DT_SEC
]
=
static_cast
<
int32_t
>
(
int64
%
power_of_10
[
2
]);
int64
/=
power_of_10
[
2
];
parts
[
DT_MIN
]
=
static_cast
<
int32_t
>
(
int64
%
power_of_10
[
2
]);
int64
/=
power_of_10
[
2
];
parts
[
DT_HOUR
]
=
static_cast
<
int32_t
>
(
int64
%
power_of_10
[
2
]);
int64
/=
power_of_10
[
2
];
parts
[
DT_MDAY
]
=
static_cast
<
int32_t
>
(
int64
%
power_of_10
[
2
]);
int64
/=
power_of_10
[
2
];
parts
[
DT_MON
]
=
static_cast
<
int32_t
>
(
int64
%
power_of_10
[
2
]);
int64
/=
power_of_10
[
2
];
parts
[
DT_YEAR
]
=
static_cast
<
int32_t
>
(
int64
%
power_of_10
[
4
]);
if
(
nano_second
)
{
parts
[
DT_USEC
]
=
static_cast
<
int32_t
>
((
nano_second
+
500
)
/
power_of_10
[
3
]);
}
parts
[
DT_SEC
]
=
static_cast
<
int32_t
>
(
time_second
%
power_of_10
[
2
]);
time_second
/=
power_of_10
[
2
];
parts
[
DT_MIN
]
=
static_cast
<
int32_t
>
(
time_second
%
power_of_10
[
2
]);
time_second
/=
power_of_10
[
2
];
parts
[
DT_HOUR
]
=
static_cast
<
int32_t
>
(
time_second
%
power_of_10
[
2
]);
time_second
/=
power_of_10
[
2
];
parts
[
DT_MDAY
]
=
static_cast
<
int32_t
>
(
time_second
%
power_of_10
[
2
]);
time_second
/=
power_of_10
[
2
];
parts
[
DT_MON
]
=
static_cast
<
int32_t
>
(
time_second
%
power_of_10
[
2
]);
time_second
/=
power_of_10
[
2
];
parts
[
DT_YEAR
]
=
static_cast
<
int32_t
>
(
time_second
%
power_of_10
[
4
]);
apply_date_year2_rule
(
parts
[
DT_YEAR
]);
if
(
OB_FAIL
(
validate_datetime
(
ob_time
,
false
,
0
)))
{
LOG_WARN
(
"datetime is invalid or out of range"
,
K
(
ret
),
K
(
int64
));
LOG_WARN
(
"datetime is invalid or out of range"
,
K
(
ret
),
K
(
time_second
),
K
(
nano_second
));
}
else
if
(
ZERO_DATE
!=
parts
[
DT_DATE
])
{
parts
[
DT_DATE
]
=
ob_time_to_date
(
ob_time
);
}
...
...
@@ -5362,10 +5367,11 @@ int ObTimeConverter::set_ob_time_year_may_conflict(ObTime &ob_time, int32_t &jul
return
ret
;
}
int
ObTimeConverter
::
time_overflow_trunc
(
int64_t
&
value
)
int
ObTimeConverter
::
time_overflow_trunc
(
int64_t
&
value
,
const
ObScale
&
time_scale
)
{
int
ret
=
OB_SUCCESS
;
if
(
value
>
TIME_MAX_VAL
)
{
int64_t
increment
=
(
6
==
time_scale
)
?
999999
:
0
;
if
(
value
>
(
TIME_MAX_VAL
+
increment
))
{
// we need some ob error codes that map to ER_TRUNCATED_WRONG_VALUE,
// so we get OB_INVALID_DATE_FORMAT / OB_INVALID_DATE_VALUE / OB_ERR_TRUNCATED_WRONG_VALUE.
// another requirement comes from cast function in ob_obj_cast.cpp is this time object will be
...
...
@@ -5373,7 +5379,7 @@ int ObTimeConverter::time_overflow_trunc(int64_t &value)
// so we get the ONLY one: OB_ERR_TRUNCATED_WRONG_VALUE, because the other two will direct to
// ZERO_VAL of the temporal types, like cast 'abc' or '1998-76-54' to date.
ret
=
OB_ERR_TRUNCATED_WRONG_VALUE
;
value
=
TIME_MAX_VAL
;
value
=
TIME_MAX_VAL
+
increment
;
}
return
ret
;
}
...
...
deps/oblib/src/lib/timezone/ob_time_convert.h
浏览文件 @
676c105d
...
...
@@ -157,6 +157,7 @@ extern const int64_t USECS_PER_MIN;
#define MYSQL_TIMESTAMP_MIN_VAL -62167046400000000
#define ORACLE_DATETIME_MIN_VAL -62135596800000000 //start from '0001-1-1 00:00:00'
#define TIME_MAX_HOUR 838
#define TIME_MAX_VAL (3020399 * 1000000LL) // 838:59:59 .
struct
ObIntervalLimit
{
static
const
ObOracleTimeLimiter
YEAR
;
...
...
@@ -405,7 +406,7 @@ public:
static
int
str_is_date_format
(
const
ObString
&
str
,
bool
&
date_flag
);
static
int
str_to_date
(
const
ObString
&
str
,
int32_t
&
value
,
const
ObDateSqlMode
date_sql_mode
=
0
);
static
int
str_to_time
(
const
ObString
&
str
,
int64_t
&
value
,
int16_t
*
scale
=
NULL
);
static
int
str_to_time
(
const
ObString
&
str
,
int64_t
&
value
,
int16_t
*
scale
=
NULL
,
const
ObScale
&
time_scale
=
0
);
static
int
str_to_year
(
const
ObString
&
str
,
uint8_t
&
value
);
static
int
str_to_interval
(
const
ObString
&
str
,
ObDateUnitType
unit_type
,
int64_t
&
value
);
// int / double / string <- datetime(timestamp) / date / time / year.
...
...
@@ -475,7 +476,7 @@ public:
// int / string -> ObTime / ObInterval <- datetime(timestamp) / date / time / year.
static
int
int_to_ob_time_with_date
(
int64_t
int64
,
ObTime
&
ob_time
,
bool
is_dayofmonth
,
const
ObDateSqlMode
date_sql_mode
);
static
int
int_to_ob_time_without_date
(
int64_t
int64
,
ObTime
&
ob_time
);
static
int
int_to_ob_time_without_date
(
int64_t
time_second
,
ObTime
&
ob_time
,
int64_t
nano_second
=
0
);
static
int
str_to_ob_time_with_date
(
const
ObString
&
str
,
ObTime
&
ob_time
,
int16_t
*
scale
,
const
bool
is_dayofmonth
,
const
ObDateSqlMode
date_sql_mode
);
static
int
str_to_ob_time_without_date
(
const
ObString
&
str
,
ObTime
&
ob_time
,
int16_t
*
scale
=
NULL
);
...
...
@@ -569,7 +570,7 @@ public:
static
int
set_ob_time_part_directly
(
ObTime
&
ob_time
,
int64_t
&
conflict_bitset
,
const
int64_t
part_offset
,
const
int32_t
part_value
);
static
int
set_ob_time_part_may_conflict
(
ObTime
&
ob_time
,
int64_t
&
conflict_bitset
,
const
int64_t
part_offset
,
const
int32_t
part_value
);
static
int32_t
calc_max_name_length
(
const
ObTimeConstStr
names
[],
const
int64_t
size
);
static
int
time_overflow_trunc
(
int64_t
&
value
);
static
int
time_overflow_trunc
(
int64_t
&
value
,
const
ObScale
&
time_scale
=
0
);
static
void
round_datetime
(
int16_t
scale
,
int64_t
&
value
);
static
ObOTimestampData
round_otimestamp
(
const
int16_t
scale
,
const
ObOTimestampData
&
in_ot_data
);
static
int
round_interval_ds
(
const
ObScale
scale
,
ObIntervalDSValue
&
value
);
...
...
src/sql/engine/expr/ob_datum_cast.cpp
浏览文件 @
676c105d
...
...
@@ -32,7 +32,6 @@ namespace oceanbase
namespace
sql
{
using
namespace
oceanbase
::
common
;
//// common function and macro
#define CAST_FUNC_NAME(intype, outtype) \
int intype##_##outtype(const sql::ObExpr &expr, \
...
...
@@ -959,7 +958,8 @@ static OB_INLINE int common_string_time(const ObExpr &expr,
int
warning
=
OB_SUCCESS
;
int64_t
out_val
=
0
;
ObScale
res_scale
;
// useless
if
(
CAST_FAIL
(
ObTimeConverter
::
str_to_time
(
in_str
,
out_val
,
&
res_scale
)))
{
ObScale
time_scale
=
expr
.
datum_meta_
.
scale_
;
if
(
CAST_FAIL
(
ObTimeConverter
::
str_to_time
(
in_str
,
out_val
,
&
res_scale
,
time_scale
)))
{
LOG_WARN
(
"str_to_time failed"
,
K
(
ret
),
K
(
in_str
));
}
else
{
SET_RES_TIME
(
out_val
);
...
...
@@ -9234,7 +9234,7 @@ int ob_datum_to_ob_time_without_date(const ObDatum &datum, const ObObjType type,
LOG_WARN
(
"int to ob time without date failed"
,
K
(
ret
));
}
else
{
//mysql中intTC转time时,如果hour超过838,那么time应该为null,而不是最大值。
const
int64_t
time_max_val
=
3020399
*
1000000L
L
;
// 838:59:59 .
const
int64_t
time_max_val
=
TIME_MAX_VA
L
;
// 838:59:59 .
int64_t
value
=
ObTimeConverter
::
ob_time_to_time
(
ob_time
);
if
(
value
>
time_max_val
)
{
ret
=
OB_INVALID_DATE_VALUE
;
...
...
@@ -9279,21 +9279,23 @@ int ob_datum_to_ob_time_without_date(const ObDatum &datum, const ObObjType type,
break
;
}
case
ObNumberTC
:
{
number
::
ObNumber
num
(
datum
.
get_number
());
const
char
*
num_format
=
num
.
format
();
if
(
OB_ISNULL
(
num_format
))
{
ret
=
OB_ERR_UNEXPECTED
;
LOG_WARN
(
"number format value is null"
,
K
(
ret
));
int64_t
int_part
=
0
;
int64_t
dec_part
=
0
;
const
number
::
ObNumber
num
(
datum
.
get_number
());
if
(
!
num
.
is_int_parts_valid_int64
(
int_part
,
dec_part
))
{
ret
=
OB_INVALID_DATE_FORMAT
;
LOG_WARN
(
"invalid date format"
,
K
(
ret
),
K
(
num
));
}
else
{
ObString
num_str
(
num_format
);
if
(
OB_FAIL
(
ObTimeConverter
::
str_to_ob_time_without_date
(
num_str
,
ob_time
)))
{
LOG_WARN
(
"str to obtime without date failed"
,
K
(
ret
));
if
(
OB_FAIL
(
ObTimeConverter
::
int_to_ob_time_without_date
(
int_part
,
ob_time
,
dec_part
)))
{
LOG_WARN
(
"int to ob time without date failed"
,
K
(
ret
));
}
else
{
int64_t
value
=
ObTimeConverter
::
ob_time_to_time
(
ob_time
);
int64_t
tmp_value
=
value
;
ObTimeConverter
::
time_overflow_trunc
(
value
);
if
(
value
!=
tmp_value
)
{
ObTimeConverter
::
time_to_ob_time
(
value
,
ob_time
);
if
((
!
ob_time
.
parts_
[
DT_YEAR
])
&&
(
!
ob_time
.
parts_
[
DT_MON
])
&&
(
!
ob_time
.
parts_
[
DT_MDAY
]))
{
//mysql中intTC转time时,如果超过838:59:59.999999,那么time应该为null,而不是最大值。
const
int64_t
time_max_val
=
TIME_MAX_VAL
+
999999
;
// 838:59:59.999999 .
int64_t
value
=
ObTimeConverter
::
ob_time_to_time
(
ob_time
);
if
(
value
>
time_max_val
)
{
ret
=
OB_INVALID_DATE_VALUE
;
}
}
}
}
...
...
src/sql/engine/expr/ob_expr_time.h
浏览文件 @
676c105d
...
...
@@ -116,8 +116,10 @@ inline int ObExprSecond::calc_result_type1(ObExprResType &type,
type
.
set_precision
(
4
);
type
.
set_scale
(
0
);
common
::
ObObjTypeClass
tc1
=
ob_obj_type_class
(
type1
.
get_type
());
if
((
common
::
ObEnumSetTC
==
tc1
)
||
(
common
::
ObFloatTC
==
tc1
)
||
(
common
::
ObDoubleTC
==
tc1
)
)
{
if
((
common
::
ObEnumSetTC
==
tc1
))
{
type1
.
set_calc_type_default_varchar
();
}
else
if
((
common
::
ObFloatTC
==
tc1
)
||
(
common
::
ObDoubleTC
==
tc1
))
{
type1
.
set_calc_type
(
common
::
ObNumberType
);
}
return
common
::
OB_SUCCESS
;
}
...
...
@@ -144,8 +146,10 @@ inline int ObExprMicrosecond::calc_result_type1(ObExprResType &type,
type
.
set_precision
(
4
);
type
.
set_scale
(
0
);
common
::
ObObjTypeClass
tc1
=
ob_obj_type_class
(
type1
.
get_type
());
if
((
common
::
ObEnumSetTC
==
tc1
)
||
(
common
::
ObFloatTC
==
tc1
)
||
(
common
::
ObDoubleTC
==
tc1
)
)
{
if
((
common
::
ObEnumSetTC
==
tc1
))
{
type1
.
set_calc_type_default_varchar
();
}
else
if
((
common
::
ObFloatTC
==
tc1
)
||
(
common
::
ObDoubleTC
==
tc1
))
{
type1
.
set_calc_type
(
common
::
ObNumberType
);
}
return
common
::
OB_SUCCESS
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录