Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
oceanbase
oceanbase
提交
00e1521f
O
oceanbase
项目概览
oceanbase
/
oceanbase
8 个月 前同步成功
通知
260
Star
6084
Fork
1301
代码
文件
提交
分支
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,体验更适合开发者的 AI 搜索 >>
提交
00e1521f
编写于
4月 18, 2024
作者:
H
hezuojiao
提交者:
ob-robot
4月 18, 2024
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix invalid enumset val in concurrent scenarios
上级
11f151f4
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
106 addition
and
7 deletion
+106
-7
src/sql/engine/expr/ob_datum_cast.cpp
src/sql/engine/expr/ob_datum_cast.cpp
+7
-2
src/sql/engine/expr/ob_expr_column_conv.cpp
src/sql/engine/expr/ob_expr_column_conv.cpp
+77
-5
src/sql/engine/expr/ob_expr_column_conv.h
src/sql/engine/expr/ob_expr_column_conv.h
+22
-0
未找到文件。
src/sql/engine/expr/ob_datum_cast.cpp
浏览文件 @
00e1521f
...
...
@@ -2783,9 +2783,14 @@ int cast_identity_enum_set(const sql::ObExpr &expr,
UNUSED(cast_mode);
UNUSED(str_values);
EVAL_ARG() {
res_datum.set_enum(child_res->get_enum());
if (ob_is_null(expr.args_[0]->datum_meta_.type_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("null type with non-null value", K(ret), K(child_res->get_enum()));
} else {
res_datum.set_enum(child_res->get_enum());
}
}
return
OB_SUCCESS
;
return
ret
;
}
int cast_not_support_enum_set(const sql::ObExpr &expr,
...
...
src/sql/engine/expr/ob_expr_column_conv.cpp
浏览文件 @
00e1521f
...
...
@@ -404,6 +404,25 @@ static inline int column_convert_datum_accuracy_check(const ObExpr &expr,
return
ret
;
}
int
enum_set_valid_check
(
const
uint64_t
val
,
const
int64_t
str_values_count
,
const
bool
is_enum
)
{
int
ret
=
common
::
OB_SUCCESS
;
if
(
OB_UNLIKELY
(
str_values_count
<=
0
))
{
ret
=
OB_ERR_UNEXPECTED
;
LOG_WARN
(
"unexpected str values count"
,
K
(
ret
),
K
(
str_values_count
),
K
(
is_enum
));
}
else
if
(
is_enum
&&
(
val
>
str_values_count
))
{
// ENUM type, its value should not exceed str_values_count
ret
=
OB_ERR_UNEXPECTED
;
LOG_WARN
(
"unexpected enum value"
,
K
(
ret
),
K
(
val
),
K
(
str_values_count
));
}
else
if
(
!
is_enum
&&
(
str_values_count
<
OB_MAX_SET_ELEMENT_NUM
)
&&
(
val
>=
(
1UL
<<
str_values_count
)))
{
// SET type, its value should not be greater than or equal to 2^(str_values_count)
ret
=
OB_ERR_UNEXPECTED
;
LOG_WARN
(
"unexpected set value"
,
K
(
ret
),
K
(
val
),
K
(
str_values_count
));
}
return
ret
;
}
int
ObExprColumnConv
::
column_convert
(
const
ObExpr
&
expr
,
ObEvalCtx
&
ctx
,
ObDatum
&
datum
)
...
...
@@ -420,12 +439,9 @@ int ObExprColumnConv::column_convert(const ObExpr &expr,
ObCollationType
out_cs_type
=
expr
.
datum_meta_
.
cs_type_
;
ObDatum
*
val
=
NULL
;
if
(
ob_is_enum_or_set_type
(
out_type
)
&&
!
expr
.
args_
[
4
]
->
obj_meta_
.
is_enum_or_set
())
{
ObExpr
*
old_expr
=
expr
.
args_
[
0
];
expr
.
args_
[
0
]
=
expr
.
args_
[
4
];
if
(
OB_FAIL
(
expr
.
eval_enumset
(
ctx
,
enumset_info
->
str_values_
,
cast_mode
,
val
)))
{
LOG_WARN
(
"fail to eval_enumset"
,
KPC
(
enumset_info
),
K
(
ret
));
if
(
OB_FAIL
(
eval_enumset
(
expr
,
ctx
,
val
)))
{
LOG_WARN
(
"fail to eval enumset result"
,
K
(
ret
));
}
expr
.
args_
[
0
]
=
old_expr
;
}
else
{
if
(
OB_FAIL
(
expr
.
args_
[
4
]
->
eval
(
ctx
,
val
)))
{
LOG_WARN
(
"evaluate parameter failed"
,
K
(
ret
));
...
...
@@ -448,6 +464,12 @@ int ObExprColumnConv::column_convert(const ObExpr &expr,
}
else
{
val
->
set_string
(
str
);
}
}
else
if
(
ob_is_enum_or_set_type
(
out_type
))
{
if
(
OB_FAIL
(
enum_set_valid_check
(
val
->
get_uint64
(),
enumset_info
->
str_values_
.
count
(),
(
expr
.
datum_meta_
.
type_
==
ObEnumType
))))
{
LOG_WARN
(
"enum set val is invalid"
,
K
(
ret
),
K
(
val
->
get_uint64
()),
K
(
enumset_info
->
str_values_
.
count
()),
K
(
expr
));
}
}
if
(
OB_SUCC
(
ret
)
&&
OB_FAIL
(
column_convert_datum_accuracy_check
(
expr
,
ctx
,
false
,
datum
,
cast_mode
,
*
val
)))
{
...
...
@@ -539,6 +561,56 @@ int ObExprColumnConv::column_convert(const ObExpr &expr,
return
ret
;
}
int
ObExprColumnConv
::
eval_enumset
(
const
ObExpr
&
expr
,
ObEvalCtx
&
ctx
,
common
::
ObDatum
*&
datum
)
{
int
ret
=
OB_SUCCESS
;
const
ObEnumSetInfo
*
enumset_info
=
static_cast
<
ObEnumSetInfo
*>
(
expr
.
extra_info_
);
const
uint64_t
cast_mode
=
enumset_info
->
cast_mode_
;
const
uint64_t
expr_ctx_id
=
static_cast
<
uint64_t
>
(
expr
.
expr_ctx_id_
);
if
(
OB_UNLIKELY
(
expr_ctx_id
==
ObExpr
::
INVALID_EXP_CTX_ID
))
{
ObExpr
*
old_expr
=
expr
.
args_
[
0
];
expr
.
args_
[
0
]
=
expr
.
args_
[
4
];
if
(
OB_FAIL
(
expr
.
eval_enumset
(
ctx
,
enumset_info
->
str_values_
,
cast_mode
,
datum
)))
{
LOG_WARN
(
"fail to eval_enumset"
,
KPC
(
enumset_info
),
K
(
ret
));
}
expr
.
args_
[
0
]
=
old_expr
;
}
else
{
ObExprColumnConvCtx
*
column_conv_ctx
=
NULL
;
if
(
OB_ISNULL
(
column_conv_ctx
=
static_cast
<
ObExprColumnConvCtx
*>
(
ctx
.
exec_ctx_
.
get_expr_op_ctx
(
expr_ctx_id
))))
{
if
(
OB_FAIL
(
ctx
.
exec_ctx_
.
create_expr_op_ctx
(
expr_ctx_id
,
column_conv_ctx
)))
{
LOG_WARN
(
"fail to create expr op ctx"
,
K
(
ret
),
K
(
expr_ctx_id
));
}
else
if
(
OB_FAIL
(
column_conv_ctx
->
setup_eval_expr
(
ctx
.
exec_ctx_
.
get_allocator
(),
expr
)))
{
LOG_WARN
(
"fail to init column conv ctx"
,
K
(
ret
));
}
}
if
(
OB_SUCC
(
ret
))
{
if
(
OB_FAIL
(
column_conv_ctx
->
expr_
.
eval_enumset
(
ctx
,
enumset_info
->
str_values_
,
cast_mode
,
datum
)))
{
LOG_WARN
(
"fail to eval_enumset"
,
KPC
(
enumset_info
),
K
(
ret
));
}
}
}
return
ret
;
}
int
ObExprColumnConv
::
ObExprColumnConvCtx
::
setup_eval_expr
(
ObIAllocator
&
allocator
,
const
ObExpr
&
expr
)
{
int
ret
=
OB_SUCCESS
;
const
int64_t
mem_size
=
sizeof
(
ObExpr
*
)
*
expr
.
arg_cnt_
;
if
(
OB_ISNULL
(
args_
=
static_cast
<
ObExpr
**>
(
allocator
.
alloc
(
mem_size
))))
{
ret
=
OB_ALLOCATE_MEMORY_FAILED
;
LOG_WARN
(
"fail to alloc args"
,
K
(
ret
),
K
(
mem_size
));
}
else
{
expr_
=
expr
;
expr_
.
args_
=
args_
;
MEMCPY
(
args_
,
expr
.
args_
,
mem_size
);
args_
[
0
]
=
args_
[
4
];
}
return
ret
;
}
//TODO(yaoying.yyy):(duplicate_with_type_to_str, remove later
int
ObBaseExprColumnConv
::
shallow_copy_str_values
(
const
common
::
ObIArray
<
common
::
ObString
>
&
str_values
)
{
...
...
src/sql/engine/expr/ob_expr_column_conv.h
浏览文件 @
00e1521f
...
...
@@ -92,6 +92,21 @@ public:
static
const
int64_t
PARAMS_COUNT_WITHOUT_COLUMN_INFO
=
5
;
static
const
int64_t
PARAMS_COUNT_WITH_COLUMN_INFO
=
6
;
class
ObExprColumnConvCtx
:
public
ObExprOperatorCtx
{
public:
ObExprColumnConvCtx
()
:
ObExprOperatorCtx
(),
expr_
(),
args_
(
NULL
)
{}
int
setup_eval_expr
(
ObIAllocator
&
allocator
,
const
ObExpr
&
expr
);
TO_STRING_KV
(
K_
(
expr
));
ObExpr
expr_
;
ObExpr
**
args_
;
};
public:
explicit
ObExprColumnConv
(
common
::
ObIAllocator
&
alloc
);
virtual
~
ObExprColumnConv
();
...
...
@@ -119,6 +134,13 @@ public:
static
int
column_convert
(
const
ObExpr
&
expr
,
ObEvalCtx
&
ctx
,
ObDatum
&
datum
);
virtual
bool
need_rt_ctx
()
const
override
{
return
ob_is_enum_or_set_type
(
result_type_
.
get_type
());
}
private:
static
int
eval_enumset
(
const
ObExpr
&
expr
,
ObEvalCtx
&
ctx
,
common
::
ObDatum
*&
datum
);
private:
// disallow copy
DISALLOW_COPY_AND_ASSIGN
(
ObExprColumnConv
)
const
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录