Fix mysql rollup duplicate columns wrong result
This commit is contained in:
@ -3504,13 +3504,37 @@ int ObStaticEngineCG::generate_spec(ObLogGroupBy &op, ObMergeGroupBySpec &spec,
|
|||||||
OB_LOG(WARN, "fail to init_duplicate_rollup_expr", K(ret));
|
OB_LOG(WARN, "fail to init_duplicate_rollup_expr", K(ret));
|
||||||
}
|
}
|
||||||
bool is_duplicate = false;
|
bool is_duplicate = false;
|
||||||
|
const bool is_oracle_mode = lib::is_oracle_mode();
|
||||||
|
// In the two different modes of mysql and oracle, the behavior of rollup duplicate columns
|
||||||
|
// is different. For example, when there is one row [1] in t1, in oracle mode
|
||||||
|
// select c1 from t1 group by rollup(c1, c1);
|
||||||
|
// +------+
|
||||||
|
// | c1 |
|
||||||
|
// +------+
|
||||||
|
// | 1 |
|
||||||
|
// | 1 |
|
||||||
|
// | NULL |
|
||||||
|
// +------+
|
||||||
|
// In mysql mode
|
||||||
|
// select c1 from t1 group by c1, c1 with rollup;
|
||||||
|
// +------+
|
||||||
|
// | c1 |
|
||||||
|
// +------+
|
||||||
|
// | 1 |
|
||||||
|
// | NULL |
|
||||||
|
// | NULL |
|
||||||
|
// +------+
|
||||||
|
// So we need to distinguish between two modes when initializing `is_duplicate_rollup_expr_`
|
||||||
|
// array. For oracle, it is initialized from left to right. For mysql, it is initialized from
|
||||||
|
// right to left.
|
||||||
ARRAY_FOREACH(rollup_exprs, i) {
|
ARRAY_FOREACH(rollup_exprs, i) {
|
||||||
const ObRawExpr* raw_expr = rollup_exprs.at(i);
|
const ObRawExpr* raw_expr = rollup_exprs.at(i);
|
||||||
ObExpr *expr = NULL;
|
ObExpr *expr = NULL;
|
||||||
if (OB_FAIL(generate_rt_expr(*raw_expr, expr))) {
|
if (OB_FAIL(generate_rt_expr(*raw_expr, expr))) {
|
||||||
LOG_WARN("failed to generate_rt_expr", K(ret));
|
LOG_WARN("failed to generate_rt_expr", K(ret));
|
||||||
} else if (FALSE_IT(is_duplicate = (has_exist_in_array(spec.group_exprs_, expr)
|
} else if (FALSE_IT(is_duplicate = (is_oracle_mode && // set is_duplicate to false in mysql
|
||||||
|| has_exist_in_array(spec.rollup_exprs_, expr)))) {
|
(has_exist_in_array(spec.group_exprs_, expr)
|
||||||
|
|| has_exist_in_array(spec.rollup_exprs_, expr))))) {
|
||||||
} else if (OB_FAIL(spec.is_duplicate_rollup_expr_.push_back(is_duplicate))) {
|
} else if (OB_FAIL(spec.is_duplicate_rollup_expr_.push_back(is_duplicate))) {
|
||||||
OB_LOG(WARN, "fail to push distinct_rollup_expr", K(ret));
|
OB_LOG(WARN, "fail to push distinct_rollup_expr", K(ret));
|
||||||
} else if (OB_FAIL(spec.add_rollup_expr(expr))) {
|
} else if (OB_FAIL(spec.add_rollup_expr(expr))) {
|
||||||
@ -3519,6 +3543,21 @@ int ObStaticEngineCG::generate_spec(ObLogGroupBy &op, ObMergeGroupBySpec &spec,
|
|||||||
LOG_DEBUG("rollup is duplicate key", K(is_duplicate));
|
LOG_DEBUG("rollup is duplicate key", K(is_duplicate));
|
||||||
}
|
}
|
||||||
} // end for
|
} // end for
|
||||||
|
// mysql mode, reinit duplicate rollup expr from right to left
|
||||||
|
if (OB_SUCC(ret) && !is_oracle_mode && rollup_exprs.count() > 0) {
|
||||||
|
for (int64_t i = spec.rollup_exprs_.count() - 2; OB_SUCC(ret) && i >= 0; --i) {
|
||||||
|
if (has_exist_in_array(spec.group_exprs_, spec.rollup_exprs_.at(i))) {
|
||||||
|
spec.is_duplicate_rollup_expr_.at(i) = true;
|
||||||
|
} else {
|
||||||
|
for (int64_t j = i + 1; !spec.is_duplicate_rollup_expr_.at(i)
|
||||||
|
&& j < spec.rollup_exprs_.count(); ++j) {
|
||||||
|
if (spec.rollup_exprs_.at(i) == spec.rollup_exprs_.at(j)) {
|
||||||
|
spec.is_duplicate_rollup_expr_.at(i) = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. add aggr columns
|
// 3. add aggr columns
|
||||||
|
|||||||
Reference in New Issue
Block a user