[bugfix] fix rollup bug

This commit is contained in:
obdev 2023-03-06 10:11:21 +00:00 committed by ob-robot
parent d7da0bcfb3
commit 115b2dc7f0
4 changed files with 53 additions and 0 deletions

View File

@ -1002,6 +1002,7 @@ int ObSelectResolver::resolve_normal_query(const ParseNode &parse_tree)
const ParseNode *group_by = NULL;
const ParseNode *having = NULL;
ObSelectStmt *select_stmt = get_select_stmt();
bool has_rollup = false;
CK(OB_NOT_NULL(select_stmt),
OB_NOT_NULL(session_info_),
OB_NOT_NULL(select_stmt->get_query_ctx()));
@ -1023,6 +1024,7 @@ int ObSelectResolver::resolve_normal_query(const ParseNode &parse_tree)
OZ( search_connect_group_by_clause(parse_tree, start_with, connect_by, group_by, having) );
if (OB_SUCC(ret) && OB_NOT_NULL(group_by)) {
set_has_group_by_clause();
OZ (check_rollup_clause(group_by, has_rollup));
}
if (OB_SUCC(ret) && (start_with != NULL || connect_by != NULL)) {
select_stmt->set_hierarchical_query(true);
@ -1044,11 +1046,19 @@ int ObSelectResolver::resolve_normal_query(const ParseNode &parse_tree)
if (!is_oracle_mode()) {
// mysql resolve: from->where->select_item->group by->having->order by
count_name_win_expr = select_stmt->get_window_func_count();
if (has_rollup) {
expr_resv_ctx_.set_new_scope();
}
OZ( resolve_field_list(*(parse_tree.children_[PARSE_SELECT_SELECT])));
}
/* resolve group by clause */
OZ( resolve_group_clause(group_by) );
if (has_rollup && is_oracle_mode()) {
expr_resv_ctx_.set_new_scope();
}
/* resolve having clause */
OZ( resolve_having_clause(having) );
@ -3605,6 +3615,30 @@ int ObSelectResolver::resolve_group_clause(const ParseNode *node)
return ret;
}
int ObSelectResolver::check_rollup_clause(const ParseNode *node, bool &has_rollup)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(node) || OB_ISNULL(node->children_) ||
OB_UNLIKELY(T_GROUPBY_CLAUSE != node->type_)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid resolver arguments", K(ret), K(node));
} else {
for (int64_t i = 0; OB_SUCC(ret) && i < node->num_child_; ++i) {
const ParseNode *child_node = node->children_[i];
if (OB_ISNULL(child_node)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret), K(child_node));
} else if (child_node->type_ == T_ROLLUP_LIST ||
child_node->type_ == T_CUBE_LIST ||
child_node->type_ == T_GROUPING_SETS_LIST ||
child_node->type_ == T_WITH_ROLLUP_CLAUSE) {
has_rollup = true;
}
}
}
return ret;
}
int ObSelectResolver::resolve_group_by_list(const ParseNode *node,
common::ObIArray<ObRawExpr*> &groupby_exprs,
common::ObIArray<ObRawExpr*> &rollup_exprs,

View File

@ -147,6 +147,8 @@ protected:
ObSelectStmt *select_stmt,
bool &has_explicit_dir,
bool is_groupby_expr);
int check_rollup_clause(const ParseNode *node, bool &has_rollup);
int resolve_group_by_list(const ParseNode *node,
common::ObIArray<ObRawExpr*> &groupby_exprs,
common::ObIArray<ObRawExpr*> &rollup_exprs,

View File

@ -544,6 +544,17 @@ int ObTransformQueryPushDown::check_select_item_push_down(ObSelectStmt *select_s
} else {
can_be = true;
}
if (OB_SUCC(ret) && select_stmt->has_rollup()) {
for (int64_t i = 0; OB_SUCC(ret) && can_be && i < select_exprs.count(); ++i) {
if (OB_ISNULL(select_exprs.at(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("select expr is null", K(ret));
} else {
can_be = !select_exprs.at(i)->is_const_expr() &&
!select_exprs.at(i)->has_flag(CNT_SUB_QUERY);
}
}
}
return ret;
}

View File

@ -597,6 +597,7 @@ int ObTransformViewMerge::check_can_be_merged(ObDMLStmt *parent_stmt,
{
int ret = OB_SUCCESS;
can_be = true;
bool has_rollup = false;
if (OB_ISNULL(parent_stmt) || OB_ISNULL(child_stmt)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
@ -604,6 +605,8 @@ int ObTransformViewMerge::check_can_be_merged(ObDMLStmt *parent_stmt,
LOG_WARN("failed to check", K(ret));
} else if (!can_be) {
} else {
has_rollup = parent_stmt->is_select_stmt() &&
static_cast<ObSelectStmt *>(parent_stmt)->has_rollup();
//select expr不能包含subquery
for (int64_t i = 0; OB_SUCC(ret) && can_be && i < child_stmt->get_select_item_size(); i++) {
ObRawExpr *expr = child_stmt->get_select_item(i).expr_;
@ -613,6 +616,9 @@ int ObTransformViewMerge::check_can_be_merged(ObDMLStmt *parent_stmt,
} else if (expr->has_flag(CNT_SUB_QUERY)) {
can_be = false;
OPT_TRACE("view`s select expr contain subquery, can not merge");
} else if (expr->is_const_expr() && has_rollup) {
can_be = false;
OPT_TRACE("const expr can not be merged into rollup stmt");
}
}
//stmt不能包含rand函数 https://work.aone.alibaba-inc.com/issue/35875561