[CP] [CP] Add limitation for larget set stmts' cost based transformation.
This commit is contained in:
		| @ -165,7 +165,8 @@ int ObTransformRule::transform_stmt_recursively(common::ObIArray<ObParentDMLStmt | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
|   bool is_stack_overflow = false; | ||||
|   if (OB_ISNULL(stmt)) { | ||||
|   int64_t size = 0; | ||||
|   if (OB_ISNULL(stmt) || OB_ISNULL(ctx_)) { | ||||
|     ret = OB_INVALID_ARGUMENT; | ||||
|     LOG_WARN("stmt is NULL", K(ret)); | ||||
|   } else if (OB_FAIL(check_stack_overflow(is_stack_overflow))) { | ||||
| @ -173,7 +174,10 @@ int ObTransformRule::transform_stmt_recursively(common::ObIArray<ObParentDMLStmt | ||||
|   } else if (is_stack_overflow) { | ||||
|     ret = OB_SIZE_OVERFLOW; | ||||
|     LOG_WARN("too deep recursive", K(current_level), K(is_stack_overflow), K(ret)); | ||||
|   } else if (is_large_stmt(*stmt) && | ||||
|   } else if (stmt->is_select_stmt() && | ||||
|         OB_FAIL(static_cast<const ObSelectStmt *>(stmt)->get_set_stmt_size(size))) { | ||||
|     LOG_WARN("failed to get set stm size", K(ret)); | ||||
|   } else if (size > common::OB_MAX_SET_STMT_SIZE && | ||||
|             !(transformer_type_ == PRE_PROCESS || | ||||
|             transformer_type_ == POST_PROCESS)) { | ||||
|     // skip transformation for large stmt | ||||
| @ -270,6 +274,8 @@ int ObTransformRule::accept_transform(common::ObIArray<ObParentDMLStmt> &parent_ | ||||
|     LOG_WARN("context is null", K(ret), K(ctx_), K(stmt), K(trans_stmt), K(top_stmt)); | ||||
|   } else if (force_accept) { | ||||
|     trans_happened = true; | ||||
|   } else if (ctx_->is_set_stmt_oversize_) { | ||||
|     LOG_TRACE("not accept transform because large set stmt", K(ctx_->is_set_stmt_oversize_)); | ||||
|   } else if (OB_FAIL(evaluate_cost(parent_stmts, trans_stmt, true, | ||||
|                                    trans_stmt_cost, is_expected, check_ctx))) { | ||||
|     LOG_WARN("failed to evaluate cost for the transformed stmt", K(ret)); | ||||
| @ -281,11 +287,10 @@ int ObTransformRule::accept_transform(common::ObIArray<ObParentDMLStmt> &parent_ | ||||
|   } else { | ||||
|     trans_happened = trans_stmt_cost < stmt_cost_; | ||||
|   } | ||||
|  | ||||
|   if (OB_FAIL(ret)) { | ||||
|   } else if (!trans_happened) { | ||||
|     LOG_TRACE("reject transform because the cost is increased or the query plan is unexpected", | ||||
|                                       K_(stmt_cost), K(trans_stmt_cost), K(is_expected)); | ||||
|                      K_(ctx_->is_set_stmt_oversize), K_(stmt_cost), K(trans_stmt_cost), K(is_expected)); | ||||
|   } else if (OB_FAIL(adjust_transformed_stmt(parent_stmts, trans_stmt, tmp1, tmp2))) { | ||||
|     LOG_WARN("failed to adjust transformed stmt", K(ret)); | ||||
|   } else if (force_accept) { | ||||
| @ -737,20 +742,6 @@ bool ObTransformRule::is_view_stmt(const ObIArray<ObParentDMLStmt> &parents, con | ||||
|   return bret; | ||||
| } | ||||
|  | ||||
| bool ObTransformRule::is_large_stmt(const ObDMLStmt &stmt) | ||||
| { | ||||
|   bool bret = false; | ||||
|   int ret = OB_SUCCESS; | ||||
|   int64_t size = 0; | ||||
|   if (stmt.is_select_stmt()) { | ||||
|     if (OB_FAIL(static_cast<const ObSelectStmt&>(stmt).get_set_stmt_size(size))) { | ||||
|       LOG_WARN("failed to get set stm size", K(ret)); | ||||
|     } else if (size > common::OB_MAX_SET_STMT_SIZE) { | ||||
|       bret = true; | ||||
|     } | ||||
|   } | ||||
|   return bret; | ||||
| } | ||||
|  | ||||
| int ObTryTransHelper::fill_helper(const ObQueryCtx *query_ctx) | ||||
| { | ||||
|  | ||||
| @ -53,6 +53,7 @@ struct ObTransformerCtx | ||||
|     expr_constraints_(), | ||||
|     plan_const_param_constraints_(), | ||||
|     equal_param_constraints_(), | ||||
|     is_set_stmt_oversize_(false), | ||||
|     happened_cost_based_trans_(0), | ||||
|     equal_sets_(), | ||||
|     ignore_semi_infos_(), | ||||
| @ -108,6 +109,7 @@ struct ObTransformerCtx | ||||
|   ObSEArray<ObExprConstraint, 4, common::ModulePageAllocator, true> expr_constraints_; | ||||
|   ObSEArray<ObPCConstParamInfo, 4, common::ModulePageAllocator, true> plan_const_param_constraints_; | ||||
|   ObSEArray<ObPCParamEqualInfo, 4, common::ModulePageAllocator, true> equal_param_constraints_; | ||||
|   bool is_set_stmt_oversize_; | ||||
|   // record cost based transformers | ||||
|   uint64_t happened_cost_based_trans_; | ||||
|   EqualSets equal_sets_; | ||||
| @ -415,8 +417,6 @@ private: | ||||
|   bool is_view_stmt(const ObIArray<ObParentDMLStmt> &parents, | ||||
|                     const ObDMLStmt &stmt); | ||||
|  | ||||
|   bool is_large_stmt(const ObDMLStmt &stmt); | ||||
|  | ||||
|   bool skip_move_trans_loc() const | ||||
|   { | ||||
|     return TEMP_TABLE_OPTIMIZATION == transformer_type_ // move trans loc in transform rule | ||||
| @ -431,7 +431,6 @@ private: | ||||
|            || PREDICATE_MOVE_AROUND == transformer_type_; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   DISALLOW_COPY_AND_ASSIGN(ObTransformRule); | ||||
|  | ||||
| protected: | ||||
|  | ||||
| @ -63,6 +63,8 @@ int ObTransformerImpl::transform(ObDMLStmt *&stmt) | ||||
|   if (OB_ISNULL(stmt)) { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
|     LOG_WARN("get unexpected null", K(ret)); | ||||
|   } else if (OB_FAIL(SMART_CALL(get_stmt_trans_info(stmt)))) { | ||||
|     LOG_WARN("get_stmt_trans_info failed", K(ret)); | ||||
|   } else if (OB_FAIL(do_transform_pre_precessing(stmt))) { | ||||
|     LOG_WARN("failed to do transform pre_precessing", K(ret)); | ||||
|   } else if (OB_FAIL(stmt->formalize_stmt_expr_reference())) { | ||||
| @ -81,6 +83,34 @@ int ObTransformerImpl::transform(ObDMLStmt *&stmt) | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| int ObTransformerImpl::get_stmt_trans_info(ObDMLStmt *stmt) | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
|   if (OB_ISNULL(stmt) || OB_ISNULL(ctx_)) { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
|     LOG_WARN("stmt is null", K(ret)); | ||||
|   } else if (stmt->is_select_stmt()) { | ||||
|     int64_t size = 0; | ||||
|     if (OB_FAIL(static_cast<ObSelectStmt *>(stmt)->get_set_stmt_size(size))) { | ||||
|       LOG_WARN("get set stmt size failed", K(ret)); | ||||
|     } else if (size > ObTransformerImpl::MAX_SET_STMT_SIZE_OF_COSTED_BASED_RELUES) { | ||||
|       ctx_->is_set_stmt_oversize_ = true; | ||||
|     } | ||||
|   } | ||||
|   if (OB_SUCC(ret) && !ctx_->is_set_stmt_oversize_) { | ||||
|     ObSEArray<ObSelectStmt*, 4> child_stmts; | ||||
|     if (OB_FAIL(stmt->get_child_stmts(child_stmts))) { | ||||
|       LOG_WARN("failed to get child stmts", K(ret)); | ||||
|     } | ||||
|     for (int64_t i = 0; OB_SUCC(ret) && !ctx_->is_set_stmt_oversize_&& i < child_stmts.count(); i++) { | ||||
|       if (OB_FAIL(SMART_CALL(get_stmt_trans_info(child_stmts.at(i))))) { | ||||
|         LOG_WARN("get_stmt_trans_info failed", K(ret)); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| int ObTransformerImpl::do_transform(ObDMLStmt *&stmt) | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
|  | ||||
| @ -50,6 +50,7 @@ class ObTransformerImpl | ||||
| { | ||||
|   static const int64_t DEFAULT_ITERATION_COUNT = 10; | ||||
|   static const int64_t MAX_RULE_COUNT = 64; | ||||
|   static const uint64_t MAX_SET_STMT_SIZE_OF_COSTED_BASED_RELUES = 5; | ||||
| public: | ||||
|   ObTransformerImpl(ObTransformerCtx *ctx) | ||||
|     : ctx_(ctx), | ||||
| @ -146,7 +147,7 @@ public: | ||||
| private: | ||||
|  | ||||
|   int collect_trans_stat(const ObTransformRule &rule); | ||||
|  | ||||
|   int get_stmt_trans_info(ObDMLStmt *stmt); | ||||
|   void print_trans_stat(); | ||||
|  | ||||
|   int finalize_exec_params(ObDMLStmt *stmt); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 obdev
					obdev