fix master bugs in rewrite
This commit is contained in:
parent
3895cfc3e4
commit
d49644bc7d
@ -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 property,can 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;
|
||||
}
|
||||
}
|
||||
|
@ -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))) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user