Fix simplify is null bug

This commit is contained in:
xianyu-w
2023-01-09 12:38:06 +00:00
committed by ob-robot
parent c153bc2b09
commit 2c5e745e15
4 changed files with 88 additions and 24 deletions

View File

@ -172,24 +172,32 @@ int ObTransformSimplifyExpr::replace_is_null_condition(ObDMLStmt *stmt, bool &tr
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
LOG_WARN("data member or parameter is NULL", K(stmt), K(ctx_)); LOG_WARN("data member or parameter is NULL", K(stmt), K(ctx_));
} else if (stmt->is_sel_del_upd()) { } else if (stmt->is_sel_del_upd()) {
ObNotNullContext not_null_ctx(*ctx_, stmt);
if (OB_FAIL(not_null_ctx.generate_stmt_context(NULLABLE_SCOPE::NS_FROM))){
LOG_WARN("failed to generate not null context", K(ret));
}
for (int64_t i = 0; OB_SUCC(ret) && i < stmt->get_condition_size(); ++i) { for (int64_t i = 0; OB_SUCC(ret) && i < stmt->get_condition_size(); ++i) {
ObRawExpr *cond = NULL; if (OB_FAIL(inner_replace_is_null_condition(
if (OB_ISNULL(cond = stmt->get_condition_expr(i))) { stmt, stmt->get_condition_exprs().at(i), not_null_ctx, is_happened))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("condition expr is null", K(ret));
} else if (OB_FAIL(inner_replace_is_null_condition(
stmt, stmt->get_condition_exprs().at(i), is_happened))) {
LOG_WARN("failed to replace is null expr", K(ret)); LOG_WARN("failed to replace is null expr", K(ret));
} else { } else {
trans_happened |= is_happened; trans_happened |= is_happened;
} }
} }
if (OB_SUCC(ret) && stmt->is_select_stmt()) { if (OB_SUCC(ret) && stmt->is_select_stmt()) {
not_null_ctx.reset();
if (OB_FAIL(not_null_ctx.generate_stmt_context(NULLABLE_SCOPE::NS_TOP))){
LOG_WARN("failed to generate not null context", K(ret));
}
ObSelectStmt *sel_stmt = static_cast<ObSelectStmt *>(stmt); ObSelectStmt *sel_stmt = static_cast<ObSelectStmt *>(stmt);
for (int64_t i = 0; OB_SUCC(ret) && i < sel_stmt->get_having_expr_size(); ++i) { for (int64_t i = 0; OB_SUCC(ret) && i < sel_stmt->get_having_expr_size(); ++i) {
if (OB_FAIL(inner_replace_is_null_condition( if (OB_FAIL(not_null_ctx.remove_having_filter(sel_stmt->get_having_exprs().at(i)))){
sel_stmt, sel_stmt->get_having_exprs().at(i), is_happened))) { LOG_WARN("failed to remove filter", K(ret));
} else if (OB_FAIL(inner_replace_is_null_condition(
sel_stmt, sel_stmt->get_having_exprs().at(i), not_null_ctx, is_happened))) {
LOG_WARN("failed to replace is null expr", K(ret)); LOG_WARN("failed to replace is null expr", K(ret));
} else if (OB_FAIL(not_null_ctx.add_having_filter(sel_stmt->get_having_exprs().at(i)))) {
LOG_WARN("failed to add filter", K(ret));
} else { } else {
trans_happened |= is_happened; trans_happened |= is_happened;
} }
@ -201,6 +209,7 @@ int ObTransformSimplifyExpr::replace_is_null_condition(ObDMLStmt *stmt, bool &tr
int ObTransformSimplifyExpr::inner_replace_is_null_condition(ObDMLStmt *stmt, int ObTransformSimplifyExpr::inner_replace_is_null_condition(ObDMLStmt *stmt,
ObRawExpr *&expr, ObRawExpr *&expr,
ObNotNullContext &not_null_ctx,
bool &trans_happened) bool &trans_happened)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
@ -223,7 +232,10 @@ int ObTransformSimplifyExpr::inner_replace_is_null_condition(ObDMLStmt *stmt,
if (OB_ISNULL(temp = op_expr->get_param_expr(i))) { if (OB_ISNULL(temp = op_expr->get_param_expr(i))) {
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
LOG_WARN("null expr", K(ret)); LOG_WARN("null expr", K(ret));
} else if (OB_FAIL(SMART_CALL(inner_replace_is_null_condition(stmt, temp, is_happened)))) { } else if (OB_FAIL(SMART_CALL(inner_replace_is_null_condition(stmt,
temp,
not_null_ctx,
is_happened)))) {
LOG_WARN("failed to replace is null expr", K(ret)); LOG_WARN("failed to replace is null expr", K(ret));
} else { } else {
trans_happened |= is_happened; trans_happened |= is_happened;
@ -236,7 +248,7 @@ int ObTransformSimplifyExpr::inner_replace_is_null_condition(ObDMLStmt *stmt,
&& (T_OP_IS == expr->get_expr_type() && (T_OP_IS == expr->get_expr_type()
|| T_OP_IS_NOT == expr->get_expr_type())) { || T_OP_IS_NOT == expr->get_expr_type())) {
// do transforamtion for its own exprs // do transforamtion for its own exprs
if (OB_FAIL(do_replace_is_null_condition(stmt, expr, is_happened))) { if (OB_FAIL(do_replace_is_null_condition(stmt, expr, not_null_ctx, is_happened))) {
LOG_WARN("failed to replace is null condition", K(ret)); LOG_WARN("failed to replace is null condition", K(ret));
} else { } else {
trans_happened |= is_happened; trans_happened |= is_happened;
@ -256,6 +268,7 @@ int ObTransformSimplifyExpr::inner_replace_is_null_condition(ObDMLStmt *stmt,
int ObTransformSimplifyExpr::do_replace_is_null_condition(ObDMLStmt *stmt, int ObTransformSimplifyExpr::do_replace_is_null_condition(ObDMLStmt *stmt,
ObRawExpr *&expr, ObRawExpr *&expr,
ObNotNullContext &not_null_ctx,
bool &trans_happened) bool &trans_happened)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
@ -295,8 +308,7 @@ int ObTransformSimplifyExpr::do_replace_is_null_condition(ObDMLStmt *stmt,
uint64_t table_id = col_expr->get_table_id(); uint64_t table_id = col_expr->get_table_id();
if (OB_FAIL(ctx_->session_info_->get_sql_auto_is_null(sql_auto_is_null))) { if (OB_FAIL(ctx_->session_info_->get_sql_auto_is_null(sql_auto_is_null))) {
LOG_WARN("fail to get sql_auto_is_null system variable", K(ret)); LOG_WARN("fail to get sql_auto_is_null system variable", K(ret));
} else if (OB_FAIL(ObTransformUtils::is_expr_not_null(ctx_, stmt, col_expr, } else if (OB_FAIL(ObTransformUtils::is_expr_not_null(not_null_ctx, col_expr,
NULLABLE_SCOPE::NS_FROM,
is_not_null, &constraints))) { is_not_null, &constraints))) {
LOG_WARN("failed to check expr not null", K(ret)); LOG_WARN("failed to check expr not null", K(ret));
} else if (is_not_null) { } else if (is_not_null) {

View File

@ -18,6 +18,8 @@
namespace oceanbase { namespace oceanbase {
namespace sql { namespace sql {
struct ObNotNullContext;
class ObTransformSimplifyExpr : public ObTransformRule class ObTransformSimplifyExpr : public ObTransformRule
{ {
public: public:
@ -34,9 +36,11 @@ private:
int replace_is_null_condition(ObDMLStmt *stmt, bool &trans_happened); int replace_is_null_condition(ObDMLStmt *stmt, bool &trans_happened);
int inner_replace_is_null_condition(ObDMLStmt *stmt, int inner_replace_is_null_condition(ObDMLStmt *stmt,
ObRawExpr *&expr, ObRawExpr *&expr,
ObNotNullContext &not_null_ctx,
bool &trans_happened); bool &trans_happened);
int do_replace_is_null_condition(ObDMLStmt *stmt, int do_replace_is_null_condition(ObDMLStmt *stmt,
ObRawExpr *&expr, ObRawExpr *&expr,
ObNotNullContext &not_null_ctx,
bool &trans_happened); bool &trans_happened);
int replace_op_null_condition(ObDMLStmt *stmt, bool &trans_happened); int replace_op_null_condition(ObDMLStmt *stmt, bool &trans_happened);
int replace_cmp_null_condition(ObRawExpr *&expr, int replace_cmp_null_condition(ObRawExpr *&expr,

View File

@ -1729,11 +1729,34 @@ int ObNotNullContext::add_filter(const ObIArray<ObRawExpr *> &filters)
return ret; return ret;
} }
int ObNotNullContext::add_filter(ObRawExpr *filter)
{
return filters_.push_back(filter);
}
int ObNotNullContext::remove_filter(ObRawExpr *filter) int ObNotNullContext::remove_filter(ObRawExpr *filter)
{ {
return ObOptimizerUtil::remove_item(filters_, filter); return ObOptimizerUtil::remove_item(filters_, filter);
} }
int ObNotNullContext::add_having_filter(const ObIArray<ObRawExpr *> &filters)
{
int ret = OB_SUCCESS;
if (OB_FAIL(append(having_filters_, filters))) {
LOG_WARN("failed to append filters", K(ret));
}
return ret;
}
int ObNotNullContext::add_having_filter(ObRawExpr *filter)
{
return having_filters_.push_back(filter);
}
int ObNotNullContext::remove_having_filter(ObRawExpr *filter)
{
return ObOptimizerUtil::remove_item(having_filters_, filter);
}
int ObTransformUtils::get_outer_join_right_tables(const JoinedTable &joined_table, int ObTransformUtils::get_outer_join_right_tables(const JoinedTable &joined_table,
ObIArray<uint64_t> &table_ids) ObIArray<uint64_t> &table_ids)
{ {
@ -1754,13 +1777,26 @@ int ObTransformUtils::get_outer_join_right_tables(const JoinedTable &joined_tabl
table_ids)))) { table_ids)))) {
LOG_WARN("failed to visit right table", K(ret)); LOG_WARN("failed to visit right table", K(ret));
} }
} } else if (joined_table.is_full_join()){
if (OB_SUCC(ret) && (joined_table.is_left_join() || if (left->is_joined_table()) {
joined_table.is_full_join())) { if (OB_FAIL(append(table_ids, static_cast<JoinedTable *>(left)->single_table_ids_))) {
LOG_WARN("failed to append tables ids", K(ret));
}
} else if (OB_FAIL(table_ids.push_back(left->table_id_))) {
LOG_WARN("failed to push back left table id", K(ret));
}
if (OB_SUCC(ret) && right->is_joined_table()) {
if (OB_FAIL(append(table_ids, static_cast<JoinedTable *>(right)->single_table_ids_))) {
LOG_WARN("failed to append tables ids", K(ret));
}
} else if (OB_FAIL(table_ids.push_back(right->table_id_))) {
LOG_WARN("failed to push back right table id", K(ret));
}
} else if (joined_table.is_left_join()) {
if (left->is_joined_table() && if (left->is_joined_table() &&
OB_FAIL(SMART_CALL(get_outer_join_right_tables(static_cast<JoinedTable&>(*left), OB_FAIL(SMART_CALL(get_outer_join_right_tables(static_cast<JoinedTable&>(*left),
table_ids)))) { table_ids)))){
LOG_WARN("failed to visit left table", K(ret)); LOG_WARN("failed to visit left table", K(ret));
} else if (right->is_joined_table()) { } else if (right->is_joined_table()) {
if (OB_FAIL(append(table_ids, static_cast<JoinedTable *>(right)->single_table_ids_))) { if (OB_FAIL(append(table_ids, static_cast<JoinedTable *>(right)->single_table_ids_))) {
LOG_WARN("failed to append tables ids", K(ret)); LOG_WARN("failed to append tables ids", K(ret));
@ -1768,14 +1804,11 @@ int ObTransformUtils::get_outer_join_right_tables(const JoinedTable &joined_tabl
} else if (OB_FAIL(table_ids.push_back(right->table_id_))) { } else if (OB_FAIL(table_ids.push_back(right->table_id_))) {
LOG_WARN("failed to push back right table id", K(ret)); LOG_WARN("failed to push back right table id", K(ret));
} }
} } else if (joined_table.is_right_join()) {
if (OB_SUCC(ret) && (joined_table.is_right_join() ||
joined_table.is_full_join())) {
if (right->is_joined_table() && if (right->is_joined_table() &&
OB_FAIL(SMART_CALL(get_outer_join_right_tables(static_cast<JoinedTable&>(*right), OB_FAIL(SMART_CALL(get_outer_join_right_tables(static_cast<JoinedTable&>(*right),
table_ids)))) { table_ids)))){
LOG_WARN("failed to visit right table", K(ret)); LOG_WARN("failed to visit right table", K(ret));
} else if (left->is_joined_table()) { } else if (left->is_joined_table()) {
if (OB_FAIL(append(table_ids, static_cast<JoinedTable *>(left)->single_table_ids_))) { if (OB_FAIL(append(table_ids, static_cast<JoinedTable *>(left)->single_table_ids_))) {
LOG_WARN("failed to append tables ids", K(ret)); LOG_WARN("failed to append tables ids", K(ret));

View File

@ -81,8 +81,23 @@ struct ObNotNullContext
int add_filter(const ObIArray<ObRawExpr *> &filters); int add_filter(const ObIArray<ObRawExpr *> &filters);
int add_filter(ObRawExpr *filter);
int remove_filter(ObRawExpr *filter); int remove_filter(ObRawExpr *filter);
int add_having_filter(const ObIArray<ObRawExpr *> &filters);
int add_having_filter(ObRawExpr *filter);
int remove_having_filter(ObRawExpr *filter);
inline void reset() {
group_clause_exprs_.reset();
right_table_ids_.reset();
filters_.reset();
having_filters_.reset();
}
public: public:
// params // params
ObExecContext *exec_ctx_; ObExecContext *exec_ctx_;