fix pushdown filter into set stmt bug

This commit is contained in:
zzg19950727
2023-02-24 13:52:25 +00:00
committed by ob-robot
parent 8441f54f6f
commit f6f344d2ca
5 changed files with 108 additions and 45 deletions

View File

@ -6402,57 +6402,58 @@ int ObOptimizerUtil::check_pushdown_filter_for_set(const ObSelectStmt &parent_st
ObIArray<ObRawExpr*> &remain_filters)
{
int ret = OB_SUCCESS;
ObSEArray<ObRawExpr *, 4> child_select_list;
ObSEArray<ObRawExpr *, 4> parent_select_list;
if (OB_FAIL(subquery.get_select_exprs(child_select_list))) {
LOG_WARN("get child stmt select exprs failed", K(ret));
} else if (OB_FAIL(parent_stmt.get_select_exprs(parent_select_list))) {
LOG_WARN("get parent stmt select exprs failed", K(ret));
} else if (child_select_list.count() != parent_select_list.count()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("child stmt select exprs size is incorrect", K(child_select_list.count()),
K(parent_select_list.count()), K(ret));
}
ObSEArray<ObRawExpr *, 4> view_column_exprs;
ObSEArray<ObRawExpr *, 4> set_op_exprs;
ObSEArray<ObRawExpr *, 4> select_exprs;
for (int64_t i = 0; OB_SUCC(ret) && i < pushdown_filters.count(); ++i) {
ObSEArray<ObRawExpr *, 4> view_column_exprs;
ObRawExpr *expr = pushdown_filters.at(i);
if (OB_ISNULL(expr)) {
ObRawExpr *pred = NULL;
bool is_simple_expr = true;
bool pushed = false;
set_op_exprs.reuse();
select_exprs.reuse();
view_column_exprs.reuse();
if (OB_ISNULL(pred = pushdown_filters.at(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null expr", K(ret));
} else if (OB_FAIL(ObTransformUtils::replace_expr(parent_select_list,
child_select_list,
expr))) {
SQL_LOG(WARN, "failed to replace expr", K(ret));
} else if (OB_FAIL(expr->extract_info())) {
LOG_WARN("failed to extract info", K(ret), K(*expr));
} else if (expr->has_flag(CNT_WINDOW_FUNC) ||
expr->has_flag(CNT_AGG) ||
expr->has_flag(CNT_SUB_QUERY) ||
expr->has_flag(CNT_ONETIME)) {
ret = remain_filters.push_back(expr);
} else if (OB_FAIL(ObRawExprUtils::extract_column_exprs(expr, view_column_exprs))) {
LOG_WARN("failed to extract column exprs", K(ret));
} else if (!common_exprs.empty() &&
!subset_exprs(view_column_exprs, common_exprs)) {
//common_exprs为空,说明既没有windown func,也没有group by
ret = remain_filters.push_back(expr);
} else if (OB_FAIL(candi_filters.push_back(expr))) {
LOG_WARN("failed to push back predicate", K(ret));
LOG_WARN("predicate is null", K(ret));
} else if (OB_FAIL(ObRawExprUtils::extract_set_op_exprs(pred, set_op_exprs))) {
LOG_WARN("failed to extract set op exprs", K(ret));
} else if (OB_FAIL(ObTransformUtils::convert_set_op_expr_to_select_expr(set_op_exprs,
subquery,
select_exprs))) {
LOG_WARN("failed to convert set op exprs to select exprs", K(ret));
} else if (set_op_exprs.count() != select_exprs.count()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect set op expr count", K(ret));
}
for (int64_t j = 0; OB_SUCC(ret) && is_simple_expr && j < select_exprs.count(); ++j) {
ObRawExpr *expr = select_exprs.at(j);
if (OB_ISNULL(expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null expr", K(ret));
} else if (expr->has_flag(CNT_WINDOW_FUNC) ||
expr->has_flag(CNT_AGG) ||
expr->has_flag(CNT_SUB_QUERY) ||
expr->has_flag(CNT_ONETIME)) {
is_simple_expr = false;
} else if (OB_FAIL(ObRawExprUtils::extract_column_exprs(expr, view_column_exprs))) {
LOG_WARN("failed to extract column exprs", K(ret));
}
}
if (OB_FAIL(ret)) {
} else if (OB_FAIL(ObTransformUtils::replace_expr(child_select_list,
parent_select_list,
expr))) {
SQL_LOG(WARN, "failed to replace expr", K(ret));
} else if (OB_FAIL(expr->extract_info())) {
LOG_WARN("failed to extract info", K(ret), K(*expr));
} else if (!is_simple_expr) {
//can not push down
} else if (!common_exprs.empty() &&
!subset_exprs(view_column_exprs, common_exprs)) {
//common_exprs为空,说明既没有windown func,也没有group by
} else if (OB_FAIL(candi_filters.push_back(pred))) {
LOG_WARN("failed to push back predicate", K(ret));
} else {
pushdown_filters.at(i) = expr;
pushed = true;
}
if (OB_SUCC(ret) && !pushed &&
OB_FAIL(remain_filters.push_back(pred))) {
LOG_WARN("failed to push back expr", K(ret));
}
}
if (OB_SUCC(ret)) {
LOG_TRACE("success to check_pushdown_filter_for_set", K(pushdown_filters), K(candi_filters),
K(remain_filters));
}
return ret;
}