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, const ObIArray<ObRawExpr*> &exprs,
ObIArray<ObRawExpr*> &corr_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, static int is_table_on_null_side(const ObDMLStmt *stmt,
uint64_t table_id, uint64_t table_id,
bool &is_on_null_side); 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, int ObTransformConstPropagate::ConstInfoContext::merge_expired_const_infos(ConstInfoContext &other,
bool is_null_side) bool can_pull_up)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
for (int64_t i = 0; OB_SUCC(ret) && i < other.active_const_infos_.count(); ++i) { for (int64_t i = 0; OB_SUCC(ret) && i < other.active_const_infos_.count(); ++i) {
if (other.active_const_infos_.at(i).can_pullup_) { if (can_pull_up) {
other.active_const_infos_.at(i).can_pullup_ = !is_null_side;
if (OB_FAIL(add_const_info(other.active_const_infos_.at(i)))) { if (OB_FAIL(add_const_info(other.active_const_infos_.at(i)))) {
LOG_WARN("failed to push back", K(ret)); LOG_WARN("failed to push back", K(ret));
} }
} else if (!other.active_const_infos_.at(i).is_used_) { } else if (other.active_const_infos_.at(i).is_used_) {
// do nothing if (OB_FAIL(expired_const_infos_.push_back(other.active_const_infos_.at(i)))) {
} else if (OB_FAIL(expired_const_infos_.push_back(other.active_const_infos_.at(i)))) { LOG_WARN("failed to push back", K(ret));
LOG_WARN("failed to push back", K(ret)); }
} }
} }
if (OB_SUCC(ret)) { if (OB_SUCC(ret)) {
@ -252,6 +251,7 @@ int ObTransformConstPropagate::do_transform(ObDMLStmt *stmt,
} }
if (OB_SUCC(ret)) { if (OB_SUCC(ret)) {
is_happened = false;
if (OB_FAIL(collect_equal_pair_from_tables(stmt, if (OB_FAIL(collect_equal_pair_from_tables(stmt,
const_ctx, const_ctx,
is_happened))) { is_happened))) {
@ -263,6 +263,7 @@ int ObTransformConstPropagate::do_transform(ObDMLStmt *stmt,
} }
if (OB_SUCC(ret)) { if (OB_SUCC(ret)) {
is_happened = false;
if (OB_FAIL(collect_equal_pair_from_semi_infos(stmt, if (OB_FAIL(collect_equal_pair_from_semi_infos(stmt,
const_ctx, const_ctx,
is_happened))) { is_happened))) {
@ -274,6 +275,7 @@ int ObTransformConstPropagate::do_transform(ObDMLStmt *stmt,
} }
if (OB_SUCC(ret)) { if (OB_SUCC(ret)) {
is_happened = false;
if (OB_FAIL(replace_join_conditions(stmt, if (OB_FAIL(replace_join_conditions(stmt,
const_ctx, const_ctx,
is_happened))) { is_happened))) {
@ -285,6 +287,7 @@ int ObTransformConstPropagate::do_transform(ObDMLStmt *stmt,
} }
if (OB_SUCC(ret) && !const_ctx.active_const_infos_.empty()) { if (OB_SUCC(ret) && !const_ctx.active_const_infos_.empty()) {
is_happened = false;
if (OB_FAIL(replace_common_exprs(stmt->get_condition_exprs(), if (OB_FAIL(replace_common_exprs(stmt->get_condition_exprs(),
const_ctx, const_ctx,
is_happened))) { is_happened))) {
@ -313,6 +316,7 @@ int ObTransformConstPropagate::do_transform(ObDMLStmt *stmt,
if (OB_SUCC(ret) && !const_ctx.active_const_infos_.empty() && if (OB_SUCC(ret) && !const_ctx.active_const_infos_.empty() &&
(stmt->is_insert_stmt() || stmt->is_merge_stmt())) { (stmt->is_insert_stmt() || stmt->is_merge_stmt())) {
ObDelUpdStmt *insert = static_cast<ObDelUpdStmt *>(stmt); ObDelUpdStmt *insert = static_cast<ObDelUpdStmt *>(stmt);
is_happened = false;
if (OB_FAIL(replace_common_exprs(insert->get_sharding_conditions(), if (OB_FAIL(replace_common_exprs(insert->get_sharding_conditions(),
const_ctx, const_ctx,
is_happened))) { is_happened))) {
@ -364,9 +368,10 @@ int ObTransformConstPropagate::do_transform(ObDMLStmt *stmt,
if (OB_SUCC(ret) && stmt->is_select_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) { 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), if (OB_FAIL(replace_select_exprs(static_cast<ObSelectStmt*>(stmt),
const_ctx, const_ctx,
is_happened))) { is_happened))) {
LOG_WARN("failed to replace select exprs", K(ret)); LOG_WARN("failed to replace select exprs", K(ret));
} else { } else {
trans_happened |= is_happened; trans_happened |= is_happened;
@ -389,6 +394,7 @@ int ObTransformConstPropagate::do_transform(ObDMLStmt *stmt,
} }
if (OB_SUCC(ret) && stmt->is_select_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(), if (OB_FAIL(replace_common_exprs(static_cast<ObSelectStmt*>(stmt)->get_having_exprs(),
const_ctx, const_ctx,
is_happened))) { is_happened))) {
@ -641,6 +647,12 @@ int ObTransformConstPropagate::collect_equal_pair_from_semi_infos(ObDMLStmt *stm
return ret; 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, int ObTransformConstPropagate::recursive_collect_const_info_from_table(ObDMLStmt *stmt,
TableItem *table_item, TableItem *table_item,
ConstInfoContext &const_ctx, ConstInfoContext &const_ctx,
@ -648,6 +660,7 @@ int ObTransformConstPropagate::recursive_collect_const_info_from_table(ObDMLStmt
bool &trans_happened) bool &trans_happened)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
JoinedTable *joined_table = NULL;
if (OB_ISNULL(stmt) || OB_ISNULL(table_item)) { if (OB_ISNULL(stmt) || OB_ISNULL(table_item)) {
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid parameter", K(ret)); 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))) { 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)); LOG_WARN("failed to collect const info from pullup", K(ret));
} }
} else if (table_item->is_joined_table()) { } else if (!table_item->is_joined_table()) {
JoinedTable *joined_table = static_cast<JoinedTable *>(table_item); } else if (FALSE_IT(joined_table = static_cast<JoinedTable *>(table_item))) {
if (LEFT_OUTER_JOIN == joined_table->joined_type_ || } else if (LEFT_OUTER_JOIN == joined_table->joined_type_ ||
RIGHT_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 // 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_); TableItem *left_table = LEFT_OUTER_JOIN == joined_table->joined_type_ ?
bool left_happened = false; joined_table->left_table_ : joined_table->right_table_;
bool right_happened = false; TableItem *right_table = LEFT_OUTER_JOIN == joined_table->joined_type_ ?
bool condition_happened = false; joined_table->right_table_ : joined_table->left_table_;
if (OB_FAIL(SMART_CALL(recursive_collect_const_info_from_table(stmt, ConstInfoContext tmp_ctx(const_ctx.shared_expr_checker_, const_ctx.allow_trans_);
joined_table->left_table_, bool left_happened = false;
tmp_ctx, bool right_happened = false;
!joined_table->is_left_join(), bool condition_happened = false;
left_happened)))) { bool replace_join_left = false;
LOG_WARN("failed to recursive collect const info from table", K(ret)); bool replace_join_right = false;
} else if (OB_FAIL(SMART_CALL(recursive_collect_const_info_from_table(stmt, if (OB_FAIL(SMART_CALL(recursive_collect_const_info_from_table(stmt, left_table,
joined_table->right_table_, tmp_ctx, false,
tmp_ctx, left_happened)))) {
!joined_table->is_right_join(), LOG_WARN("failed to recursive collect const info from table", K(ret));
right_happened)))) { } else if (OB_FAIL(SMART_CALL(recursive_replace_join_conditions(joined_table, tmp_ctx,
LOG_WARN("failed to recursive collect const info from table", K(ret)); replace_join_left)))) {
} else if (OB_FAIL(collect_equal_pair_from_condition(stmt, LOG_WARN("failed to replace exprs in joined table", K(ret));
joined_table->get_join_conditions(), } else if (OB_FAIL(const_ctx.merge_expired_const_infos(tmp_ctx, true))) {
tmp_ctx, LOG_WARN("failed to merge expired const infos", K(ret));
condition_happened))) { } else if (FALSE_IT(tmp_ctx.reset())) {
LOG_WARN("failed to collect const info from join condition", K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_collect_const_info_from_table(stmt, right_table,
} else { tmp_ctx, true,
trans_happened |= left_happened || right_happened || condition_happened; right_happened)))) {
} LOG_WARN("failed to recursive collect const info from table", K(ret));
if (OB_SUCC(ret)) { } else if (OB_FAIL(collect_equal_pair_from_condition(stmt, joined_table->get_join_conditions(),
bool is_happened = false; tmp_ctx, condition_happened))) {
if (OB_FAIL(SMART_CALL(recursive_replace_join_conditions(joined_table, LOG_WARN("failed to collect const info from join condition", K(ret));
tmp_ctx, } else if (OB_FAIL(SMART_CALL(recursive_replace_join_conditions(joined_table, tmp_ctx,
is_happened)))) { replace_join_right)))) {
LOG_WARN("failed to replace exprs in joined table", K(ret)); LOG_WARN("failed to replace exprs in joined table", K(ret));
} else if (const_ctx.merge_expired_const_infos(tmp_ctx, is_null_side)) { } else if (OB_FAIL(const_ctx.merge_expired_const_infos(tmp_ctx, false))) {
LOG_WARN("failed to merge expired const infos", K(ret)); LOG_WARN("failed to merge expired const infos", K(ret));
} else { } else {
trans_happened |= is_happened; 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),
} else if (joined_table->is_inner_join()) { K(right_happened), K(condition_happened), K(replace_join_left),
bool left_happened = false; K(replace_join_right));
bool right_happened = false; }
bool condition_happened = false; } else if (joined_table->is_inner_join()) {
if (OB_FAIL(SMART_CALL(recursive_collect_const_info_from_table(stmt, bool left_happened = false;
joined_table->left_table_, bool right_happened = false;
const_ctx, bool condition_happened = false;
false, if (OB_FAIL(SMART_CALL(recursive_collect_const_info_from_table(stmt,
left_happened)))) { joined_table->left_table_,
LOG_WARN("failed to recursive collect const info from table", K(ret)); const_ctx,
} else if (OB_FAIL(SMART_CALL(recursive_collect_const_info_from_table(stmt, false,
joined_table->right_table_, left_happened)))) {
const_ctx, LOG_WARN("failed to recursive collect const info from table", K(ret));
false, } else if (OB_FAIL(SMART_CALL(recursive_collect_const_info_from_table(stmt,
right_happened)))) { joined_table->right_table_,
LOG_WARN("failed to recursive collect const info from table", K(ret)); const_ctx,
} else if (OB_FAIL(collect_equal_pair_from_condition(stmt, false,
joined_table->get_join_conditions(), right_happened)))) {
const_ctx, LOG_WARN("failed to recursive collect const info from table", K(ret));
condition_happened))) { } else if (OB_FAIL(collect_equal_pair_from_condition(stmt,
LOG_WARN("failed to collect const info from join condition", K(ret)); joined_table->get_join_conditions(),
} else { const_ctx,
trans_happened |= left_happened || right_happened || condition_happened; 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; 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) { 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_; ObRawExpr *select_expr = child_stmt->get_select_items().at(j).expr_;
ExprConstInfo equal_info; ExprConstInfo equal_info;
equal_info.can_pullup_ = !is_null_side;
equal_info.mem_equal_ = true; equal_info.mem_equal_ = true;
const uint64_t column_id = j + OB_APP_MIN_COLUMN_ID; const uint64_t column_id = j + OB_APP_MIN_COLUMN_ID;
if (OB_ISNULL(select_expr)) { if (OB_ISNULL(select_expr)) {

View File

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

View File

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

View File

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