Fix: When the generated column is equal conds, the constant will not find the corresponding table information.

This commit is contained in:
yaojing624 2023-10-24 04:09:56 +00:00 committed by ob-robot
parent a0276e0c49
commit 58f226a3da
3 changed files with 114 additions and 0 deletions

View File

@ -246,6 +246,114 @@ int ObLogJoin::get_plan_item_info(PlanText &plan_text,
return ret;
}
int ObLogJoin::adjust_join_conds(ObIArray<ObRawExpr *> &dest_exprs)
{
int ret = OB_SUCCESS;
int64_t dest_num = dest_exprs.count();
for (int64_t i = 0; OB_SUCC(ret) && i < dest_num; ++i) {
ObRawExpr *&cur_expr = dest_exprs.at(i);
ObRawExpr *lexpr = NULL;
ObRawExpr *rexpr = NULL;
if (OB_ISNULL(lexpr = cur_expr->get_param_expr(0)) ||
OB_ISNULL(rexpr = cur_expr->get_param_expr(1))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid argument", K(lexpr), K(rexpr), K(ret));
} else if (!(T_OP_EQ == cur_expr->get_expr_type() ||
T_OP_NSEQ == cur_expr->get_expr_type())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid argument", K(cur_expr->get_expr_type()), K(ret));
} else if (T_OP_EQ == cur_expr->get_expr_type()) {
ObSEArray<ObRawExpr*, 4> left_columns;
ObSEArray<ObRawExpr*, 4> right_columns;
if (OB_FAIL(ObRawExprUtils::extract_column_exprs(lexpr, left_columns))) {
LOG_WARN("extract column exprs failed", K(ret), K(lexpr));
} else if (OB_FAIL(ObRawExprUtils::extract_column_exprs(rexpr, right_columns))) {
LOG_WARN("extract column exprs failed", K(ret), K(rexpr));
} else {
bool is_conclude_gen_col = false;
for (int64_t j = 0; OB_SUCC(ret) && !is_conclude_gen_col &&
j < left_columns.count(); ++j) {
ObRawExpr *dep_column = left_columns.at(j);
if (OB_ISNULL(dep_column)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("deps_column is null");
} else if (!dep_column->is_column_ref_expr()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("dep column is invalid", K(ret), KPC(dep_column));
} else if (static_cast<ObColumnRefRawExpr *>(dep_column)->is_generated_column()) {
is_conclude_gen_col = true;
}
}
for (int64_t j = 0; OB_SUCC(ret) && !is_conclude_gen_col &&
j < right_columns.count(); ++j) {
ObRawExpr *dep_column = right_columns.at(j);
if (OB_ISNULL(dep_column)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("deps_column is null");
} else if (!dep_column->is_column_ref_expr()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("dep column is invalid", K(ret), KPC(dep_column));
} else if (static_cast<ObColumnRefRawExpr *>(dep_column)->is_generated_column()) {
is_conclude_gen_col = true;
}
}
if (OB_SUCC(ret) && is_conclude_gen_col) {
bool is_opposite = false;
if (OB_FAIL(calc_equal_cond_opposite(
*cur_expr, is_opposite))) {
LOG_WARN("failed to calc equal condition opposite", K(ret));
} else {
LOG_INFO("do is_opposite", K(ret), K(is_opposite));
// Before generating column replacement, determine whether the dependent expression
// is a constant expression. If so, you need to change the left and right node positions
// in advance.
if (is_opposite) {
std::swap(cur_expr->get_param_expr(0), cur_expr->get_param_expr(1));
}
}
}
}
}
}
return ret;
}
int ObLogJoin::calc_equal_cond_opposite(const ObRawExpr &raw_expr,
bool &is_opposite)
{
int ret = OB_SUCCESS;
is_opposite = false;
const ObLogicalOperator *left_child = NULL;
const ObLogicalOperator *right_child = NULL;
const ObRawExpr *lexpr = NULL;
const ObRawExpr *rexpr = NULL;
if (OB_ISNULL(lexpr = raw_expr.get_param_expr(0)) ||
OB_ISNULL(rexpr = raw_expr.get_param_expr(1))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid argument", K(lexpr), K(rexpr), K(ret));
} else if (!(T_OP_EQ == raw_expr.get_expr_type() ||
T_OP_NSEQ == raw_expr.get_expr_type())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid argument", K(raw_expr.get_expr_type()), K(ret));
} else if (OB_ISNULL(left_child = this->get_child(0)) ||
OB_ISNULL(right_child = this->get_child(1))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid argument", K(left_child), K(right_child), K(ret));
} else if (lexpr->get_relation_ids().is_subset(left_child->get_table_set())
&& rexpr->get_relation_ids().is_subset(right_child->get_table_set())) {
is_opposite = false;
} else if (lexpr->get_relation_ids().is_subset(right_child->get_table_set())
&& rexpr->get_relation_ids().is_subset(left_child->get_table_set())) {
is_opposite = true;
} else {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid equal condition", K(this), K(raw_expr), K(ret));
}
return ret;
}
int ObLogJoin::inner_replace_op_exprs(ObRawExprReplacer &replacer)
{
int ret = OB_SUCCESS;

View File

@ -99,6 +99,9 @@ namespace sql
const common::ObIArray<ObRawExpr *> &get_join_conditions() const { return join_conditions_; }
common::ObIArray<ObRawExpr *> &get_join_filters() { return join_filters_; }
int adjust_join_conds(ObIArray<ObRawExpr *> &dest_exprs);
int calc_equal_cond_opposite(const ObRawExpr &raw_expr,
bool &is_opposite);
virtual int inner_replace_op_exprs(ObRawExprReplacer &replacer) override;
const common::ObIArray<ObOrderDirection> &get_merge_directions() const { return merge_directions_; }

View File

@ -11813,6 +11813,9 @@ int ObLogPlan::adjust_final_plan_info(ObLogicalOperator *&op)
} else if (log_op_def::LOG_SUBPLAN_FILTER == op->get_type() &&
OB_FAIL(static_cast<ObLogSubPlanFilter*>(op)->check_and_set_das_group_rescan())) {
LOG_WARN("failed to set use batch spf", K(ret));
} else if (log_op_def::LOG_JOIN == op->get_type() &&
OB_FAIL(static_cast<ObLogJoin*>(op)->adjust_join_conds(static_cast<ObLogJoin *>(op)->get_join_conditions()))) {
LOG_WARN("failed to adjust join conds", K(ret));
} else { /*do nothing*/ }
}
}