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;
|
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,
|
int ObRawExprUtils::extract_column_exprs(const ObRawExpr *raw_expr,
|
||||||
ObIArray<ObRawExpr*> &column_exprs,
|
ObIArray<ObRawExpr*> &column_exprs,
|
||||||
bool need_pseudo_column)
|
bool need_pseudo_column)
|
||||||
|
|||||||
@ -372,6 +372,8 @@ public:
|
|||||||
static bool is_all_column_exprs(const common::ObIArray<ObRawExpr*> &exprs);
|
static bool is_all_column_exprs(const common::ObIArray<ObRawExpr*> &exprs);
|
||||||
static int extract_set_op_exprs(const ObRawExpr *raw_expr,
|
static int extract_set_op_exprs(const ObRawExpr *raw_expr,
|
||||||
common::ObIArray<ObRawExpr*> &set_op_exprs);
|
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
|
/// extract column exprs from the raw expr
|
||||||
static int extract_column_exprs(const ObRawExpr *raw_expr,
|
static int extract_column_exprs(const ObRawExpr *raw_expr,
|
||||||
common::ObIArray<ObRawExpr*> &column_exprs,
|
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()) {
|
if (column_count == view_stmt->get_select_item_size()) {
|
||||||
/*do nothing*/
|
/*do nothing*/
|
||||||
//if outer output is const expr, then inner output must be const expr, eg:select 1 from (select 2 from t1)
|
//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()) {
|
} 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) {
|
for (int64_t i = 0; OB_SUCC(ret) && is_same && i < view_stmt->get_select_item_size(); ++i) {
|
||||||
ObRawExpr *select_expr = NULL;
|
ObRawExpr *select_expr = NULL;
|
||||||
@ -440,6 +446,49 @@ int ObTransformQueryPushDown::is_select_item_same(ObSelectStmt *select_stmt,
|
|||||||
return ret;
|
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能否被下压
|
/*@brief check_rownum_push_down检查含有rownum能否被下压
|
||||||
* 1.外层存在rownum时
|
* 1.外层存在rownum时
|
||||||
* 如果外层存在rownum,内层是非spj时算子基本都不支持下压,如:
|
* 如果外层存在rownum,内层是非spj时算子基本都不支持下压,如:
|
||||||
|
|||||||
@ -74,6 +74,10 @@ private:
|
|||||||
bool &is_same,
|
bool &is_same,
|
||||||
common::ObIArray<int64_t> &select_offset,
|
common::ObIArray<int64_t> &select_offset,
|
||||||
common::ObIArray<SelectItem> &const_select_items);
|
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,
|
int do_transform(ObSelectStmt *select_stmt,
|
||||||
ObSelectStmt *view_stmt,
|
ObSelectStmt *view_stmt,
|
||||||
bool need_distinct,
|
bool need_distinct,
|
||||||
|
|||||||
Reference in New Issue
Block a user