提交 a0a8950d 编写于 作者: O obdev 提交者: wangzelin.wzl

fix join elimination bug

上级 fb85dd28
......@@ -698,29 +698,70 @@ int ObTransformJoinElimination::check_transform_validity_outer_join(
}
if (OB_SUCC(ret) && need_check_relation_exprs) {
ObSqlBitSet<8, int64_t> rel_ids;
ObSqlBitSet<> semi_left_rel_ids;
ObSqlBitSet<8, int64_t> right_rel_ids;
ObSEArray<ObRawExpr *, 8> join_conditions;
if (OB_FAIL(join_conditions.assign(joined_table->join_conditions_))) {
LOG_WARN("failed to push back to join conditions.", K(ret));
} else if (OB_FAIL(extract_semi_left_rel_ids(stmt,
joined_table->right_table_,
semi_left_rel_ids))) {
LOG_WARN("failed to extract semi info left table rel ids", K(ret));
} else if (OB_FAIL(extract_child_conditions(stmt,
joined_table->right_table_,
join_conditions,
rel_ids))) {
joined_table->right_table_,
join_conditions,
right_rel_ids))) {
LOG_WARN("failed to extract right child exprs.", K(ret));
} else if (OB_FAIL(adjust_relation_exprs(rel_ids,// right table not use by any other expr
join_conditions,
relation_exprs,
is_valid))) {
} else if (OB_FAIL(adjust_relation_exprs(semi_left_rel_ids,
right_rel_ids,// right table not use by any other expr
join_conditions,
relation_exprs,
is_valid))) {
LOG_WARN("failed to check expr in select items.", K(ret));
}
}
return ret;
}
int ObTransformJoinElimination::extract_semi_left_rel_ids(ObDMLStmt *stmt,
TableItem *table_item,
ObSqlBitSet<> &semi_left_rel_ids)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(stmt) || OB_ISNULL(table_item)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
} else {
for (int64_t i = 0; OB_SUCC(ret) && i < stmt->get_semi_infos().count(); ++i) {
SemiInfo *semi = stmt->get_semi_infos().at(i);
ObSEArray<uint64_t, 4> r_table_ids;
ObSEArray<uint64_t, 4> common_table_ids;
if (OB_ISNULL(semi)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("semi info is null", K(ret));
} else if (table_item->is_joined_table() &&
OB_FAIL(r_table_ids.assign(static_cast<JoinedTable *>(table_item)->single_table_ids_))) {
} else if (!table_item->is_joined_table() &&
OB_FAIL(r_table_ids.push_back(table_item->table_id_))) {
LOG_WARN("failed to push back joined table", K(ret));
} else if (OB_FAIL(ObOptimizerUtil::intersect(semi->left_table_ids_, r_table_ids, common_table_ids))) {
LOG_WARN("failed to intersect table ids", K(ret));
} else if (!common_table_ids.empty()) {
for (int64_t j = 0; OB_SUCC(ret) && j < common_table_ids.count(); ++j) {
if (OB_FAIL(semi_left_rel_ids.add_member(stmt->get_table_bit_index(common_table_ids.at(j))))) {
LOG_WARN("failed to add semi join left table ids", K(ret));
}
}
}
}
}
return ret;
}
int ObTransformJoinElimination::extract_child_conditions(ObDMLStmt *stmt,
TableItem *table_item,
ObIArray<ObRawExpr *> &join_conditions,
ObSqlBitSet<8, int64_t> &rel_ids)
ObSqlBitSet<8, int64_t> &right_rel_ids)
{
int ret = OB_SUCCESS;
bool is_stack_overflow = false;
......@@ -737,12 +778,12 @@ int ObTransformJoinElimination::extract_child_conditions(ObDMLStmt *stmt,
if (OB_FAIL(SMART_CALL(extract_child_conditions(stmt,
joined_table->left_table_,
join_conditions,
rel_ids)))) {
right_rel_ids)))) {
LOG_WARN("failed to remove right tables from stmt", K(ret));
} else if (OB_FAIL(SMART_CALL(extract_child_conditions(stmt,
joined_table->right_table_,
join_conditions,
rel_ids)))) {
right_rel_ids)))) {
LOG_WARN("failed to remove right tables from stmt", K(ret));
} else {
int64_t N = joined_table->join_conditions_.count();
......@@ -752,13 +793,14 @@ int ObTransformJoinElimination::extract_child_conditions(ObDMLStmt *stmt,
} else { /* do nothing. */ }
}
}
} else if (OB_FAIL(rel_ids.add_member(stmt->get_table_bit_index(table_item->table_id_)))) {
} else if (OB_FAIL(right_rel_ids.add_member(stmt->get_table_bit_index(table_item->table_id_)))) {
LOG_WARN("failed to add member to rel ids.", K(ret));
} else { /* do nothing. */ }
return ret;
}
int ObTransformJoinElimination::adjust_relation_exprs(const ObSqlBitSet<8, int64_t> &rel_ids,
int ObTransformJoinElimination::adjust_relation_exprs(const ObSqlBitSet<> &semi_left_rel_ids,
const ObSqlBitSet<8, int64_t> &right_rel_ids,
const ObIArray<ObRawExpr *> &join_conditions,
ObIArray<ObRawExpr *> &relation_exprs,
bool &is_valid)
......@@ -771,6 +813,8 @@ int ObTransformJoinElimination::adjust_relation_exprs(const ObSqlBitSet<8, int64
LOG_WARN("failed to assign to all exprs.", K(ret));
} else if (OB_FAIL(ObOptimizerUtil::remove_item(all_exprs, join_conditions))) {
LOG_WARN("faile to remove item from all stmt exprs.", K(ret));
} else if (OB_FAIL(select_rel_ids.add_members2(semi_left_rel_ids))) {
LOG_WARN("failed to add rel ids", K(ret));
}
for (int64_t i = 0; OB_SUCC(ret) && i < all_exprs.count(); i++) {
if (OB_ISNULL(all_exprs.at(i))) {
......@@ -781,7 +825,7 @@ int ObTransformJoinElimination::adjust_relation_exprs(const ObSqlBitSet<8, int64
} else { /*do nothing.*/ }
}
if (OB_SUCC(ret)) {
is_valid = select_rel_ids.overlap2(rel_ids) ? false : true;
is_valid = select_rel_ids.overlap2(right_rel_ids) ? false : true;
if (is_valid && OB_FAIL(relation_exprs.assign(all_exprs))) {
LOG_WARN("failed to assign cross stmt exprs.", K(ret));
} else { /* do nothing. */ }
......
......@@ -196,16 +196,19 @@ private:
const ObIArray<int64_t> &output_map,
ObIArray<ObRawExpr *> &source_exprs,
ObIArray<ObRawExpr *> &target_exprs);
int extract_semi_left_rel_ids(ObDMLStmt *stmt,
TableItem *table_item,
ObSqlBitSet<> &semi_left_rel_ids);
int extract_child_conditions(ObDMLStmt *stmt,
TableItem *source_table,
ObIArray<ObRawExpr *> &join_conditions,
ObSqlBitSet<8, int64_t> &rel_ids);
ObSqlBitSet<8, int64_t> &right_rel_ids);
int adjust_relation_exprs(const ObSqlBitSet<8, int64_t> &rel_ids,
const ObIArray<ObRawExpr *> &join_conditions,
ObIArray<ObRawExpr *> &relation_exprs,
bool &is_valid);
int adjust_relation_exprs(const ObSqlBitSet<> &semi_left_rel_ids,
const ObSqlBitSet<8, int64_t> &right_rel_ids,
const ObIArray<ObRawExpr *> &join_conditions,
ObIArray<ObRawExpr *> &relation_exprs,
bool &is_valid);
int extract_equal_join_columns(const ObIArray<ObRawExpr *> &join_conds,
const TableItem *source_table,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册