[bugfix] fix rollup bug
This commit is contained in:
parent
d7da0bcfb3
commit
115b2dc7f0
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user