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
	 yinyj17
					yinyj17