fix query pushdown into set stmt bug
This commit is contained in:
@ -3245,6 +3245,21 @@ int ObRawExprUtils::extract_set_op_exprs(const ObRawExpr *raw_expr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRawExprUtils::extract_set_op_exprs(const ObIArray<ObRawExpr*> &exprs,
|
||||
common::ObIArray<ObRawExpr*> &set_op_exprs)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < exprs.count(); ++i) {
|
||||
if (OB_ISNULL(exprs.at(i))) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("Expr is NULL", K(ret), K(i));
|
||||
} else if (OB_FAIL(extract_set_op_exprs(exprs.at(i), set_op_exprs))) {
|
||||
LOG_WARN("Failed to extract column exprs", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRawExprUtils::extract_column_exprs(const ObRawExpr *raw_expr,
|
||||
ObIArray<ObRawExpr*> &column_exprs,
|
||||
bool need_pseudo_column)
|
||||
|
||||
@ -372,6 +372,8 @@ public:
|
||||
static bool is_all_column_exprs(const common::ObIArray<ObRawExpr*> &exprs);
|
||||
static int extract_set_op_exprs(const ObRawExpr *raw_expr,
|
||||
common::ObIArray<ObRawExpr*> &set_op_exprs);
|
||||
static int extract_set_op_exprs(const ObIArray<ObRawExpr*> &exprs,
|
||||
common::ObIArray<ObRawExpr*> &set_op_exprs);
|
||||
/// extract column exprs from the raw expr
|
||||
static int extract_column_exprs(const ObRawExpr *raw_expr,
|
||||
common::ObIArray<ObRawExpr*> &column_exprs,
|
||||
|
||||
@ -414,6 +414,12 @@ int ObTransformQueryPushDown::is_select_item_same(ObSelectStmt *select_stmt,
|
||||
if (column_count == view_stmt->get_select_item_size()) {
|
||||
/*do nothing*/
|
||||
//if outer output is const expr, then inner output must be const expr, eg:select 1 from (select 2 from t1)
|
||||
} else if (OB_FAIL(check_set_op_expr_reference(select_stmt, view_stmt,
|
||||
select_offset, is_same))) {
|
||||
LOG_WARN("failed to check select item reference", K(ret));
|
||||
} else if (!is_same) {
|
||||
// view stmt is set stmt and outer output not contain all set op exprs in relation exprs of view
|
||||
// eg: select 1, c1 from (select 2 c1, 3 c2 from t1 union all select 4, 5 from t2 order by union[2]) v
|
||||
} else if (const_select_items.count() == select_stmt->get_select_item_size()) {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && is_same && i < view_stmt->get_select_item_size(); ++i) {
|
||||
ObRawExpr *select_expr = NULL;
|
||||
@ -440,6 +446,49 @@ int ObTransformQueryPushDown::is_select_item_same(ObSelectStmt *select_stmt,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObTransformQueryPushDown::check_set_op_expr_reference(ObSelectStmt *select_stmt,
|
||||
ObSelectStmt *view_stmt,
|
||||
ObIArray<int64_t> &select_offset,
|
||||
bool &is_valid)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
is_valid = true;
|
||||
if (OB_ISNULL(select_stmt)|| OB_ISNULL(view_stmt)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("stmt is NULL", K(select_stmt), K(view_stmt), K(ret));
|
||||
} else if (!view_stmt->is_set_stmt()) {
|
||||
// do nothing
|
||||
} else {
|
||||
ObSEArray<ObRawExpr*, 4> relation_exprs;
|
||||
ObSEArray<ObRawExpr*, 4> set_op_exprs;
|
||||
ObBitSet<> selected_set_op_idx;
|
||||
ObStmtExprGetter visitor;
|
||||
visitor.set_relation_scope();
|
||||
visitor.remove_scope(SCOPE_SELECT);
|
||||
if (OB_FAIL(view_stmt->get_relation_exprs(relation_exprs, visitor))) {
|
||||
LOG_WARN("failed to get relation exprs", K(ret));
|
||||
} else if (OB_FAIL(ObRawExprUtils::extract_set_op_exprs(relation_exprs,
|
||||
set_op_exprs))) {
|
||||
LOG_WARN("failed to extract column ids", K(ret));
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < select_offset.count(); ++i) {
|
||||
if (select_offset.at(i) != -1) {
|
||||
selected_set_op_idx.add_member(select_offset.at(i));
|
||||
}
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && is_valid && i < set_op_exprs.count(); ++i) {
|
||||
ObSetOpRawExpr *expr = static_cast<ObSetOpRawExpr*>(set_op_exprs.at(i));
|
||||
if (OB_ISNULL(expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null expr", K(ret), KPC(set_op_exprs.at(i)));
|
||||
} else if (!selected_set_op_idx.has_member(expr->get_idx())) {
|
||||
is_valid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*@brief check_rownum_push_down检查含有rownum能否被下压
|
||||
* 1.外层存在rownum时
|
||||
* 如果外层存在rownum,内层是非spj时算子基本都不支持下压,如:
|
||||
|
||||
@ -74,6 +74,10 @@ private:
|
||||
bool &is_same,
|
||||
common::ObIArray<int64_t> &select_offset,
|
||||
common::ObIArray<SelectItem> &const_select_items);
|
||||
int check_set_op_expr_reference(ObSelectStmt *select_stmt,
|
||||
ObSelectStmt *view_stmt,
|
||||
common::ObIArray<int64_t> &select_offset,
|
||||
bool &is_contain);
|
||||
int do_transform(ObSelectStmt *select_stmt,
|
||||
ObSelectStmt *view_stmt,
|
||||
bool need_distinct,
|
||||
|
||||
Reference in New Issue
Block a user