fix bug that null side checking without recursion the root joined-table

This commit is contained in:
jingtaoye35
2024-06-28 03:51:48 +00:00
committed by ob-robot
parent 650ab2c268
commit a7bdd6c86b
5 changed files with 160 additions and 168 deletions

View File

@ -430,6 +430,7 @@ public:
const ObIArray<ObRawExpr*> &exprs,
ObIArray<ObRawExpr*> &corr_exprs);
// check whether a no-joined-table is on joined-table's null side
static int is_table_on_null_side(const ObDMLStmt *stmt,
uint64_t table_id,
bool &is_on_null_side);

View File

@ -145,19 +145,18 @@ int ObTransformConstPropagate::ConstInfoContext::add_const_info(ExprConstInfo &c
}
int ObTransformConstPropagate::ConstInfoContext::merge_expired_const_infos(ConstInfoContext &other,
bool is_null_side)
bool can_pull_up)
{
int ret = OB_SUCCESS;
for (int64_t i = 0; OB_SUCC(ret) && i < other.active_const_infos_.count(); ++i) {
if (other.active_const_infos_.at(i).can_pullup_) {
other.active_const_infos_.at(i).can_pullup_ = !is_null_side;
if (can_pull_up) {
if (OB_FAIL(add_const_info(other.active_const_infos_.at(i)))) {
LOG_WARN("failed to push back", K(ret));
}
} else if (!other.active_const_infos_.at(i).is_used_) {
// do nothing
} else if (OB_FAIL(expired_const_infos_.push_back(other.active_const_infos_.at(i)))) {
LOG_WARN("failed to push back", K(ret));
} else if (other.active_const_infos_.at(i).is_used_) {
if (OB_FAIL(expired_const_infos_.push_back(other.active_const_infos_.at(i)))) {
LOG_WARN("failed to push back", K(ret));
}
}
}
if (OB_SUCC(ret)) {
@ -252,6 +251,7 @@ int ObTransformConstPropagate::do_transform(ObDMLStmt *stmt,
}
if (OB_SUCC(ret)) {
is_happened = false;
if (OB_FAIL(collect_equal_pair_from_tables(stmt,
const_ctx,
is_happened))) {
@ -263,6 +263,7 @@ int ObTransformConstPropagate::do_transform(ObDMLStmt *stmt,
}
if (OB_SUCC(ret)) {
is_happened = false;
if (OB_FAIL(collect_equal_pair_from_semi_infos(stmt,
const_ctx,
is_happened))) {
@ -274,6 +275,7 @@ int ObTransformConstPropagate::do_transform(ObDMLStmt *stmt,
}
if (OB_SUCC(ret)) {
is_happened = false;
if (OB_FAIL(replace_join_conditions(stmt,
const_ctx,
is_happened))) {
@ -285,6 +287,7 @@ int ObTransformConstPropagate::do_transform(ObDMLStmt *stmt,
}
if (OB_SUCC(ret) && !const_ctx.active_const_infos_.empty()) {
is_happened = false;
if (OB_FAIL(replace_common_exprs(stmt->get_condition_exprs(),
const_ctx,
is_happened))) {
@ -313,6 +316,7 @@ int ObTransformConstPropagate::do_transform(ObDMLStmt *stmt,
if (OB_SUCC(ret) && !const_ctx.active_const_infos_.empty() &&
(stmt->is_insert_stmt() || stmt->is_merge_stmt())) {
ObDelUpdStmt *insert = static_cast<ObDelUpdStmt *>(stmt);
is_happened = false;
if (OB_FAIL(replace_common_exprs(insert->get_sharding_conditions(),
const_ctx,
is_happened))) {
@ -364,9 +368,10 @@ int ObTransformConstPropagate::do_transform(ObDMLStmt *stmt,
if (OB_SUCC(ret) && stmt->is_select_stmt()) {
if (!const_ctx.active_const_infos_.empty() && !ignore_all_select_exprs && static_cast<ObSelectStmt*>(stmt)->get_aggr_item_size() > 0) {
is_happened = false;
if (OB_FAIL(replace_select_exprs(static_cast<ObSelectStmt*>(stmt),
const_ctx,
is_happened))) {
const_ctx,
is_happened))) {
LOG_WARN("failed to replace select exprs", K(ret));
} else {
trans_happened |= is_happened;
@ -389,6 +394,7 @@ int ObTransformConstPropagate::do_transform(ObDMLStmt *stmt,
}
if (OB_SUCC(ret) && stmt->is_select_stmt()) {
is_happened = false;
if (OB_FAIL(replace_common_exprs(static_cast<ObSelectStmt*>(stmt)->get_having_exprs(),
const_ctx,
is_happened))) {
@ -641,6 +647,12 @@ int ObTransformConstPropagate::collect_equal_pair_from_semi_infos(ObDMLStmt *stm
return ret;
}
/* collect const info from table
* 1. As left-join table(also right-join table
* const infos from not_null_side and on_condition can be pulled up to high level const ctx.
* const infos from null_side can only used on self level join table.
* 2. inner-join table, const infos can be pulled up to high level const ctx.
*/
int ObTransformConstPropagate::recursive_collect_const_info_from_table(ObDMLStmt *stmt,
TableItem *table_item,
ConstInfoContext &const_ctx,
@ -648,6 +660,7 @@ int ObTransformConstPropagate::recursive_collect_const_info_from_table(ObDMLStmt
bool &trans_happened)
{
int ret = OB_SUCCESS;
JoinedTable *joined_table = NULL;
if (OB_ISNULL(stmt) || OB_ISNULL(table_item)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid parameter", K(ret));
@ -655,71 +668,75 @@ int ObTransformConstPropagate::recursive_collect_const_info_from_table(ObDMLStmt
if (OB_FAIL(collect_equal_pair_from_pullup(stmt, table_item, const_ctx, is_null_side))) {
LOG_WARN("failed to collect const info from pullup", K(ret));
}
} else if (table_item->is_joined_table()) {
JoinedTable *joined_table = static_cast<JoinedTable *>(table_item);
if (LEFT_OUTER_JOIN == joined_table->joined_type_ ||
RIGHT_OUTER_JOIN == joined_table->joined_type_) {
// FULL_OUT_JOIN is not transformed because may eliminate all equal join conditions
ConstInfoContext tmp_ctx(const_ctx.shared_expr_checker_, const_ctx.allow_trans_);
bool left_happened = false;
bool right_happened = false;
bool condition_happened = false;
if (OB_FAIL(SMART_CALL(recursive_collect_const_info_from_table(stmt,
joined_table->left_table_,
tmp_ctx,
!joined_table->is_left_join(),
left_happened)))) {
LOG_WARN("failed to recursive collect const info from table", K(ret));
} else if (OB_FAIL(SMART_CALL(recursive_collect_const_info_from_table(stmt,
joined_table->right_table_,
tmp_ctx,
!joined_table->is_right_join(),
right_happened)))) {
LOG_WARN("failed to recursive collect const info from table", K(ret));
} else if (OB_FAIL(collect_equal_pair_from_condition(stmt,
joined_table->get_join_conditions(),
tmp_ctx,
condition_happened))) {
LOG_WARN("failed to collect const info from join condition", K(ret));
} else {
trans_happened |= left_happened || right_happened || condition_happened;
}
if (OB_SUCC(ret)) {
bool is_happened = false;
if (OB_FAIL(SMART_CALL(recursive_replace_join_conditions(joined_table,
tmp_ctx,
is_happened)))) {
LOG_WARN("failed to replace exprs in joined table", K(ret));
} else if (const_ctx.merge_expired_const_infos(tmp_ctx, is_null_side)) {
LOG_WARN("failed to merge expired const infos", K(ret));
} else {
trans_happened |= is_happened;
}
}
} else if (joined_table->is_inner_join()) {
bool left_happened = false;
bool right_happened = false;
bool condition_happened = false;
if (OB_FAIL(SMART_CALL(recursive_collect_const_info_from_table(stmt,
joined_table->left_table_,
const_ctx,
false,
left_happened)))) {
LOG_WARN("failed to recursive collect const info from table", K(ret));
} else if (OB_FAIL(SMART_CALL(recursive_collect_const_info_from_table(stmt,
joined_table->right_table_,
const_ctx,
false,
right_happened)))) {
LOG_WARN("failed to recursive collect const info from table", K(ret));
} else if (OB_FAIL(collect_equal_pair_from_condition(stmt,
joined_table->get_join_conditions(),
const_ctx,
condition_happened))) {
LOG_WARN("failed to collect const info from join condition", K(ret));
} else {
trans_happened |= left_happened || right_happened || condition_happened;
}
} else if (!table_item->is_joined_table()) {
} else if (FALSE_IT(joined_table = static_cast<JoinedTable *>(table_item))) {
} else if (LEFT_OUTER_JOIN == joined_table->joined_type_ ||
RIGHT_OUTER_JOIN == joined_table->joined_type_) {
// FULL_OUT_JOIN is not transformed because may eliminate all equal join conditions
TableItem *left_table = LEFT_OUTER_JOIN == joined_table->joined_type_ ?
joined_table->left_table_ : joined_table->right_table_;
TableItem *right_table = LEFT_OUTER_JOIN == joined_table->joined_type_ ?
joined_table->right_table_ : joined_table->left_table_;
ConstInfoContext tmp_ctx(const_ctx.shared_expr_checker_, const_ctx.allow_trans_);
bool left_happened = false;
bool right_happened = false;
bool condition_happened = false;
bool replace_join_left = false;
bool replace_join_right = false;
if (OB_FAIL(SMART_CALL(recursive_collect_const_info_from_table(stmt, left_table,
tmp_ctx, false,
left_happened)))) {
LOG_WARN("failed to recursive collect const info from table", K(ret));
} else if (OB_FAIL(SMART_CALL(recursive_replace_join_conditions(joined_table, tmp_ctx,
replace_join_left)))) {
LOG_WARN("failed to replace exprs in joined table", K(ret));
} else if (OB_FAIL(const_ctx.merge_expired_const_infos(tmp_ctx, true))) {
LOG_WARN("failed to merge expired const infos", K(ret));
} else if (FALSE_IT(tmp_ctx.reset())) {
} else if (OB_FAIL(SMART_CALL(recursive_collect_const_info_from_table(stmt, right_table,
tmp_ctx, true,
right_happened)))) {
LOG_WARN("failed to recursive collect const info from table", K(ret));
} else if (OB_FAIL(collect_equal_pair_from_condition(stmt, joined_table->get_join_conditions(),
tmp_ctx, condition_happened))) {
LOG_WARN("failed to collect const info from join condition", K(ret));
} else if (OB_FAIL(SMART_CALL(recursive_replace_join_conditions(joined_table, tmp_ctx,
replace_join_right)))) {
LOG_WARN("failed to replace exprs in joined table", K(ret));
} else if (OB_FAIL(const_ctx.merge_expired_const_infos(tmp_ctx, false))) {
LOG_WARN("failed to merge expired const infos", K(ret));
} else {
trans_happened |= left_happened || right_happened || condition_happened ||
replace_join_left || replace_join_right;
LOG_TRACE("collect const info from table", K(trans_happened), K(left_happened),
K(right_happened), K(condition_happened), K(replace_join_left),
K(replace_join_right));
}
} else if (joined_table->is_inner_join()) {
bool left_happened = false;
bool right_happened = false;
bool condition_happened = false;
if (OB_FAIL(SMART_CALL(recursive_collect_const_info_from_table(stmt,
joined_table->left_table_,
const_ctx,
false,
left_happened)))) {
LOG_WARN("failed to recursive collect const info from table", K(ret));
} else if (OB_FAIL(SMART_CALL(recursive_collect_const_info_from_table(stmt,
joined_table->right_table_,
const_ctx,
false,
right_happened)))) {
LOG_WARN("failed to recursive collect const info from table", K(ret));
} else if (OB_FAIL(collect_equal_pair_from_condition(stmt,
joined_table->get_join_conditions(),
const_ctx,
condition_happened))) {
LOG_WARN("failed to collect const info from join condition", K(ret));
} else {
trans_happened |= left_happened || right_happened || condition_happened;
LOG_TRACE("collect const info from table", K(trans_happened), K(left_happened),
K(right_happened), K(condition_happened));
}
}
return ret;
@ -744,7 +761,6 @@ int ObTransformConstPropagate::collect_equal_pair_from_pullup(ObDMLStmt *stmt,
for (int64_t j = 0; OB_SUCC(ret) && j < child_stmt->get_select_item_size(); ++j) {
ObRawExpr *select_expr = child_stmt->get_select_items().at(j).expr_;
ExprConstInfo equal_info;
equal_info.can_pullup_ = !is_null_side;
equal_info.mem_equal_ = true;
const uint64_t column_id = j + OB_APP_MIN_COLUMN_ID;
if (OB_ISNULL(select_expr)) {

View File

@ -49,7 +49,6 @@ private:
new_expr_(NULL),
equal_infos_(),
need_add_constraint_(PRE_CALC_RESULT_NONE),
can_pullup_(false),
mem_equal_(false),
is_used_(false),
is_complex_const_info_(false),
@ -67,13 +66,12 @@ private:
ObRawExpr* new_expr_;
common::ObSEArray<ObPCParamEqualInfo, 2> equal_infos_;
PreCalcExprExpectResult need_add_constraint_;
bool can_pullup_;
bool mem_equal_; //param expr mem is const expr.
bool is_used_;
//record or/in predicate const exprs
bool is_complex_const_info_;
common::ObSEArray<ObRawExpr*, 4> multi_const_exprs_;
common::ObSEArray<PreCalcExprExpectResult, 4> multi_need_add_constraints_;
common::ObSEArray<ObRawExpr*, 2> multi_const_exprs_;
common::ObSEArray<PreCalcExprExpectResult, 2> multi_need_add_constraints_;
TO_STRING_KV(KPC_(column_expr),
KPC_(const_expr),
@ -81,7 +79,6 @@ private:
K_(new_expr),
K_(equal_infos),
K_(need_add_constraint),
K_(can_pullup),
K_(mem_equal),
K_(is_used),
K_(is_complex_const_info),
@ -99,16 +96,21 @@ private:
{
}
~ConstInfoContext() {}
void reset() {
active_const_infos_.reset();
expired_const_infos_.reset();
extra_excluded_exprs_.reset();
}
int add_const_infos(ObIArray<ExprConstInfo> &const_infos);
int add_const_info(ExprConstInfo &const_info);
int merge_expired_const_infos(ConstInfoContext &other, bool is_null_side);
int merge_expired_const_infos(ConstInfoContext &other, bool can_pull_up);
int find_exclude_expr(const ObRawExpr *expr, bool &found);
int expire_const_infos();
common::ObSEArray<ExprConstInfo, 4> active_const_infos_;
common::ObSEArray<ExprConstInfo, 4> expired_const_infos_;
common::ObSEArray<ObRawExpr *, 4> extra_excluded_exprs_;
common::ObSEArray<ExprConstInfo, 2> active_const_infos_;
common::ObSEArray<ExprConstInfo, 2> expired_const_infos_;
common::ObSEArray<ObRawExpr *, 2> extra_excluded_exprs_;
bool allow_trans_;
const ObSharedExprChecker &shared_expr_checker_;

View File

@ -397,8 +397,8 @@ int ObTransformViewMerge::transform_generated_table(ObDMLStmt *parent_stmt,
ObSelectStmt *child_stmt = NULL;
ViewMergeHelper helper;
trans_happened = false;
OPT_TRACE("try to merge view:", table_item);
helper.trans_table = table_item;
OPT_TRACE("try to merge view:", table_item);
if (OB_ISNULL(parent_stmt) || OB_ISNULL(table_item)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null ptr", K(ret), K(parent_stmt), K(table_item));
@ -412,7 +412,6 @@ int ObTransformViewMerge::transform_generated_table(ObDMLStmt *parent_stmt,
child_stmt,
helper,
parent_stmt->is_hierarchical_query(),
false,
can_be))) {
LOG_WARN("failed to check can be unnested", K(ret));
} else if (!can_be) {
@ -445,7 +444,6 @@ int ObTransformViewMerge::transform_generated_table(ObDMLStmt *parent_stmt,
helper.parent_table = parent_table;
helper.trans_table = table_item;
helper.can_push_where = can_push_where;
bool is_left_join_right_table = false;
trans_happened = false;
OPT_TRACE("try to merge view:", table_item);
if (OB_ISNULL(parent_stmt) || OB_ISNULL(parent_table) || OB_ISNULL(table_item)) {
@ -457,34 +455,16 @@ int ObTransformViewMerge::transform_generated_table(ObDMLStmt *parent_stmt,
} else if (OB_ISNULL(child_stmt = table_item->ref_query_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
} else if (parent_table->joined_type_ == FULL_OUTER_JOIN) {
//如果是full outer join,如果视图有null reject输出表达式,需要视图有非空列
helper.need_check_null_propagate = true;
} else if (parent_table->joined_type_ == LEFT_OUTER_JOIN) {
if (table_item == parent_table->right_table_) {
//如果是left join的右表,如果视图有null reject输出表达式,需要视图有非空列
helper.need_check_null_propagate = true;
is_left_join_right_table = true;
}
} else if (parent_table->joined_type_ == RIGHT_OUTER_JOIN) {
if (table_item == parent_table->left_table_) {
//如果是right join的左表,如果视图有null reject输出表达式,需要视图有非空列
helper.need_check_null_propagate = true;
is_left_join_right_table = true;
}
} else {/*do nothing*/}
if (OB_FAIL(ret) ||
(!table_item->is_generated_table() &&
!table_item->is_lateral_table())) {
/*do nothing*/
} else if (need_check_where_condi && child_stmt->get_condition_size() > 0) {
/*do nothing*/
OPT_TRACE("view has conditions, can not merge view");
} else if (OB_FAIL(ObOptimizerUtil::is_table_on_null_side(parent_stmt,
table_item->table_id_,
helper.need_check_null_propagate))) {
LOG_WARN("failed to check is table on null side", K(ret), K(table_item->table_id_));
} else if (OB_FAIL(check_can_be_merged(parent_stmt,
child_stmt,
helper,
!can_push_where,
is_left_join_right_table,
can_be))) {
LOG_WARN("failed to check can be unnested", K(ret));
} else if (!can_be) {
@ -617,19 +597,17 @@ int ObTransformViewMerge::check_can_be_merged(ObDMLStmt *parent_stmt,
ObSelectStmt *child_stmt,
ViewMergeHelper &helper,
bool need_check_subquery,
bool is_left_join_right_table,
bool &can_be)
{
int ret = OB_SUCCESS;
can_be = true;
bool has_rollup = false;
can_be = true;
if (OB_ISNULL(parent_stmt) || OB_ISNULL(child_stmt)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
} else if (OB_FAIL(check_basic_validity(parent_stmt, child_stmt, can_be))) {
LOG_WARN("failed to check", K(ret));
} else if (!can_be) {
} else {
} else if (can_be) {
has_rollup = parent_stmt->is_select_stmt() &&
static_cast<ObSelectStmt *>(parent_stmt)->has_rollup();
//select expr不能包含subquery
@ -646,47 +624,45 @@ int ObTransformViewMerge::check_can_be_merged(ObDMLStmt *parent_stmt,
OPT_TRACE("const expr can not be merged into rollup stmt");
}
}
//stmt不能包含rand函数
if (OB_SUCC(ret) && can_be) {
bool has_rand = false;
if (OB_FAIL(child_stmt->has_rand(has_rand))) {
LOG_WARN("failed to get rand flag", K(ret));
} else if (has_rand) {
can_be = false;
OPT_TRACE("view has random expr, can not merge");
}
}
//stmt不能包含rand函数
if (OB_SUCC(ret) && can_be) {
bool has_rand = false;
if (OB_FAIL(child_stmt->has_rand(has_rand))) {
LOG_WARN("failed to get rand flag", K(ret));
} else if (has_rand) {
can_be = false;
OPT_TRACE("view has random expr, can not merge");
}
if (OB_SUCC(ret) && can_be) {
bool contain = false;
bool is_ref_outer = false;
if (OB_ISNULL(helper.trans_table)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null table item", K(ret));
} else if (!helper.trans_table->is_lateral_table()) {
// do nothing
} else if (OB_FAIL(ObTransformUtils::is_table_item_correlated(helper.trans_table->exec_params_,
*child_stmt,
contain))) {
LOG_WARN("failed to check is table item correlated", K(ret));
} else if (contain) {
can_be = false;
OPT_TRACE("lateral inline view has correlated table item, can not merge");
} else if (helper.parent_table != NULL &&
OB_FAIL(ObTransformUtils::check_lateral_ref_outer_table(parent_stmt,
helper.parent_table,
helper.trans_table,
is_ref_outer))) {
LOG_WARN("failed to check lateral ref outer table", K(ret));
} else if (is_ref_outer) {
can_be = false;
OPT_TRACE("lateral inline view ref outer table, can not merge");
}
}
if (OB_SUCC(ret) && can_be) {
bool contain = false;
bool is_ref_outer = false;
if (OB_ISNULL(helper.trans_table)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null table item", K(ret));
} else if (!helper.trans_table->is_lateral_table()) {
// do nothing
} else if (OB_FAIL(ObTransformUtils::is_table_item_correlated(helper.trans_table->exec_params_,
*child_stmt,
contain))) {
LOG_WARN("failed to check is table item correlated", K(ret));
} else if (contain) {
can_be = false;
OPT_TRACE("lateral inline view has correlated table item, can not merge");
} else if (helper.parent_table != NULL &&
OB_FAIL(ObTransformUtils::check_lateral_ref_outer_table(parent_stmt,
helper.parent_table,
helper.trans_table,
is_ref_outer))) {
LOG_WARN("failed to check lateral ref outer table", K(ret));
} else if (is_ref_outer) {
can_be = false;
OPT_TRACE("lateral inline view ref outer table, can not merge");
}
}
//检查where condition是否存在子查询
if (OB_FAIL(ret) || !can_be) {
/*do nothing*/
} else if (need_check_subquery){
if (OB_SUCC(ret) && can_be && need_check_subquery){
if (child_stmt->get_semi_infos().count() > 0) {
can_be =false;
OPT_TRACE("view has semi info, can not merge");
@ -702,24 +678,22 @@ int ObTransformViewMerge::check_can_be_merged(ObDMLStmt *parent_stmt,
} else { /*do nothing*/ }
}
}
} else {/*do nothing*/}
}
//Check if the left join right view expansion will increase the plan space.
if (OB_FAIL(ret) || !can_be || !is_left_join_right_table) {
/*do nothing*/
} else if (OB_ISNULL(helper.parent_table)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null table item", K(ret));
} else if (OB_FAIL(check_left_join_right_view_need_merge(parent_stmt,
child_stmt,
helper.trans_table,
helper.parent_table,
can_be))) {
LOG_WARN("failed to check left join right view need merge", K(ret));
if (OB_SUCC(ret) && can_be && NULL != helper.parent_table) {
if ((LEFT_OUTER_JOIN == helper.parent_table->joined_type_ && helper.parent_table->right_table_ == helper.trans_table) ||
(RIGHT_OUTER_JOIN == helper.parent_table->joined_type_ && helper.parent_table->left_table_ == helper.trans_table)) {
if (OB_FAIL(check_left_join_right_view_need_merge(parent_stmt,
child_stmt,
helper.trans_table,
helper.parent_table,
can_be))) {
LOG_WARN("failed to check left join right view need merge", K(ret));
}
}
}
//检查视图是否有空值拒绝表达式
if (OB_FAIL(ret) || !can_be) {
/*do nothing*/
} else if (helper.need_check_null_propagate){
if (OB_SUCC(ret) && can_be && helper.need_check_null_propagate){
ObSEArray<ObRawExpr *, 4> columns;
ObSqlBitSet<> from_tables;
ObSEArray<ObRawExpr*, 4> column_exprs;
@ -754,7 +728,7 @@ int ObTransformViewMerge::check_can_be_merged(ObDMLStmt *parent_stmt,
OPT_TRACE("view has null propagate expr, but not found not null column");
}
}
} else {/*do nothing*/}
}
return ret;
}
@ -765,9 +739,9 @@ int ObTransformViewMerge::check_left_join_right_view_need_merge(ObDMLStmt *paren
bool &need_merge)
{
int ret = OB_SUCCESS;
need_merge = false;
bool force_merge = false;
bool force_no_merge = false;
need_merge = false;
if (OB_ISNULL(child_stmt) || OB_ISNULL(parent_stmt) ||
OB_ISNULL(view_table)) {
ret = OB_ERR_UNEXPECTED;

View File

@ -67,7 +67,6 @@ private:
ObSelectStmt* child_stmt,
ViewMergeHelper &helper,
bool need_check_subquery,
bool is_left_join_right_table,
bool &can_be);
int check_left_join_right_view_need_merge(ObDMLStmt *parent_stmt,