fix master bugs in rewrite

This commit is contained in:
jingtaoye35 2024-10-28 05:46:13 +00:00 committed by ob-robot
parent 3895cfc3e4
commit d49644bc7d
2 changed files with 41 additions and 29 deletions

View File

@ -2581,10 +2581,6 @@ int ObTransformJoinElimination::is_table_column_used_in_subquery(const ObSelectS
return ret;
}
/*
source_table and target_table come from the same stmt
there must be one simple condition at least in join filters which simple condition is source_table's column equals to target table's same column
*/
int ObTransformJoinElimination::check_semi_join_condition(ObDMLStmt *stmt,
ObIArray<ObRawExpr*> &semi_conds,
const TableItem *source_table,
@ -2597,7 +2593,6 @@ int ObTransformJoinElimination::check_semi_join_condition(ObDMLStmt *stmt,
bool &is_simple_filter)
{
int ret = OB_SUCCESS;
bool source_table_has_filter = false;
is_simple_join_condition = true;
target_tables_have_filter = false;
is_simple_filter = true;
@ -2614,7 +2609,7 @@ int ObTransformJoinElimination::check_semi_join_condition(ObDMLStmt *stmt,
ret = OB_ERR_UNEXPECTED;
LOG_WARN("expr is null", K(ret));
} else if (!expr->get_relation_ids().has_member(right_idx)) {
source_table_has_filter = true;
/* do nothing */
} else if (!expr->get_relation_ids().has_member(left_idx)) {
target_tables_have_filter = true;
if (T_OP_OR == expr->get_expr_type()) { // complex right table filter
@ -2651,17 +2646,38 @@ int ObTransformJoinElimination::check_semi_join_condition(ObDMLStmt *stmt,
} else {/*do nothing*/}
}
}
/* source table is required in not null side, bad case:
select * from (t2 left join t1 on t2.c1 = t1.c1) semi join t1 t;
--> following rewriting is wrong when t1 is a empty table.
select * from t2 left join t1 on t2.c1 = t1.c1;
The following logic can be processed more finely
if source table is on null side, but where_condition or on_condition has null reject propertycan also do this optimization.
but this is a very corner case, so may modify oneday when there is a need
*/
if (OB_SUCC(ret) && is_simple_join_condition && source_exprs.empty()) {
bool is_on_null_side = true;
if (!source_table_has_filter) {
is_simple_join_condition = false;
} else if (OB_FAIL(ObOptimizerUtil::is_table_on_null_side(stmt,
source_table->table_id_,
is_on_null_side))) {
bool has_null_reject = false;
ObRelIds left_ids;
if (OB_FAIL(ObOptimizerUtil::is_table_on_null_side(stmt,
source_table->table_id_,
is_on_null_side))) {
LOG_WARN("failed to check table is on null side", K(ret));
} else if (is_on_null_side) {
/* source table is required in not null side, bad case:
select * from (t2 left join t1 on t2.c1 = t1.c1) semi join t1 t on t1.c2 = 1 */
} else if (!is_on_null_side) {
/* do nothing */
} else if (OB_FAIL(left_ids.add_member(left_idx))) {
LOG_WARN("failed to add member");
} else if (OB_FAIL(ObTransformUtils::is_null_reject_conditions(semi_conds,
left_ids,
has_null_reject))) {
LOG_WARN("failed to get is null reject conditions", K(ret));
} else if (!has_null_reject &&
OB_FAIL(ObTransformUtils::is_null_reject_conditions(stmt->get_condition_exprs(),
left_ids,
has_null_reject))) {
LOG_WARN("failed to get is null reject conditions", K(ret));
} else if (!has_null_reject) {
is_simple_join_condition = false;
}
}
@ -2684,7 +2700,6 @@ int ObTransformJoinElimination::check_semi_join_condition(ObDMLStmt *stmt,
bool &is_simple_filter)
{
int ret = OB_SUCCESS;
bool source_table_has_filter = false;
is_simple_join_condition = true;
target_tables_have_filter = false;
is_simple_filter = true;
@ -2701,7 +2716,7 @@ int ObTransformJoinElimination::check_semi_join_condition(ObDMLStmt *stmt,
ret = OB_ERR_UNEXPECTED;
LOG_WARN("expr is null", K(ret));
} else if (!select_relids.at(i).has_member(right_idx)) {
source_table_has_filter = true;
/* do nothing */
} else if (!expr->get_relation_ids().has_member(left_idx)) {
target_tables_have_filter = true;
if (T_OP_OR == expr->get_expr_type()) { // complex right table filter
@ -2750,15 +2765,11 @@ int ObTransformJoinElimination::check_semi_join_condition(ObDMLStmt *stmt,
}
if (OB_SUCC(ret) && is_simple_join_condition && source_exprs.empty()) {
bool is_on_null_side = true;
if (!source_table_has_filter) {
is_simple_join_condition = false;
} else if (OB_FAIL(ObOptimizerUtil::is_table_on_null_side(stmt,
source_table->table_id_,
is_on_null_side))) {
if (OB_FAIL(ObOptimizerUtil::is_table_on_null_side(stmt,
source_table->table_id_,
is_on_null_side))) {
LOG_WARN("failed to check table is on null side", K(ret));
} else if (is_on_null_side) {
/* source table is required in not null side, bad case:
select * from (t2 left join t1 on t2.c1 = t1.c1) semi join t1 t on t1.c2 = 1 */
is_simple_join_condition = false;
}
}

View File

@ -1781,8 +1781,13 @@ int ObTransformOrExpansion::may_expr_extract_query_range(const ObDMLStmt *stmt,
}
if (OB_SUCC(ret) && !is_match) {
const ObItemType com_type = expr->get_expr_type();
// EQ、NSEQ、LE、LT、GE、GT、NE、IS、IS_NOT
if ((T_OP_EQ <= com_type && T_OP_NE >= com_type) || T_OP_IS == com_type || T_OP_IS_NOT == com_type) {
if (expr->has_flag(CNT_COLUMN) &&
(expr->has_flag(IS_ROWID_SIMPLE_COND) || expr->has_flag(IS_ROWID_RANGE_COND))) {
//rowid = const or rowid belong const range can choose primary key.
is_match = true;
} else if ((T_OP_EQ <= com_type && T_OP_NE >= com_type) ||
T_OP_IS == com_type || T_OP_IS_NOT == com_type) {
// EQ、NSEQ、LE、LT、GE、GT、NE、IS、IS_NOT
if (OB_UNLIKELY(expr->get_param_count() != 2) ||
OB_ISNULL(l_expr = expr->get_param_expr(0)) || OB_ISNULL(r_expr = expr->get_param_expr(1))) {
ret = OB_ERR_UNEXPECTED;
@ -1820,10 +1825,6 @@ int ObTransformOrExpansion::may_expr_extract_query_range(const ObDMLStmt *stmt,
} else if (r_expr->is_const_expr() && r2_expr->is_const_expr()) {
is_right_const = true;
}
} else if (expr->has_flag(CNT_COLUMN) &&
(expr->has_flag(IS_ROWID_SIMPLE_COND) || expr->has_flag(IS_ROWID_RANGE_COND))) {
//rowid = const or rowid belong const range can choose primary key.
is_match = true;
}
if (OB_SUCC(ret) && !is_match && is_right_const) {
if (OB_FAIL(ObOptimizerUtil::get_expr_without_lossless_cast(l_expr, l_expr))) {