[CP] not considering const expr equal in or/and expr when computing shared expr

This commit is contained in:
jingtaoye35
2024-02-20 07:16:09 +00:00
committed by ob-robot
parent 625ea22c07
commit a3096d9389
5 changed files with 108 additions and 43 deletions

View File

@ -2473,7 +2473,9 @@ int ObTransformSimplifyExpr::do_canonicalize(ObDMLStmt *stmt, ObIArray<ObRawExpr
//do nothing
} else if (OB_FAIL(push_not(conditions, push_not_happend))) {
LOG_WARN("push not expr failed", K(ret));
} else if (OB_FAIL(remove_duplicate_exprs(conditions, remove_duplicate_happend))) {
} else if (OB_FAIL(remove_duplicate_exprs(stmt->get_query_ctx(),
conditions,
remove_duplicate_happend))) {
LOG_WARN("remove_duplicate_exprs failed", K(ret));
} else if (OB_FAIL(pull_similar_expr(stmt, conditions, pull_similar_happend))) {
LOG_WARN("pull_similar_expr failed", K(ret));
@ -2817,14 +2819,17 @@ int ObTransformSimplifyExpr::get_opposite_op(ObItemType type, ObItemType& opposi
return ret;
}
int ObTransformSimplifyExpr::remove_duplicate_exprs(ObIArray<ObRawExpr*> &conditions, bool &trans_happened)
int ObTransformSimplifyExpr::remove_duplicate_exprs(ObQueryCtx* query_ctx,
ObIArray<ObRawExpr*> &conditions,
bool &trans_happened)
{
/* basic case
* A and A -> A
* A or A -> A
*/
int ret = OB_SUCCESS;
for (int64_t i = 0; OB_SUCC(ret) && i < conditions.count(); i++) {
const int64_t param_count = conditions.count();
for (int64_t i = 0; OB_SUCC(ret) && i < param_count; i++) {
if (OB_ISNULL(conditions.at(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null pointer error", K(conditions.at(i)), K(ret));
@ -2832,18 +2837,45 @@ int ObTransformSimplifyExpr::remove_duplicate_exprs(ObIArray<ObRawExpr*> &condit
LOG_WARN("do_remove fail", K(conditions.at(i)), K(ret));
}
}
if (OB_SUCC(ret) && conditions.count() > 1) {
if (OB_SUCC(ret) && param_count > 1 && param_count <= 100) {
//select * from t1 where c1 > 1 and c1 > 1
//like above stmt, and expr in level 0 is process here
ObSEArray<ObRawExpr *, 4> param_conds;
if (OB_FAIL(append_array_no_dup(param_conds, conditions))) {
LOG_WARN("fail to append_array_no_dup", K(ret));
} else if (param_conds.count() == conditions.count()) {
//do nothing
} else if (OB_FAIL(conditions.assign(param_conds))) {
LOG_WARN("assign array failed", K(ret));
ObQuestionmarkEqualCtx cmp_ctx(true);
if (OB_ISNULL(query_ctx)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null pointer error", K(ret));
} else if (OB_FAIL(param_conds.assign(conditions))) {
LOG_WARN("failed to assign array", K(ret));
} else {
trans_happened = true;
for (int64_t i = param_count - 1; OB_SUCC(ret) && i >= 1; i--) {
for (int64_t j = 0; OB_SUCC(ret) && j < i; j++) {
if (param_conds.at(i)->same_as(*param_conds.at(j), &cmp_ctx)) {
if (OB_FAIL(param_conds.remove(i))) {
LOG_WARN("failed to remove", K(ret));
} else if (!cmp_ctx.equal_pairs_.empty()) {
if (OB_FAIL(append(query_ctx->all_equal_param_constraints_,
cmp_ctx.equal_pairs_))) {
LOG_WARN("failed to append expr", K(ret));
} else {
cmp_ctx.equal_pairs_.reset();
}
}
break;
} else if (!cmp_ctx.equal_pairs_.empty()) {
cmp_ctx.equal_pairs_.reset();
}
}
}
if (OB_FAIL(ret)) {
} else if (param_conds.count() == conditions.count()) {
//do nothing
} else if (OB_FAIL(conditions.assign(param_conds))) {
LOG_WARN("assign array failed", K(ret));
} else {
trans_happened = true;
}
}
}
if (OB_SUCC(ret) && trans_happened) {
@ -2902,11 +2934,11 @@ int ObTransformSimplifyExpr::pull_similar_expr(ObDMLStmt *stmt,
{
/*
* example1:
* c1 and c5 or (c1 and c2) or (c1 and c3 and c4)
* (c1 and c5) or (c1 and c2) or (c1 and c3 and c4)
* param_sets<<c1,c5>,<c1,c2>,<c1,c3,c4>>
* intersection : <c1>
* param_sets after remove intersection: <<c5>,<c2>,<c3,c4>>
* build new expr : c1 and (c5 or or c2 c3 and c4)
* build new expr : c1 and (c5 or c2 or (c3 and c4))
*
* example2:
* c1 or (c1 and c2) or (c1 and c3 and c4)
@ -3095,18 +3127,13 @@ int ObTransformSimplifyExpr::get_intersection(ObDMLStmt *stmt,
} else if (OB_FAIL(params.assign(temp_result))) {
LOG_WARN("fail to assign array", K(ret));
}
}
if (OB_SUCC(ret) && is_valid) {
if (OB_FAIL(append(ctx_->equal_param_constraints_, context.equal_param_info_))) {
context.equal_param_info_.reset();
ret = OB_SIZE_OVERFLOW == context.error_code_;
LOG_WARN("append equal param info failed", K(ret));
} else if (OB_FAIL(intersection.assign(params))) {
LOG_WARN("fail to assign array", K(ret));
} else {
if (OB_SUCC(ret)) {
context.equal_param_info_.reset();
}
}
if (OB_SUCC(ret) && is_valid && OB_FAIL(intersection.assign(params))) {
LOG_WARN("fail to assign array", K(ret));
}
return ret;
}
@ -3114,16 +3141,25 @@ int ObTransformSimplifyExpr::remove_intersect_item(ObIArray<ObSEArray<ObRawExpr
ObIArray<ObRawExpr *> &intersection)
{
int ret = OB_SUCCESS;
ObStmtCompareContext context;
for (int64_t i = 0; OB_SUCC(ret) && i < params_sets.count(); i++) {
ObSEArray<ObRawExpr *, 4> temp_result;
for (int64_t j = 0; OB_SUCC(ret) && j < params_sets.at(i).count(); j++) {
bool find = false;
if (OB_FAIL(ObTransformUtils::find_expr(intersection, params_sets.at(i).at(j), find))) {
if (OB_FAIL(ObTransformUtils::find_expr(intersection, params_sets.at(i).at(j), find, &context))) {
LOG_WARN("failed to find expr", K(ret));
} else if (find) {
// do nothing
if (!context.equal_param_info_.empty()) {
if (OB_FAIL(append(ctx_->equal_param_constraints_, context.equal_param_info_))) {
ret = OB_SIZE_OVERFLOW == context.error_code_;
LOG_WARN("append equal param info failed", K(ret));
}
context.equal_param_info_.reset();
}
} else if (OB_FAIL(temp_result.push_back(params_sets.at(i).at(j)))) {
LOG_WARN("failed to push back expr", K(ret));
} else if (!context.equal_param_info_.empty()) {
context.equal_param_info_.reset();
}
}
if (OB_FAIL(ret)) {