[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