fix pushdown filter into set stmt bug
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user