Fix simplify is null bug
This commit is contained in:
@ -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 ¬_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 ¬_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) {
|
||||||
|
|||||||
@ -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 ¬_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 ¬_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,
|
||||||
|
|||||||
@ -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));
|
||||||
|
|||||||
@ -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_;
|
||||||
|
|||||||
Reference in New Issue
Block a user