Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
大炮V587
oceanbase
提交
25b02ac3
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,发现更多精彩内容 >>
提交
25b02ac3
编写于
12月 12, 2022
作者:
L
Larry955
提交者:
ob-robot
1月 12, 2023
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix parallel var assign bug
上级
30421352
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
205 addition
and
136 deletion
+205
-136
src/sql/optimizer/ob_join_order.cpp
src/sql/optimizer/ob_join_order.cpp
+2
-1
src/sql/optimizer/ob_log_operator_factory.h
src/sql/optimizer/ob_log_operator_factory.h
+0
-33
src/sql/optimizer/ob_log_plan.cpp
src/sql/optimizer/ob_log_plan.cpp
+3
-0
src/sql/optimizer/ob_logical_operator.cpp
src/sql/optimizer/ob_logical_operator.cpp
+28
-19
src/sql/optimizer/ob_logical_operator.h
src/sql/optimizer/ob_logical_operator.h
+1
-2
src/sql/optimizer/ob_optimizer.cpp
src/sql/optimizer/ob_optimizer.cpp
+52
-44
src/sql/optimizer/ob_optimizer.h
src/sql/optimizer/ob_optimizer.h
+4
-3
src/sql/optimizer/ob_optimizer_context.h
src/sql/optimizer/ob_optimizer_context.h
+9
-1
src/sql/optimizer/ob_select_log_plan.cpp
src/sql/optimizer/ob_select_log_plan.cpp
+9
-1
src/sql/resolver/dml/ob_dml_stmt.cpp
src/sql/resolver/dml/ob_dml_stmt.cpp
+91
-28
src/sql/resolver/dml/ob_dml_stmt.h
src/sql/resolver/dml/ob_dml_stmt.h
+6
-4
未找到文件。
src/sql/optimizer/ob_join_order.cpp
浏览文件 @
25b02ac3
...
...
@@ -9074,7 +9074,8 @@ int ObJoinOrder::get_valid_path_info(const ObJoinOrder &left_tree,
if (OB_FAIL(ret)) {
/*do nothing*/
} else {
if (get_cnt_rownum()) {
if (get_cnt_rownum() ||
(!opt_ctx.is_var_assign_only_in_root_stmt() && opt_ctx.has_var_assign())) {
path_info.distributed_methods_ &= DIST_PULL_TO_LOCAL | DIST_BASIC_METHOD;
}
if (IS_LEFT_STYLE_JOIN(path_info.join_type_)) {
...
...
src/sql/optimizer/ob_log_operator_factory.h
浏览文件 @
25b02ac3
...
...
@@ -201,39 +201,6 @@ enum class WinDistAlgo
LIST
=
3
// range + random distribute
};
#define ADD_DIST_METHOD_WITHOUT_BC2HOST(method) \
do {add_join_dist_flag(method, DIST_PULL_TO_LOCAL); \
add_join_dist_flag(method, DIST_HASH_HASH); \
add_join_dist_flag(method, DIST_BROADCAST_NONE); \
add_join_dist_flag(method, DIST_NONE_BROADCAST); \
add_join_dist_flag(method, DIST_PARTITION_NONE); \
add_join_dist_flag(method, DIST_NONE_PARTITION); \
add_join_dist_flag(method, DIST_PARTITION_WISE); \
} while(0);
#define REMOVE_PX_SPECIFIC_DIST_METHOD(method) \
do {remove_join_dist_flag(method, DIST_HASH_HASH); \
remove_join_dist_flag(method, DIST_BROADCAST_NONE); \
remove_join_dist_flag(method, DIST_NONE_BROADCAST); \
remove_join_dist_flag(method, DIST_BC2HOST_NONE); \
remove_join_dist_flag(method, DIST_NONE_RANDOM); \
remove_join_dist_flag(method, DIST_RANDOM_NONE); \
} while(0);
#define UPDATE_CURRENT_JOIN_DIST_METHOD(method, cost, v_method, v_cost) \
do { if ((DIST_INVALID_METHOD == method || cost > v_cost) && 0 != v_method) { \
method = v_method; \
cost = v_cost;} \
} while(0);
#define REMOVE_PX_PARALLEL_DFO_DIST_METHOD(method) \
do {remove_join_dist_flag(method, DIST_HASH_HASH); \
remove_join_dist_flag(method, DIST_BROADCAST_NONE); \
remove_join_dist_flag(method, DIST_NONE_BROADCAST); \
remove_join_dist_flag(method, DIST_NONE_RANDOM); \
remove_join_dist_flag(method, DIST_RANDOM_NONE); \
} while(0);
class
ObLogPlan
;
class
ObLogOperatorFactory
{
...
...
src/sql/optimizer/ob_log_plan.cpp
浏览文件 @
25b02ac3
...
...
@@ -8670,6 +8670,9 @@ int ObLogPlan::create_subplan_filter_plan(ObLogicalOperator *&top,
LOG_WARN("failed to check whether contains recursive cte", K(ret));
} else if (is_recursive_cte) {
dist_algo = DistAlgo::DIST_PULL_TO_LOCAL;
} else if (!get_optimizer_context().is_var_assign_only_in_root_stmt() &&
get_optimizer_context().has_var_assign()) {
dist_algo = DistAlgo::DIST_PULL_TO_LOCAL;
} else if (OB_FAIL(check_if_subplan_filter_match_partition_wise(top,
subquery_ops,
params,
...
...
src/sql/optimizer/ob_logical_operator.cpp
浏览文件 @
25b02ac3
...
...
@@ -3742,22 +3742,25 @@ int ObLogicalOperator::adjust_plan_root_output_exprs()
}
else
if
(
output_exprs_
.
empty
())
{
/*do nothing*/
}
else
if
(
stmt
->
is_select_stmt
()
&&
FALSE_IT
(
into_item
=
static_cast
<
const
ObSelectStmt
*>
(
get_stmt
()
)
->
get_select_into
()))
{
FALSE_IT
(
into_item
=
static_cast
<
const
ObSelectStmt
*>
(
stmt
)
->
get_select_into
()))
{
/*do nothing*/
}
else
if
(
NULL
==
get_parent
()
&&
NULL
!=
into_item
&&
T_INTO_OUTFILE
==
into_item
->
into_type_
)
{
if
(
OB_FAIL
(
build_and_put_into_outfile_expr
(
into_item
,
output_exprs_
)))
{
LOG_WARN
(
"failed to add into outfile expr to ctx"
,
K
(
ret
));
}
else
{
LOG_TRACE
(
"succeed to add into outfile expr to ctx"
,
K
(
ret
));
}
}
else
if
(
NULL
==
get_parent
()
&&
check_stmt_can_be_packed
(
stmt
))
{
if
(
OB_FAIL
(
build_and_put_pack_expr
(
output_exprs_
)))
{
LOG_WARN
(
"failed to add pack expr to context"
,
K
(
ret
));
}
else
if
(
NULL
==
get_parent
())
{
if
(
NULL
!=
into_item
&&
T_INTO_OUTFILE
==
into_item
->
into_type_
)
{
if
(
OB_FAIL
(
build_and_put_into_outfile_expr
(
into_item
,
output_exprs_
)))
{
LOG_WARN
(
"failed to add into outfile expr to ctx"
,
K
(
ret
));
}
else
{
LOG_TRACE
(
"succeed to add into outfile expr to ctx"
,
K
(
ret
));
}
}
else
{
LOG_TRACE
(
"succeed to add plan root output exprs"
,
K
(
output_exprs_
));
bool
need_pack
=
false
;
if
(
OB_FAIL
(
check_stmt_can_be_packed
(
stmt
,
need_pack
)))
{
LOG_WARN
(
"failed to check stmt can be pack"
,
K
(
ret
));
}
else
if
(
need_pack
&&
OB_FAIL
(
build_and_put_pack_expr
(
output_exprs_
)))
{
LOG_WARN
(
"failed to add pack expr to context"
,
K
(
ret
));
}
}
}
else
{
/*do nothing*/
}
LOG_TRACE
(
"succeed to adjust plan root output exprs"
,
K
(
output_exprs_
));
}
return
ret
;
}
...
...
@@ -3784,16 +3787,22 @@ int ObLogicalOperator::set_plan_root_output_exprs()
return
ret
;
}
bool
ObLogicalOperator
::
check_stmt_can_be_packed
(
const
ObDMLStmt
*
stmt
)
int
ObLogicalOperator
::
check_stmt_can_be_packed
(
const
ObDMLStmt
*
stmt
,
bool
&
need_pack
)
{
bool
need_pack
=
false
;
int
ret
=
OB_SUCCESS
;
need_pack
=
false
;
ObSQLSessionInfo
*
session_info
=
NULL
;
if
(
NULL
!=
stmt
&&
NULL
!=
get_plan
()
&&
NULL
!=
(
session_info
=
get_plan
()
->
get_optimizer_context
().
get_session_info
()))
{
if
(
OB_ISNULL
(
stmt
)
||
OB_ISNULL
(
get_plan
())
||
OB_ISNULL
(
session_info
=
get_plan
()
->
get_optimizer_context
().
get_session_info
()))
{
ret
=
OB_ERR_UNEXPECTED
;
LOG_WARN
(
"get unexpected null"
,
K
(
ret
));
}
else
{
bool
has_var_assign
=
get_plan
()
->
get_optimizer_context
().
has_var_assign
();
bool
is_var_assign_only_in_root
=
get_plan
()
->
get_optimizer_context
().
is_var_assign_only_in_root_stmt
();
need_pack
=
stmt
->
is_select_stmt
()
&&
(
!
session_info
->
is_inner
())
&&
LOG_EXCHANGE
==
type_
&&
(
ObPhyPlanType
::
OB_PHY_PLAN_DISTRIBUTED
==
get_phy_plan_type
());
&&
(
ObPhyPlanType
::
OB_PHY_PLAN_DISTRIBUTED
==
get_phy_plan_type
())
&&
!
has_var_assign
;
}
return
need_pack
;
return
ret
;
}
int
ObLogicalOperator
::
replace_generated_agg_expr
(
...
...
src/sql/optimizer/ob_logical_operator.h
浏览文件 @
25b02ac3
...
...
@@ -769,7 +769,6 @@ public:
static
const
int64_t
second_child
=
1
;
static
const
int64_t
third_child
=
2
;
static
const
int64_t
fourth_child
=
3
;
static
const
int64_t
SEQUENTIAL_EXECUTION_THRESHOLD
=
1000
;
ObLogicalOperator
(
ObLogPlan
&
plan
);
virtual
~
ObLogicalOperator
();
...
...
@@ -1480,7 +1479,7 @@ public:
inline
const
ObShardingInfo
*
get_strong_sharding
()
const
{
return
strong_sharding_
;
}
inline
void
set_strong_sharding
(
ObShardingInfo
*
strong_sharding
)
{
strong_sharding_
=
strong_sharding
;
}
bool
check_stmt_can_be_packed
(
const
ObDMLStmt
*
stmt
);
int
check_stmt_can_be_packed
(
const
ObDMLStmt
*
stmt
,
bool
&
need_pack
);
inline
ObIArray
<
ObShardingInfo
*>
&
get_weak_sharding
()
{
return
weak_sharding_
;
}
inline
const
ObIArray
<
ObShardingInfo
*>
&
get_weak_sharding
()
const
{
return
weak_sharding_
;
}
...
...
src/sql/optimizer/ob_optimizer.cpp
浏览文件 @
25b02ac3
...
...
@@ -240,48 +240,56 @@ bool ObOptimizer::exists_temp_table(const ObIArray<ObSqlTempTableInfo*> &temp_ta
return
bret
;
}
// max_table_hint used for parallelism at the statement or object level
int
ObOptimizer
::
get_stmt_max_table_parallel_hint
(
ObDMLStmt
&
stmt
,
int64_t
&
max_table_hint
)
/**
* @brief Get the attr from stmt recursively object
*
* @param stmt
* @param max_dop used for table's parallel attribute
* @param max_table_parallel used for parallelism at the statement or object level
* @return int
*/
int
ObOptimizer
::
get_stmt_parallel_info
(
ObDMLStmt
*
stmt
,
int64_t
&
max_table_dop
,
int64_t
&
max_table_parallel
)
{
int
ret
=
OB_SUCCESS
;
ObSEArray
<
ObSelectStmt
*
,
4
>
child_stmts
;
ObQueryCtx
*
query_ctx
=
NULL
;
int64_t
cur_max_table_hint
=
ObGlobalHint
::
UNSET_PARALLEL
;
if
(
OB_FAIL
(
stmt
.
get_stmt_hint
().
get_max_table_parallel
(
stmt
,
cur_max_table_hint
)))
{
if
(
OB_ISNULL
(
stmt
))
{
ret
=
OB_ERR_UNEXPECTED
;
LOG_WARN
(
"get unexpected null"
,
K
(
ret
));
}
else
if
(
OB_FAIL
(
stmt
->
get_child_stmts
(
child_stmts
)))
{
LOG_WARN
(
"failed to get child stmt"
,
K
(
ret
));
}
else
if
(
OB_FAIL
(
SMART_CALL
(
get_stmt_max_table_dop
(
*
stmt
,
max_table_dop
))))
{
LOG_WARN
(
"failed to get stmt max table dop"
,
K
(
ret
));
}
else
if
(
OB_FAIL
(
stmt
->
get_stmt_hint
().
get_max_table_parallel
(
*
stmt
,
cur_max_table_hint
)))
{
LOG_WARN
(
"failed to get max table parallel"
,
K
(
ret
));
}
else
if
(
OB_FAIL
(
stmt
.
get_child_stmts
(
child_stmts
)))
{
LOG_WARN
(
"failed to get child stmts"
,
K
(
ret
));
}
else
{
max_table_hint
=
std
::
max
(
max_table_hint
,
cur_max_table_hint
);
}
for
(
int64_t
i
=
0
;
OB_SUCC
(
ret
)
&&
i
<
child_stmts
.
count
();
i
++
)
{
if
(
OB_ISNULL
(
child_stmts
.
at
(
i
)))
{
ret
=
OB_ERR_UNEXPECTED
;
LOG_WARN
(
"get unexpected null"
,
K
(
ret
));
}
else
if
(
OB_FAIL
(
SMART_CALL
(
get_stmt_max_table_parallel_hint
(
*
child_stmts
.
at
(
i
),
max_table_hint
))))
{
LOG_WARN
(
"failed to get stmt max table dop"
,
K
(
ret
));
}
else
{
/*do nothing*/
}
max_table_parallel
=
std
::
max
(
max_table_parallel
,
cur_max_table_hint
);
for
(
int64_t
i
=
0
;
OB_SUCC
(
ret
)
&&
i
<
child_stmts
.
count
();
i
++
)
{
if
(
OB_ISNULL
(
child_stmts
.
at
(
i
)))
{
ret
=
OB_ERR_UNEXPECTED
;
LOG_WARN
(
"get unexpected null"
,
K
(
ret
));
}
else
if
(
OB_FAIL
(
SMART_CALL
(
get_stmt_parallel_info
(
child_stmts
.
at
(
i
),
max_table_dop
,
max_table_parallel
))))
{
LOG_WARN
(
"failed to get stmt max table dop"
,
K
(
ret
));
}
else
{
/*do nothing*/
}
}
}
return
ret
;
}
// max_table_dop used for table's parallel attribute
int
ObOptimizer
::
get_stmt_max_table_dop
(
ObDMLStmt
&
stmt
,
int64_t
&
max_table_dop
)
{
int
ret
=
OB_SUCCESS
;
ObSEArray
<
ObSelectStmt
*
,
4
>
child_stmts
;
ObQueryCtx
*
query_ctx
=
NULL
;
ObSQLSessionInfo
*
session_info
=
NULL
;
share
::
schema
::
ObSchemaGetterGuard
*
schema_guard
=
ctx_
.
get_schema_guard
();
if
(
OB_ISNULL
(
schema_guard
)
||
OB_ISNULL
(
query_ctx
=
ctx_
.
get_query_ctx
())
||
if
(
OB_ISNULL
(
schema_guard
)
||
OB_ISNULL
(
session_info
=
ctx_
.
get_session_info
()))
{
ret
=
OB_ERR_UNEXPECTED
;
LOG_WARN
(
"get unexpected null"
,
K
(
schema_guard
),
K
(
query_ctx
),
K
(
session_info
),
K
(
ret
));
}
else
if
(
OB_FAIL
(
stmt
.
get_child_stmts
(
child_stmts
)))
{
LOG_WARN
(
"failed to get child stmts"
,
K
(
ret
));
LOG_WARN
(
"get unexpected null"
,
K
(
schema_guard
),
K
(
session_info
),
K
(
ret
));
}
else
{
for
(
int64_t
i
=
0
;
OB_SUCC
(
ret
)
&&
i
<
stmt
.
get_table_items
().
count
();
i
++
)
{
TableItem
*
table_item
=
NULL
;
...
...
@@ -294,8 +302,8 @@ int ObOptimizer::get_stmt_max_table_dop(ObDMLStmt &stmt,
table_item
->
is_fake_cte_table
()
||
table_item
->
is_joined_table
())
{
}
else
if
(
table_item
->
is_temp_table
())
{
if
(
OB_FAIL
(
child_stmts
.
push_back
(
table_item
->
ref_query_
)))
{
LOG_WARN
(
"
push back failed
"
,
K
(
ret
));
if
(
OB_FAIL
(
SMART_CALL
(
get_stmt_max_table_dop
(
*
table_item
->
ref_query_
,
max_table_dop
)
)))
{
LOG_WARN
(
"
failed to get max table dop from ref query
"
,
K
(
ret
));
}
}
else
if
(
table_item
->
is_generated_table
())
{
}
else
{
...
...
@@ -332,15 +340,6 @@ int ObOptimizer::get_stmt_max_table_dop(ObDMLStmt &stmt,
}
}
}
for
(
int64_t
i
=
0
;
OB_SUCC
(
ret
)
&&
i
<
child_stmts
.
count
();
i
++
)
{
if
(
OB_ISNULL
(
child_stmts
.
at
(
i
)))
{
ret
=
OB_ERR_UNEXPECTED
;
LOG_WARN
(
"get unexpected null"
,
K
(
ret
));
}
else
if
(
OB_FAIL
(
SMART_CALL
(
get_stmt_max_table_dop
(
*
child_stmts
.
at
(
i
),
max_table_dop
))))
{
LOG_WARN
(
"failed to get stmt max table dop"
,
K
(
ret
));
}
else
{
/*do nothing*/
}
}
}
return
ret
;
}
...
...
@@ -570,6 +569,9 @@ int ObOptimizer::check_pdml_supported_feature(const ObDMLStmt &stmt,
LOG_WARN
(
"a online ddl expect PDML enabled. but it does not!"
,
K
(
is_use_pdml
),
K
(
ret
));
LOG_USER_ERROR
(
OB_NOT_SUPPORTED
,
"online ddl without pdml"
);
}
if
(
OB_SUCC
(
ret
)
&&
ctx_
.
has_var_assign
()
&&
!
ctx_
.
is_var_assign_only_in_root_stmt
())
{
is_use_pdml
=
false
;
}
LOG_TRACE
(
"check use all pdml feature"
,
K
(
ret
),
K
(
is_use_pdml
),
K
(
ctx_
.
is_online_ddl
()));
return
ret
;
}
...
...
@@ -611,7 +613,11 @@ int ObOptimizer::init_env_info(ObDMLStmt &stmt)
int64_t
parallel
=
1
;
bool
use_pdml
=
false
;
bool
session_enable_parallel
=
false
;
bool
has_var_assign
=
false
;
bool
is_var_assign_only_in_root_stmt
=
false
;
uint64_t
session_force_parallel_dop
=
1
;
int64_t
max_table_dop
=
1
;
int64_t
max_table_hint
=
1
;
ObDMLStmt
*
target_stmt
=
&
stmt
;
ObSQLSessionInfo
*
session
=
ctx_
.
get_session_info
();
if
(
OB_ISNULL
(
target_stmt
)
||
OB_ISNULL
(
session
))
{
...
...
@@ -620,6 +626,16 @@ int ObOptimizer::init_env_info(ObDMLStmt &stmt)
}
else
if
(
FALSE_IT
(
ctx_
.
set_is_online_ddl
(
session
->
get_ddl_info
().
is_ddl
())))
{
}
else
if
(
OB_FAIL
(
check_whether_contain_nested_sql
(
stmt
)))
{
LOG_WARN
(
"check whether contain nested sql failed"
,
K
(
ret
));
}
else
if
(
OB_FAIL
(
get_stmt_parallel_info
(
target_stmt
,
max_table_dop
,
max_table_hint
)))
{
LOG_WARN
(
"failed to get attributes from stmt"
,
K
(
ret
));
}
else
if
(
OB_FAIL
(
target_stmt
->
check_var_assign
(
has_var_assign
,
is_var_assign_only_in_root_stmt
)))
{
LOG_WARN
(
"failed to check has ref assign user var"
,
K
(
ret
));
}
else
if
(
OB_FALSE_IT
(
ctx_
.
set_has_var_assign
(
has_var_assign
))
||
OB_FALSE_IT
(
ctx_
.
set_is_var_assign_only_in_root_stmt
(
is_var_assign_only_in_root_stmt
)))
{
// do nothing
}
else
if
(
OB_FAIL
(
check_pdml_enabled
(
*
target_stmt
,
*
session
,
use_pdml
)))
{
LOG_WARN
(
"fail to check enable pdml"
,
K
(
ret
));
}
else
if
(
OB_FAIL
(
get_session_parallel_info
(
*
target_stmt
,
...
...
@@ -634,15 +650,7 @@ int ObOptimizer::init_env_info(ObDMLStmt &stmt)
}
ctx_
.
set_parallel
(
parallel
);
ctx_
.
set_use_pdml
(
use_pdml
);
int64_t
max_table_dop
=
1
;
int64_t
max_table_hint
=
1
;
if
(
OB_FAIL
(
get_stmt_max_table_dop
(
*
target_stmt
,
max_table_dop
)))
{
LOG_WARN
(
"failed to get stmt max table dop"
,
K
(
ret
));
}
else
if
(
OB_FAIL
(
get_stmt_max_table_parallel_hint
(
*
target_stmt
,
max_table_hint
)))
{
LOG_WARN
(
"failed to get stmt max table parallel"
,
K
(
ret
));
}
else
if
(
ctx_
.
get_global_hint
().
get_parallel_hint
()
!=
ObGlobalHint
::
UNSET_PARALLEL
)
{
if
(
ctx_
.
get_global_hint
().
get_parallel_hint
()
!=
ObGlobalHint
::
UNSET_PARALLEL
)
{
ctx_
.
set_parallel_rule
(
PXParallelRule
::
MANUAL_HINT
);
ctx_
.
set_parallel
(
parallel
);
ctx_
.
add_plan_note
(
PARALLEL_ENABLED_BY_GLOBAL_HINT
,
parallel
);
...
...
src/sql/optimizer/ob_optimizer.h
浏览文件 @
25b02ac3
...
...
@@ -204,9 +204,10 @@ namespace sql
const
ObSelectStmt
*
table_query
)
const
;
int
init_env_info
(
ObDMLStmt
&
stmt
);
int
get_stmt_max_table_dop
(
ObDMLStmt
&
stmt
,
int64_t
&
max_dop
);
int
get_stmt_max_table_parallel_hint
(
ObDMLStmt
&
stmt
,
int64_t
&
max_table_parallel
);
int64_t
&
max_table_dop
);
int
get_stmt_parallel_info
(
ObDMLStmt
*
stmt
,
int64_t
&
max_table_dop
,
int64_t
&
max_table_parallel
);
int
get_session_parallel_info
(
ObDMLStmt
&
stmt
,
bool
use_pdml
,
bool
&
session_px_enable_parallel
,
...
...
src/sql/optimizer/ob_optimizer_context.h
浏览文件 @
25b02ac3
...
...
@@ -146,7 +146,9 @@ ObOptimizerContext(ObSQLSessionInfo *session_info,
aggregation_optimization_settings_
(
0
),
query_ctx_
(
query_ctx
),
nested_sql_flags_
(
0
),
has_for_update_
(
false
)
has_for_update_
(
false
),
has_var_assign_
(
false
),
is_var_assign_only_in_root_stmt_
(
false
)
{
}
inline
common
::
ObOptStatManager
*
get_opt_stat_manager
()
{
return
opt_stat_manager_
;
}
inline
void
set_opt_stat_manager
(
common
::
ObOptStatManager
*
sm
)
{
opt_stat_manager_
=
sm
;
}
...
...
@@ -462,6 +464,10 @@ ObOptimizerContext(ObSQLSessionInfo *session_info,
bool
contain_user_nested_sql
()
const
{
return
nested_sql_flags_
>
0
&&
!
is_online_ddl_
;
}
void
set_for_update
()
{
has_for_update_
=
true
;
}
bool
has_for_update
()
{
return
has_for_update_
;};
inline
bool
has_var_assign
()
{
return
has_var_assign_
;
}
inline
void
set_has_var_assign
(
bool
v
)
{
has_var_assign_
=
v
;
}
inline
bool
is_var_assign_only_in_root_stmt
()
{
return
is_var_assign_only_in_root_stmt_
;
}
inline
void
set_is_var_assign_only_in_root_stmt
(
bool
v
)
{
is_var_assign_only_in_root_stmt_
=
v
;
}
private:
ObSQLSessionInfo
*
session_info_
;
...
...
@@ -529,6 +535,8 @@ private:
};
};
bool
has_for_update_
;
bool
has_var_assign_
;
bool
is_var_assign_only_in_root_stmt_
;
};
}
}
...
...
src/sql/optimizer/ob_select_log_plan.cpp
浏览文件 @
25b02ac3
...
...
@@ -1888,6 +1888,11 @@ int ObSelectLogPlan::create_union_all_plan(const ObIArray<ObLogicalOperator*> &c
|
DistAlgo
::
DIST_PARTITION_WISE
|
DistAlgo
::
DIST_PULL_TO_LOCAL
|
DistAlgo
::
DIST_SET_RANDOM
;
if
(
!
get_optimizer_context
().
is_var_assign_only_in_root_stmt
()
&&
get_optimizer_context
().
has_var_assign
())
{
set_dist_methods
&=
DistAlgo
::
DIST_PULL_TO_LOCAL
|
DistAlgo
::
DIST_BASIC_METHOD
;
}
int64_t
random_none_idx
=
OB_INVALID_INDEX
;
DistAlgo
hint_dist_methods
=
get_log_plan_hint
().
get_valid_set_dist_algo
(
&
random_none_idx
);
if
(
!
ignore_hint
&&
DistAlgo
::
DIST_INVALID_METHOD
!=
hint_dist_methods
)
{
...
...
@@ -2482,7 +2487,10 @@ int ObSelectLogPlan::get_distributed_set_methods(const EqualSets &equal_sets,
}
}
}
if
(
OB_SUCC
(
ret
)
&&
!
get_optimizer_context
().
is_var_assign_only_in_root_stmt
()
&&
get_optimizer_context
().
has_var_assign
())
{
set_dist_methods
&=
DIST_PULL_TO_LOCAL
|
DIST_BASIC_METHOD
;
}
if
(
OB_SUCC
(
ret
)
&&
(
set_dist_methods
&
DistAlgo
::
DIST_NONE_ALL
))
{
if
(
left_sharding
->
is_distributed
()
&&
right_sharding
->
is_match_all
()
&&
!
right_child
.
get_contains_das_op
()
&&
!
right_child
.
get_contains_fake_cte
()
&&
...
...
src/sql/resolver/dml/ob_dml_stmt.cpp
浏览文件 @
25b02ac3
...
...
@@ -3889,14 +3889,10 @@ int ObDMLStmt::inner_get_share_exprs(ObIArray<ObRawExpr *> &candi_share_exprs) c
return
ret
;
}
/**
* has_ref_assign_user_var
* 检查stmt及其child stmt中是否包含涉及到赋值操作的用户变量
*/
int
ObDMLStmt
::
has_ref_assign_user_var
(
bool
&
has_ref_user_var
)
const
int
ObDMLStmt
::
find_var_assign_in_query_ctx
(
bool
&
is_found
)
const
{
int
ret
=
OB_SUCCESS
;
has_ref_user_var
=
false
;
is_found
=
false
;
if
(
OB_ISNULL
(
query_ctx_
))
{
ret
=
OB_ERR_UNEXPECTED
;
LOG_WARN
(
"get unexpected null"
,
K
(
ret
));
...
...
@@ -3904,58 +3900,125 @@ int ObDMLStmt::has_ref_assign_user_var(bool &has_ref_user_var) const
// do nothing
}
else
{
// quick check
bool
find
=
false
;
for
(
int64_t
i
=
0
;
OB_SUCC
(
ret
)
&&
!
find
&&
i
<
query_ctx_
->
all_user_variable_
.
count
();
++
i
)
{
for
(
int64_t
i
=
0
;
OB_SUCC
(
ret
)
&&
!
is_found
&&
i
<
query_ctx_
->
all_user_variable_
.
count
();
++
i
)
{
const
ObUserVarIdentRawExpr
*
cur_expr
=
query_ctx_
->
all_user_variable_
.
at
(
i
);
if
(
OB_ISNULL
(
cur_expr
))
{
ret
=
OB_ERR_UNEXPECTED
;
LOG_WARN
(
"get null expr"
,
K
(
ret
));
}
else
if
(
cur_expr
->
get_is_contain_assign
()
||
cur_expr
->
get_query_has_udf
())
{
fi
nd
=
true
;
is_fou
nd
=
true
;
}
}
}
return
ret
;
}
if
(
OB_SUCC
(
ret
)){
if
(
!
find
)
{
// no user variable assignment in query
}
else
if
(
OB_FAIL
(
recursive_check_has_ref_assign_user_var
(
has_ref_user_var
)))
{
LOG_WARN
(
"failed to recursive check has assignment ref user var"
,
K
(
ret
));
/**
* @brief
*
* @param has_var_assign check if has var assign expr
* @param need_check_child need to check child stmt
* @return int
*/
int
ObDMLStmt
::
has_ref_assign_user_var
(
bool
&
has_var_assign
,
bool
need_check_child
)
const
{
int
ret
=
OB_SUCCESS
;
has_var_assign
=
false
;
bool
find
=
false
;
if
(
OB_FAIL
(
find_var_assign_in_query_ctx
(
find
)))
{
LOG_WARN
(
"failed to find var assign"
,
K
(
ret
));
}
else
if
(
!
find
)
{
// no user variable assignment in query
}
else
if
(
OB_FAIL
(
check_has_var_assign_rec
(
has_var_assign
,
need_check_child
)))
{
LOG_WARN
(
"failed to recursive check has assignment ref user var"
,
K
(
ret
));
}
return
ret
;
}
int
ObDMLStmt
::
check_has_var_assign_rec
(
bool
&
has_var_assign
,
bool
need_check_child
)
const
{
int
ret
=
OB_SUCCESS
;
if
(
OB_FAIL
(
check_user_vars_has_var_assign
(
has_var_assign
)))
{
LOG_WARN
(
"failed to check user vars has var assign expr"
,
K
(
ret
));
}
else
if
(
!
has_var_assign
&&
need_check_child
)
{
ObSEArray
<
ObSelectStmt
*
,
4
>
child_stmts
;
if
(
OB_FAIL
(
get_child_stmts
(
child_stmts
)))
{
LOG_WARN
(
"failed to get child stmts"
,
K
(
ret
));
}
else
{
for
(
int64_t
i
=
0
;
OB_SUCC
(
ret
)
&&
!
has_var_assign
&&
i
<
child_stmts
.
count
();
++
i
)
{
if
(
OB_ISNULL
(
child_stmts
.
at
(
i
)))
{
ret
=
OB_ERR_UNEXPECTED
;
LOG_WARN
(
"get unexpected null"
,
K
(
ret
));
}
else
if
(
OB_FAIL
(
SMART_CALL
(
child_stmts
.
at
(
i
)
->
check_has_var_assign_rec
(
has_var_assign
,
need_check_child
))))
{
LOG_WARN
(
"failed to recursive check has assignment ref user var"
,
K
(
ret
));
}
}
}
}
return
ret
;
}
int
ObDMLStmt
::
recursive_check_has_ref_assign_user_var
(
bool
&
has_ref_user_var
)
const
int
ObDMLStmt
::
check_user_vars_has_var_assign
(
bool
&
has_var_assign
)
const
{
int
ret
=
OB_SUCCESS
;
bool
is_stack_overflow
=
false
;
has_ref_user_var
=
false
;
if
(
OB_FAIL
(
check_stack_overflow
(
is_stack_overflow
)))
{
LOG_WARN
(
"failed to check stack overflow"
,
K
(
ret
));
}
else
if
(
is_stack_overflow
)
{
ret
=
OB_SIZE_OVERFLOW
;
LOG_WARN
(
"too deep recursive"
,
K
(
ret
),
K
(
is_stack_overflow
));
}
for
(
int64_t
i
=
0
;
OB_SUCC
(
ret
)
&&
!
has_ref_user_var
&&
i
<
get_user_var_size
();
++
i
)
{
for
(
int64_t
i
=
0
;
OB_SUCC
(
ret
)
&&
!
has_var_assign
&&
i
<
get_user_var_size
();
++
i
)
{
const
ObUserVarIdentRawExpr
*
cur_expr
=
get_user_vars
().
at
(
i
);
if
(
OB_ISNULL
(
cur_expr
))
{
ret
=
OB_ERR_UNEXPECTED
;
LOG_WARN
(
"get null expr"
,
K
(
ret
));
}
else
if
(
cur_expr
->
get_is_contain_assign
()
||
cur_expr
->
get_query_has_udf
())
{
has_
ref_user_var
=
true
;
has_
var_assign
=
true
;
}
}
if
(
OB_SUCC
(
ret
)
&&
!
has_ref_user_var
)
{
return
ret
;
}
/**
* @brief
* this stmt should be root stmt
* @param has_var_assign check has var assign in root stmt
* @param is_var_assign_only_in_root check if var assign expr only existed in root stmt
* @return int
*/
int
ObDMLStmt
::
check_var_assign
(
bool
&
has_var_assign
,
bool
&
is_var_assign_only_in_root
)
const
{
int
ret
=
OB_SUCCESS
;
has_var_assign
=
false
;
is_var_assign_only_in_root
=
false
;
bool
find
=
false
;
if
(
OB_FAIL
(
find_var_assign_in_query_ctx
(
find
)))
{
LOG_WARN
(
"failed to find var assign"
,
K
(
ret
));
}
else
if
(
!
find
)
{
// no user variable assignment in query
}
else
if
(
OB_FAIL
(
check_has_var_assign_rec
(
has_var_assign
,
is_var_assign_only_in_root
,
true
)))
{
LOG_WARN
(
"failed to recursive check has assignment ref user var"
,
K
(
ret
));
}
return
ret
;
}
int
ObDMLStmt
::
check_has_var_assign_rec
(
bool
&
has_var_assign
,
bool
&
is_var_assign_only_in_root
,
bool
is_root
)
const
{
int
ret
=
OB_SUCCESS
;
bool
tmp_has_var_assign
=
false
;
if
(
OB_FAIL
(
check_user_vars_has_var_assign
(
tmp_has_var_assign
)))
{
LOG_WARN
(
"failed to check user vars has var assign expr"
,
K
(
ret
));
}
else
if
(
tmp_has_var_assign
)
{
has_var_assign
=
true
;
is_var_assign_only_in_root
=
is_root
;
}
if
(
OB_SUCC
(
ret
))
{
ObSEArray
<
ObSelectStmt
*
,
4
>
child_stmts
;
if
(
OB_FAIL
(
get_child_stmts
(
child_stmts
)))
{
LOG_WARN
(
"failed to get child stmts"
,
K
(
ret
));
}
else
{
for
(
int64_t
i
=
0
;
OB_SUCC
(
ret
)
&&
!
has_ref_user_var
&&
i
<
child_stmts
.
count
();
++
i
)
{
for
(
int64_t
i
=
0
;
OB_SUCC
(
ret
)
&&
i
<
child_stmts
.
count
();
++
i
)
{
if
(
OB_ISNULL
(
child_stmts
.
at
(
i
)))
{
ret
=
OB_ERR_UNEXPECTED
;
LOG_WARN
(
"get unexpected null"
,
K
(
ret
));
}
else
if
(
child_stmts
.
at
(
i
)
->
recursive_check_has_ref_assign_user_var
(
has_ref_user_var
))
{
}
else
if
(
OB_FAIL
(
SMART_CALL
(
child_stmts
.
at
(
i
)
->
check_has_var_assign_rec
(
has_var_assign
,
is_var_assign_only_in_root
,
false
))))
{
LOG_WARN
(
"failed to recursive check has assignment ref user var"
,
K
(
ret
));
}
}
...
...
src/sql/resolver/dml/ob_dml_stmt.h
浏览文件 @
25b02ac3
...
...
@@ -947,10 +947,12 @@ public:
int
get_column_exprs
(
uint64_t
table_id
,
ObIArray
<
ObRawExpr
*>
&
table_cols
)
const
;
virtual
int
inner_get_share_exprs
(
ObIArray
<
ObRawExpr
*>
&
share_exprs
)
const
;
int
has_ref_assign_user_var
(
bool
&
has_ref_user_var
)
const
;
int
recursive_check_has_ref_assign_user_var
(
bool
&
has_ref_user_var
)
const
;
int
find_var_assign_in_query_ctx
(
bool
&
is_found
)
const
;
int
check_user_vars_has_var_assign
(
bool
&
has_var_assign
)
const
;
int
has_ref_assign_user_var
(
bool
&
has_ref_user_var
,
bool
need_check_child
=
true
)
const
;
int
check_has_var_assign_rec
(
bool
&
has_ref_user_var
,
bool
need_check_child
)
const
;
int
check_var_assign
(
bool
&
has_var_assign
,
bool
&
is_var_assign_only_in_root
)
const
;
int
check_has_var_assign_rec
(
bool
&
has_var_assign
,
bool
&
is_var_assign_only_in_root
,
bool
is_root
)
const
;
int
get_temp_table_ids
(
ObIArray
<
uint64_t
>
&
temp_table_ids
);
virtual
int
refill_global_index_dml_info
(
ObRawExprFactory
&
expr_factory
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录