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;
LOG_WARN("data member or parameter is NULL", K(stmt), K(ctx_));
} 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) {
ObRawExpr *cond = NULL;
if (OB_ISNULL(cond = stmt->get_condition_expr(i))) {
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))) {
if (OB_FAIL(inner_replace_is_null_condition(
stmt, stmt->get_condition_exprs().at(i), not_null_ctx, is_happened))) {
LOG_WARN("failed to replace is null expr", K(ret));
} else {
trans_happened |= is_happened;
}
}
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);
for (int64_t i = 0; OB_SUCC(ret) && i < sel_stmt->get_having_expr_size(); ++i) {
if (OB_FAIL(inner_replace_is_null_condition(
sel_stmt, sel_stmt->get_having_exprs().at(i), is_happened))) {
if (OB_FAIL(not_null_ctx.remove_having_filter(sel_stmt->get_having_exprs().at(i)))){
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));
} 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 {
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,
ObRawExpr *&expr,
ObNotNullContext &not_null_ctx,
bool &trans_happened)
{
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))) {
ret = OB_ERR_UNEXPECTED;
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));
} else {
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_NOT == expr->get_expr_type())) {
// 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));
} else {
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,
ObRawExpr *&expr,
ObNotNullContext &not_null_ctx,
bool &trans_happened)
{
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();
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));
} else if (OB_FAIL(ObTransformUtils::is_expr_not_null(ctx_, stmt, col_expr,
NULLABLE_SCOPE::NS_FROM,
} else if (OB_FAIL(ObTransformUtils::is_expr_not_null(not_null_ctx, col_expr,
is_not_null, &constraints))) {
LOG_WARN("failed to check expr not null", K(ret));
} else if (is_not_null) {

View File

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

View File

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

View File

@ -80,9 +80,24 @@ struct ObNotNullContext
int add_joined_table(const JoinedTable *table);
int add_filter(const ObIArray<ObRawExpr *> &filters);
int add_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:
// params
ObExecContext *exec_ctx_;