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