[CP] fix deduce NOT NULL attribute by aggr filter incorrectly
This commit is contained in:
parent
b9e0726dfe
commit
1756434624
@ -268,12 +268,14 @@ int ObTransformSimplifyExpr::replace_is_null_condition(ObDMLStmt *stmt, bool &tr
|
||||
}
|
||||
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(not_null_ctx.remove_having_filter(sel_stmt->get_having_exprs().at(i)))){
|
||||
bool exist_in_ctx = ObOptimizerUtil::find_item(not_null_ctx.having_filters_,
|
||||
sel_stmt->get_having_exprs().at(i));
|
||||
if (exist_in_ctx && 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)))) {
|
||||
} else if (exist_in_ctx && 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;
|
||||
@ -1309,7 +1311,9 @@ int ObTransformSimplifyExpr::remove_dummy_nvl(ObDMLStmt *stmt,
|
||||
if (OB_SUCC(ret) && stmt->is_select_stmt() && !static_cast<ObSelectStmt *>(stmt)->is_scala_group_by()) {
|
||||
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(not_null_ctx.remove_having_filter(sel_stmt->get_having_exprs().at(i)))){
|
||||
bool exist_in_ctx = ObOptimizerUtil::find_item(not_null_ctx.having_filters_,
|
||||
sel_stmt->get_having_exprs().at(i));
|
||||
if (exist_in_ctx && 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_remove_dummy_nvl(stmt,
|
||||
sel_stmt->get_having_exprs().at(i),
|
||||
@ -1317,7 +1321,7 @@ int ObTransformSimplifyExpr::remove_dummy_nvl(ObDMLStmt *stmt,
|
||||
ignore_exprs,
|
||||
trans_happened))) {
|
||||
LOG_WARN("failed to remove dummy nvl", K(ret));
|
||||
} else if (OB_FAIL(not_null_ctx.add_having_filter(sel_stmt->get_having_exprs().at(i)))) {
|
||||
} else if (exist_in_ctx && OB_FAIL(not_null_ctx.add_having_filter(sel_stmt->get_having_exprs().at(i)))) {
|
||||
LOG_WARN("failed to add filter", K(ret));
|
||||
}
|
||||
}
|
||||
|
@ -2065,12 +2065,48 @@ int ObNotNullContext::generate_stmt_context(int64_t stmt_context)
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret) && stmt_context >= NULLABLE_SCOPE::NS_TOP &&
|
||||
stmt->is_select_stmt()) {
|
||||
if (OB_FAIL(having_filters_.assign(
|
||||
static_cast<const ObSelectStmt *>(stmt)->get_having_exprs()))) {
|
||||
if (OB_SUCC(ret) && stmt_context >= NULLABLE_SCOPE::NS_TOP && stmt->is_select_stmt()) {
|
||||
// Exprs in "in_group_clause" mean different things when used in basic expressions with added NULLs versus in aggregate functions without NULLs.
|
||||
// Thus, aggregate functions with such group exprs cannot be used to infer a not-null attribute.
|
||||
// e.g. select c1, max(c2) from t1 group by rollup(c1) having max(c1) > 0 and nvl(c1, 0) is null);
|
||||
// can't deduce `c1 is not null` by `max(c1) > 0` to simplify nvl(c1, 0)
|
||||
const ObSelectStmt *sel_stmt = static_cast<const ObSelectStmt *>(stmt);
|
||||
if (OB_FAIL(ObTransformUtils::get_having_filters_for_deduce(sel_stmt,
|
||||
sel_stmt->get_having_exprs(),
|
||||
group_clause_exprs_,
|
||||
having_filters_))) {
|
||||
LOG_WARN("failed to get having filters for deduce", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObTransformUtils::get_having_filters_for_deduce(const ObSelectStmt *sel_stmt,
|
||||
const ObIArray<ObRawExpr*> &raw_having_exprs,
|
||||
const ObIArray<ObRawExpr*> &group_clause_exprs,
|
||||
ObIArray<ObRawExpr*> &having_exprs_for_deduce)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
bool has_target = false;
|
||||
if (OB_ISNULL(sel_stmt)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null", K(ret));
|
||||
} else if (sel_stmt->get_rollup_expr_size() == 0 && sel_stmt->get_cube_items_size() == 0 &&
|
||||
sel_stmt->get_grouping_sets_items_size() == 0) {
|
||||
if (OB_FAIL(having_exprs_for_deduce.assign(raw_having_exprs))) {
|
||||
LOG_WARN("failed to assign having exprs", K(ret));
|
||||
}
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < raw_having_exprs.count(); ++i) {
|
||||
if (OB_ISNULL(raw_having_exprs.at(i))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null", K(ret));
|
||||
} else if (raw_having_exprs.at(i)->has_flag(CNT_AGG)) {
|
||||
// do nothing
|
||||
} else if (OB_FAIL(having_exprs_for_deduce.push_back(raw_having_exprs.at(i)))) {
|
||||
LOG_WARN("failed to push back having expr", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -1955,6 +1955,10 @@ public:
|
||||
ObRawExpr *expr,
|
||||
bool &eq_zero,
|
||||
ObIArray<ObExprConstraint> &constraints);
|
||||
static int get_having_filters_for_deduce(const ObSelectStmt* sel_stmt,
|
||||
const ObIArray<ObRawExpr*> &raw_having_exprs,
|
||||
const ObIArray<ObRawExpr*> &group_clause_exprs,
|
||||
ObIArray<ObRawExpr*> &having_exprs_for_deduce);
|
||||
private:
|
||||
static int inner_get_lazy_left_join(ObDMLStmt *stmt,
|
||||
TableItem *table,
|
||||
|
Loading…
x
Reference in New Issue
Block a user