diff --git a/src/sql/engine/expr/ob_expr_operator.cpp b/src/sql/engine/expr/ob_expr_operator.cpp index b0f202d93e..5f97887d98 100644 --- a/src/sql/engine/expr/ob_expr_operator.cpp +++ b/src/sql/engine/expr/ob_expr_operator.cpp @@ -2581,7 +2581,6 @@ int ObSubQueryRelationalExpr::check_exists(const ObExpr& expr, ObEvalCtx& ctx, b ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected argument count", K(ret)); } else if (OB_FAIL(expr.args_[0]->eval(ctx, v))) { - ret = OB_ERR_UNEXPECTED; LOG_WARN("NULL subquery ref info returned", K(ret)); } else if (OB_FAIL(ObExprSubQueryRef::get_subquery_iter( ctx, ObExprSubQueryRef::ExtraInfo::get_info(v->get_int()), iter))) { diff --git a/src/sql/rewrite/ob_transform_aggr_subquery.cpp b/src/sql/rewrite/ob_transform_aggr_subquery.cpp index beb16ca80e..14dbf2eadd 100644 --- a/src/sql/rewrite/ob_transform_aggr_subquery.cpp +++ b/src/sql/rewrite/ob_transform_aggr_subquery.cpp @@ -697,7 +697,7 @@ int ObTransformAggrSubquery::transform_with_join_first(ObDMLStmt*& stmt, bool& t } else if (OB_UNLIKELY(!ObOptimizerUtil::find_item(view_stmt->get_subquery_exprs(), param.ja_query_ref_))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("the subquery is not found in view stmt", K(ret)); - } else if (OB_FAIL(do_join_first_transform(*view_stmt, param, root_expr))) { + } else if (OB_FAIL(do_join_first_transform(*view_stmt, param, root_expr, 0 == i))) { LOG_WARN("failed to do join first transform", K(ret)); } else { target_stmt = view_stmt; @@ -855,26 +855,13 @@ int ObTransformAggrSubquery::check_stmt_valid(ObDMLStmt& stmt, bool& is_valid) { int ret = OB_SUCCESS; is_valid = true; - int32_t bit_id = OB_INVALID_INDEX; - ObSqlBitSet<> output_rel_ids; + bool can_set_unique = false; if (stmt.is_set_stmt() || stmt.is_hierarchical_query() || !stmt.is_sel_del_upd()) { is_valid = false; - } else if (OB_FAIL(stmt.get_from_tables(output_rel_ids))) { - LOG_WARN("failed to get output rel ids", K(ret)); - } - // check all output table is basic table - // TODO check whether a view stmt has unique keys - for (int64_t i = 0; OB_SUCC(ret) && is_valid && i < stmt.get_table_items().count(); ++i) { - const TableItem* cur_table = stmt.get_table_item(i); - if (OB_ISNULL(cur_table)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("get null table item", K(ret)); - } else if (OB_UNLIKELY(OB_INVALID_INDEX == (bit_id = stmt.get_table_bit_index(cur_table->table_id_)))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid table bit index", K(ret), K(cur_table->table_id_), K(bit_id)); - } else if (output_rel_ids.has_member(bit_id) && !cur_table->is_basic_table()) { - is_valid = false; - } + } else if (OB_FAIL(ObTransformUtils::check_can_set_stmt_unique(&stmt, can_set_unique))) { + LOG_WARN("failed to check can set stmt unque", K(ret)); + } else if (!can_set_unique) { + is_valid = false; } return ret; } @@ -1054,7 +1041,7 @@ int ObTransformAggrSubquery::choose_pullup_method_for_exists( } int ObTransformAggrSubquery::do_join_first_transform( - ObSelectStmt& select_stmt, TransformParam& trans_param, ObRawExpr* root_expr) + ObSelectStmt& select_stmt, TransformParam& trans_param, ObRawExpr* root_expr, const bool is_first_trans) { int ret = OB_SUCCESS; ObQueryRefRawExpr *query_ref_expr = NULL; @@ -1066,7 +1053,7 @@ int ObTransformAggrSubquery::do_join_first_transform( || OB_ISNULL(subquery = trans_param.ja_query_ref_->get_ref_stmt())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid argument", K(ret), K(ctx_), K(root_expr), K(query_ref_expr), K(subquery)); - } else if (OB_FAIL(get_unique_keys(select_stmt, select_stmt.get_group_exprs()))) { + } else if (OB_FAIL(get_unique_keys(select_stmt, select_stmt.get_group_exprs(), is_first_trans))) { LOG_WARN("failed to get unique exprs", K(ret)); } if (OB_SUCC(ret) && trans_param.not_null_expr_ != NULL) { @@ -1131,60 +1118,45 @@ int ObTransformAggrSubquery::do_join_first_transform( LOG_WARN("failed to append semi infos", K(ret)); } else if (OB_FAIL(select_stmt.formalize_stmt(ctx_->session_info_))) { LOG_WARN("failed to formalize stmt", K(ret)); - } else if (OB_FAIL(rebuild_conditon(select_stmt))) { + } else if (OB_FAIL(rebuild_conditon(select_stmt, *subquery))) { LOG_WARN("failed to rebuild condition", K(ret)); } } return ret; } -int ObTransformAggrSubquery::get_unique_keys(ObDMLStmt& stmt, ObIArray& pkeys) +int ObTransformAggrSubquery::get_unique_keys(ObDMLStmt& stmt, ObIArray& pkeys, const bool is_first_trans) { int ret = OB_SUCCESS; - ObSqlBitSet<> from_tables; - ObSEArray tmp_pkeys; - int32_t bit_id = OB_INVALID_INDEX; - if (OB_FAIL(stmt.get_from_tables(from_tables))) { - LOG_WARN("failed to get from table set", K(ret)); - } - for (int64_t i = 0; OB_SUCC(ret) && i < stmt.get_table_items().count(); ++i) { - tmp_pkeys.reuse(); - TableItem* cur_table = stmt.get_table_item(i); - if (OB_ISNULL(cur_table)) { + ObSqlBitSet<> empty_ignore_tables; + TableItem* cur_table = NULL; + if (is_first_trans) { + if (OB_FAIL(ObTransformUtils::generate_unique_key(ctx_, &stmt, empty_ignore_tables, pkeys))) { + LOG_WARN("failed to generate unique key", K(ret)); + } + } else if (OB_UNLIKELY(1 != stmt.get_table_items().count()) || + OB_ISNULL(cur_table = stmt.get_table_item(0)) || + OB_UNLIKELY(!cur_table->is_generated_table())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected table item", K(ret), K(stmt.get_table_items().count()), K(cur_table)); + } else { + // already perform JA rewrite, get group by column from view directly + ObSelectStmt* view_stmt = NULL; + ObSEArray select_list; + ObSEArray column_list; + ObSEArray group_keys; + if (OB_ISNULL(view_stmt = cur_table->ref_query_) || OB_UNLIKELY(0 == view_stmt->get_group_expr_size())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("get null table item", K(ret)); - } else if (OB_UNLIKELY(OB_INVALID_INDEX == (bit_id = stmt.get_table_bit_index(cur_table->table_id_)))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid table bit index", K(ret), K(cur_table->table_id_), K(bit_id)); - } else if (!from_tables.has_member(bit_id)) { - // do nothing - } else if (cur_table->is_basic_table()) { - if (OB_FAIL(ObTransformUtils::generate_unique_key(ctx_, &stmt, cur_table, tmp_pkeys))) { - LOG_WARN("failed to generate unique key", K(ret)); - } else if (OB_FAIL(append(pkeys, tmp_pkeys))) { - LOG_WARN("failed to append pkeys", K(ret)); - } - } else if (cur_table->is_generated_table()) { - ObSelectStmt* view_stmt = NULL; - ObSEArray select_list; - ObSEArray column_list; - ObSEArray group_keys; - if (OB_ISNULL(view_stmt = cur_table->ref_query_) || OB_UNLIKELY(0 == view_stmt->get_group_expr_size())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("view is not a normal group by", K(ret), K(view_stmt)); - } else if (OB_FAIL(ObRawExprUtils::copy_exprs( - *ctx_->expr_factory_, view_stmt->get_group_exprs(), group_keys, COPY_REF_DEFAULT))) { - LOG_WARN("failed to copy exprs", K(ret)); - } else if (OB_FAIL(stmt.get_view_output(*cur_table, select_list, column_list))) { - LOG_WARN("failed to get view output", K(ret)); - } else if (OB_FAIL(ObTransformUtils::replace_exprs(select_list, column_list, group_keys))) { - LOG_WARN("failed to replace group keys", K(ret)); - } else if (OB_FAIL(append(pkeys, group_keys))) { - LOG_WARN("failed to append group keys", K(ret)); - } - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected table item", K(ret), K(*cur_table)); + LOG_WARN("view is not a normal group by", K(ret), K(view_stmt)); + } else if (OB_FAIL(ObRawExprUtils::copy_exprs( + *ctx_->expr_factory_, view_stmt->get_group_exprs(), group_keys, COPY_REF_DEFAULT))) { + LOG_WARN("failed to copy exprs", K(ret)); + } else if (OB_FAIL(stmt.get_view_output(*cur_table, select_list, column_list))) { + LOG_WARN("failed to get view output", K(ret)); + } else if (OB_FAIL(ObTransformUtils::replace_exprs(select_list, column_list, group_keys))) { + LOG_WARN("failed to replace group keys", K(ret)); + } else if (OB_FAIL(append(pkeys, group_keys))) { + LOG_WARN("failed to append group keys", K(ret)); } } return ret; @@ -1231,25 +1203,37 @@ int ObTransformAggrSubquery::transform_from_list(ObDMLStmt& stmt, ObSelectStmt& return ret; } -int ObTransformAggrSubquery::rebuild_conditon(ObSelectStmt& stmt) +int ObTransformAggrSubquery::rebuild_conditon(ObSelectStmt& stmt, ObSelectStmt& subquery) { int ret = OB_SUCCESS; ObSEArray where_conditions; + ObIArray* target_array = NULL; if (OB_FAIL(where_conditions.assign(stmt.get_condition_exprs()))) { LOG_WARN("failed to assign where conditions", K(ret)); } stmt.get_condition_exprs().reuse(); for (int64_t i = 0; OB_SUCC(ret) && i < where_conditions.count(); ++i) { ObRawExpr* cur_expr = NULL; + target_array = NULL; if (OB_ISNULL(cur_expr = where_conditions.at(i))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("condition expr is null", K(ret)); - } else if (cur_expr->has_flag(CNT_AGG) || cur_expr->has_flag(CNT_SUB_QUERY)) { - if (OB_FAIL(stmt.get_having_exprs().push_back(cur_expr))) { - LOG_WARN("failed to push back cur expr", K(ret)); + } else if (cur_expr->has_flag(CNT_AGG)) { + target_array = &stmt.get_having_exprs(); + } else if (cur_expr->has_flag(CNT_SUB_QUERY)) { + if (ObOptimizerUtil::find_item(subquery.get_condition_exprs(), cur_expr)) { + target_array = &stmt.get_condition_exprs(); + } else { + target_array = &stmt.get_having_exprs(); + } + } else { + target_array = &stmt.get_condition_exprs(); + } + + if (OB_SUCC(ret) && OB_NOT_NULL(target_array)) { + if (OB_FAIL(target_array->push_back(cur_expr))) { + LOG_WARN("failed to push back expr", K(ret)); } - } else if (OB_FAIL(stmt.get_condition_exprs().push_back(cur_expr))) { - LOG_WARN("failed to push back where condition", K(ret)); } } return ret; diff --git a/src/sql/rewrite/ob_transform_aggr_subquery.h b/src/sql/rewrite/ob_transform_aggr_subquery.h index 2f4bab416c..034d7b6189 100644 --- a/src/sql/rewrite/ob_transform_aggr_subquery.h +++ b/src/sql/rewrite/ob_transform_aggr_subquery.h @@ -115,13 +115,13 @@ private: int get_trans_view(ObDMLStmt& stmt, ObSelectStmt*& view_stmt, ObRawExpr* root_expr, bool post_group_by); - int do_join_first_transform(ObSelectStmt& select_stmt, TransformParam& trans_param, ObRawExpr* root_expr); + int do_join_first_transform(ObSelectStmt& select_stmt, TransformParam& trans_param, ObRawExpr* root_expr, const bool is_first_trans); - int get_unique_keys(ObDMLStmt& stmt, ObIArray& pkeys); + int get_unique_keys(ObDMLStmt& stmt, ObIArray& pkeys, const bool is_first_trans); int transform_from_list(ObDMLStmt& stmt, ObSelectStmt& subquery, const int64_t pullup_flag); - int rebuild_conditon(ObSelectStmt& stmt); + int rebuild_conditon(ObSelectStmt& stmt, ObSelectStmt& subquery); int check_subquery_aggr_item(const ObSelectStmt& subquery, bool& is_valid);