提交 d6fa1441 编写于 作者: S st0 提交者: LINGuanRen

fix CTE in mysql mode bug

上级 568b45a8
...@@ -201,6 +201,7 @@ print $fh_header '/** ...@@ -201,6 +201,7 @@ print $fh_header '/**
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details. * See the Mulan PubL v2 for more details.
*/ */
// DO NOT EDIT. This file is automatically generated from `ob_errno.def\'. // DO NOT EDIT. This file is automatically generated from `ob_errno.def\'.
#ifndef OCEANBASE_LIB_OB_ERRNO_H_ #ifndef OCEANBASE_LIB_OB_ERRNO_H_
......
...@@ -12101,7 +12101,7 @@ static struct ObStrErrorInit ...@@ -12101,7 +12101,7 @@ static struct ObStrErrorInit
ERROR_NAME[-OB_ERR_CTE_NEED_QUERY_BLOCKS] = "OB_ERR_CTE_NEED_QUERY_BLOCKS"; ERROR_NAME[-OB_ERR_CTE_NEED_QUERY_BLOCKS] = "OB_ERR_CTE_NEED_QUERY_BLOCKS";
ERROR_CAUSE[-OB_ERR_CTE_NEED_QUERY_BLOCKS] = "Internal Error"; ERROR_CAUSE[-OB_ERR_CTE_NEED_QUERY_BLOCKS] = "Internal Error";
ERROR_SOLUTION[-OB_ERR_CTE_NEED_QUERY_BLOCKS] = "Contact OceanBase Support"; ERROR_SOLUTION[-OB_ERR_CTE_NEED_QUERY_BLOCKS] = "Contact OceanBase Support";
MYSQL_ERRNO[-OB_ERR_CTE_NEED_QUERY_BLOCKS] = -1; MYSQL_ERRNO[-OB_ERR_CTE_NEED_QUERY_BLOCKS] = 3574;
SQLSTATE[-OB_ERR_CTE_NEED_QUERY_BLOCKS] = "HY000"; SQLSTATE[-OB_ERR_CTE_NEED_QUERY_BLOCKS] = "HY000";
STR_ERROR[-OB_ERR_CTE_NEED_QUERY_BLOCKS] = "Recursive Common Table Expression should have one or more non-recursive query blocks followed by one or more recursive ones"; STR_ERROR[-OB_ERR_CTE_NEED_QUERY_BLOCKS] = "Recursive Common Table Expression should have one or more non-recursive query blocks followed by one or more recursive ones";
STR_USER_ERROR[-OB_ERR_CTE_NEED_QUERY_BLOCKS] = "Recursive Common Table Expression should have one or more non-recursive query blocks followed by one or more recursive ones: %s"; STR_USER_ERROR[-OB_ERR_CTE_NEED_QUERY_BLOCKS] = "Recursive Common Table Expression should have one or more non-recursive query blocks followed by one or more recursive ones: %s";
...@@ -14009,6 +14009,8 @@ static struct ObStrErrorInit ...@@ -14009,6 +14009,8 @@ static struct ObStrErrorInit
ORACLE_STR_ERROR[-OB_ARCHIVE_LOG_NOT_CONTINUES_WITH_DATA] = "ORA-00600: internal error code, arguments: -9064, the archive log and backup data are not continuous"; ORACLE_STR_ERROR[-OB_ARCHIVE_LOG_NOT_CONTINUES_WITH_DATA] = "ORA-00600: internal error code, arguments: -9064, the archive log and backup data are not continuous";
ORACLE_STR_USER_ERROR[-OB_ARCHIVE_LOG_NOT_CONTINUES_WITH_DATA] = "ORA-00600: internal error code, arguments: -9064, the archive log and backup data are not continuous"; ORACLE_STR_USER_ERROR[-OB_ARCHIVE_LOG_NOT_CONTINUES_WITH_DATA] = "ORA-00600: internal error code, arguments: -9064, the archive log and backup data are not continuous";
ERROR_NAME[-OB_BACKUP_DELETE_BACKUP_PIECE_NOT_ALLOWED] = "OB_BACKUP_DELETE_BACKUP_PIECE_NOT_ALLOWED"; ERROR_NAME[-OB_BACKUP_DELETE_BACKUP_PIECE_NOT_ALLOWED] = "OB_BACKUP_DELETE_BACKUP_PIECE_NOT_ALLOWED";
ERROR_CAUSE[-OB_BACKUP_DELETE_BACKUP_PIECE_NOT_ALLOWED] = "Internal Error";
ERROR_SOLUTION[-OB_BACKUP_DELETE_BACKUP_PIECE_NOT_ALLOWED] = "Contact OceanBase Support";
MYSQL_ERRNO[-OB_BACKUP_DELETE_BACKUP_PIECE_NOT_ALLOWED] = -1; MYSQL_ERRNO[-OB_BACKUP_DELETE_BACKUP_PIECE_NOT_ALLOWED] = -1;
SQLSTATE[-OB_BACKUP_DELETE_BACKUP_PIECE_NOT_ALLOWED] = "HY000"; SQLSTATE[-OB_BACKUP_DELETE_BACKUP_PIECE_NOT_ALLOWED] = "HY000";
STR_ERROR[-OB_BACKUP_DELETE_BACKUP_PIECE_NOT_ALLOWED] = "deleting backup piece is not allowed"; STR_ERROR[-OB_BACKUP_DELETE_BACKUP_PIECE_NOT_ALLOWED] = "deleting backup piece is not allowed";
...@@ -1325,7 +1325,7 @@ DEFINE_ERROR_EXT(OB_ERR_WINDOW_NAME_IS_NOT_DEFINE, -5929, -1, "HY000", "Window n ...@@ -1325,7 +1325,7 @@ DEFINE_ERROR_EXT(OB_ERR_WINDOW_NAME_IS_NOT_DEFINE, -5929, -1, "HY000", "Window n
DEFINE_ORACLE_ERROR(OB_ERR_OPEN_CURSORS_EXCEEDED, -5930, -1, "HY000", "maximum open cursors exceeded", 1000, "maximum open cursors exceeded"); DEFINE_ORACLE_ERROR(OB_ERR_OPEN_CURSORS_EXCEEDED, -5930, -1, "HY000", "maximum open cursors exceeded", 1000, "maximum open cursors exceeded");
DEFINE_ORACLE_ERROR(OB_ERR_ARG_INVALID, -5931, -1, "HY000", "argument is null, invalid, or out of range", 21560, "argument %.*s is null, invalid, or out of range"); DEFINE_ORACLE_ERROR(OB_ERR_ARG_INVALID, -5931, -1, "HY000", "argument is null, invalid, or out of range", 21560, "argument %.*s is null, invalid, or out of range");
DEFINE_ORACLE_ERROR(OB_ERR_ILL_NAME_STRING, -5932, -1, "HY000", "unexpected name string", 21560, "unexpected name string '%.*s'"); DEFINE_ORACLE_ERROR(OB_ERR_ILL_NAME_STRING, -5932, -1, "HY000", "unexpected name string", 21560, "unexpected name string '%.*s'");
DEFINE_ERROR_EXT(OB_ERR_CTE_NEED_QUERY_BLOCKS, -5976, -1, "HY000", "Recursive Common Table Expression should have one or more non-recursive query blocks followed by one or more recursive ones", "Recursive Common Table Expression should have one or more non-recursive query blocks followed by one or more recursive ones: %s"); DEFINE_ERROR_EXT(OB_ERR_CTE_NEED_QUERY_BLOCKS, -5976, 3574, "HY000", "Recursive Common Table Expression should have one or more non-recursive query blocks followed by one or more recursive ones", "Recursive Common Table Expression should have one or more non-recursive query blocks followed by one or more recursive ones: %s");
DEFINE_ERROR_EXT(OB_ERR_INCORRECT_VALUE_FOR_FUNCTION, -5936, ER_WRONG_VALUE_FOR_TYPE, "HY000", "Incorrect value for function", "Incorrect %.*s value: '%.*s' for function %.*s"); DEFINE_ERROR_EXT(OB_ERR_INCORRECT_VALUE_FOR_FUNCTION, -5936, ER_WRONG_VALUE_FOR_TYPE, "HY000", "Incorrect value for function", "Incorrect %.*s value: '%.*s' for function %.*s");
DEFINE_ERROR_EXT(OB_ERR_USER_EXCEED_RESOURCE, -5967, 1226, "42000", "User has exceeded the resource", "User '%.*s' has exceeded the '%s' resource (current value: %lu)"); DEFINE_ERROR_EXT(OB_ERR_USER_EXCEED_RESOURCE, -5967, 1226, "42000", "User has exceeded the resource", "User '%.*s' has exceeded the '%s' resource (current value: %lu)");
......
...@@ -825,7 +825,7 @@ int ObSelectStmtPrinter::print_for_update() ...@@ -825,7 +825,7 @@ int ObSelectStmtPrinter::print_for_update()
int ObSelectStmtPrinter::print_with() int ObSelectStmtPrinter::print_with()
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
DATA_PRINTF("WITH "); DATA_PRINTF(is_oracle_mode() ? "WITH " : "WITH RECURSIVE");
if (OB_SUCC(ret)) { if (OB_SUCC(ret)) {
const ObSelectStmt* select_stmt = static_cast<const ObSelectStmt*>(stmt_); const ObSelectStmt* select_stmt = static_cast<const ObSelectStmt*>(stmt_);
const common::ObIArray<TableItem*>& cte_tables = select_stmt->get_CTE_table_items(); const common::ObIArray<TableItem*>& cte_tables = select_stmt->get_CTE_table_items();
......
...@@ -4816,15 +4816,16 @@ int ObOptimizerUtil::is_lossless_column_cast(const ObRawExpr* expr, bool& is_los ...@@ -4816,15 +4816,16 @@ int ObOptimizerUtil::is_lossless_column_cast(const ObRawExpr* expr, bool& is_los
} }
int ObOptimizerUtil::gen_set_target_list(ObIAllocator* allocator, ObSQLSessionInfo* session_info, int ObOptimizerUtil::gen_set_target_list(ObIAllocator* allocator, ObSQLSessionInfo* session_info,
ObRawExprFactory* expr_factory, ObSelectStmt& left_stmt, ObSelectStmt& right_stmt, ObSelectStmt* select_stmt) ObRawExprFactory* expr_factory, ObSelectStmt& left_stmt, ObSelectStmt& right_stmt,
ObSelectStmt* select_stmt, const bool to_left_type /* false */)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
ObSEArray<ObSelectStmt*, 1> left_stmts; ObSEArray<ObSelectStmt*, 1> left_stmts;
ObSEArray<ObSelectStmt*, 1> right_stmts; ObSEArray<ObSelectStmt*, 1> right_stmts;
if (OB_FAIL(left_stmts.push_back(&left_stmt)) || OB_FAIL(right_stmts.push_back(&right_stmt))) { if (OB_FAIL(left_stmts.push_back(&left_stmt)) || OB_FAIL(right_stmts.push_back(&right_stmt))) {
LOG_WARN("failed to pushback stmt", K(ret)); LOG_WARN("failed to pushback stmt", K(ret));
} else if (OB_FAIL( } else if (OB_FAIL(gen_set_target_list(
gen_set_target_list(allocator, session_info, expr_factory, left_stmts, right_stmts, select_stmt))) { allocator, session_info, expr_factory, left_stmts, right_stmts, select_stmt, to_left_type))) {
LOG_WARN("failed to get set target list", K(ret)); LOG_WARN("failed to get set target list", K(ret));
} }
return ret; return ret;
...@@ -4832,7 +4833,7 @@ int ObOptimizerUtil::gen_set_target_list(ObIAllocator* allocator, ObSQLSessionIn ...@@ -4832,7 +4833,7 @@ int ObOptimizerUtil::gen_set_target_list(ObIAllocator* allocator, ObSQLSessionIn
int ObOptimizerUtil::gen_set_target_list(ObIAllocator* allocator, ObSQLSessionInfo* session_info, int ObOptimizerUtil::gen_set_target_list(ObIAllocator* allocator, ObSQLSessionInfo* session_info,
ObRawExprFactory* expr_factory, ObIArray<ObSelectStmt*>& left_stmts, ObIArray<ObSelectStmt*>& right_stmts, ObRawExprFactory* expr_factory, ObIArray<ObSelectStmt*>& left_stmts, ObIArray<ObSelectStmt*>& right_stmts,
ObSelectStmt* select_stmt) ObSelectStmt* select_stmt, const bool to_left_type /* false */)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
UNUSED(allocator); UNUSED(allocator);
...@@ -4847,7 +4848,8 @@ int ObOptimizerUtil::gen_set_target_list(ObIAllocator* allocator, ObSQLSessionIn ...@@ -4847,7 +4848,8 @@ int ObOptimizerUtil::gen_set_target_list(ObIAllocator* allocator, ObSQLSessionIn
select_stmt->is_set_distinct(), select_stmt->is_set_distinct(),
left_stmts, left_stmts,
right_stmts, right_stmts,
&res_types))) { &res_types,
to_left_type))) {
LOG_WARN("failed to try add cast to set child list", K(ret)); LOG_WARN("failed to try add cast to set child list", K(ret));
} else if (OB_ISNULL(child_stmt = select_stmt->get_set_query(0)) || } else if (OB_ISNULL(child_stmt = select_stmt->get_set_query(0)) ||
OB_UNLIKELY(res_types.count() != child_stmt->get_select_item_size())) { OB_UNLIKELY(res_types.count() != child_stmt->get_select_item_size())) {
...@@ -5031,7 +5033,7 @@ int ObOptimizerUtil::get_set_res_types(ObIAllocator* allocator, ObSQLSessionInfo ...@@ -5031,7 +5033,7 @@ int ObOptimizerUtil::get_set_res_types(ObIAllocator* allocator, ObSQLSessionInfo
int ObOptimizerUtil::try_add_cast_to_set_child_list(ObIAllocator* allocator, ObSQLSessionInfo* session_info, int ObOptimizerUtil::try_add_cast_to_set_child_list(ObIAllocator* allocator, ObSQLSessionInfo* session_info,
ObRawExprFactory* expr_factory, const bool is_distinct, ObIArray<ObSelectStmt*>& left_stmts, ObRawExprFactory* expr_factory, const bool is_distinct, ObIArray<ObSelectStmt*>& left_stmts,
ObIArray<ObSelectStmt*>& right_stmts, ObIArray<ObExprResType>* res_types) ObIArray<ObSelectStmt*>& right_stmts, ObIArray<ObExprResType>* res_types, const bool to_left_type /* false */)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
ObExprResType res_type; ObExprResType res_type;
...@@ -5107,6 +5109,8 @@ int ObOptimizerUtil::try_add_cast_to_set_child_list(ObIAllocator* allocator, ObS ...@@ -5107,6 +5109,8 @@ int ObOptimizerUtil::try_add_cast_to_set_child_list(ObIAllocator* allocator, ObS
} }
const ObLengthSemantics length_semantics = session_info->get_actual_nls_length_semantics(); const ObLengthSemantics length_semantics = session_info->get_actual_nls_length_semantics();
if (OB_FAIL(ret)) { if (OB_FAIL(ret)) {
} else if (to_left_type) {
res_type = left_type;
} else if (OB_FAIL(types.push_back(left_type)) || OB_FAIL(types.push_back(right_type))) { } else if (OB_FAIL(types.push_back(left_type)) || OB_FAIL(types.push_back(right_type))) {
LOG_WARN("failed to push back", K(ret)); LOG_WARN("failed to push back", K(ret));
} else if (OB_FAIL(session_info->get_collation_connection(coll_type))) { } else if (OB_FAIL(session_info->get_collation_connection(coll_type))) {
...@@ -5114,6 +5118,8 @@ int ObOptimizerUtil::try_add_cast_to_set_child_list(ObIAllocator* allocator, ObS ...@@ -5114,6 +5118,8 @@ int ObOptimizerUtil::try_add_cast_to_set_child_list(ObIAllocator* allocator, ObS
} else if (OB_FAIL(dummy_op.aggregate_result_type_for_merge( } else if (OB_FAIL(dummy_op.aggregate_result_type_for_merge(
res_type, &types.at(0), 2, coll_type, is_oracle_mode(), length_semantics, session_info))) { res_type, &types.at(0), 2, coll_type, is_oracle_mode(), length_semantics, session_info))) {
LOG_WARN("failed to aggregate result type for merge", K(ret)); LOG_WARN("failed to aggregate result type for merge", K(ret));
}
if (OB_FAIL(ret)) {
} else if (ObMaxType == res_type.get_type()) { } else if (ObMaxType == res_type.get_type()) {
ret = OB_ERR_INVALID_TYPE_FOR_OP; ret = OB_ERR_INVALID_TYPE_FOR_OP;
LOG_WARN("column type incompatible", K(left_type), K(right_type)); LOG_WARN("column type incompatible", K(left_type), K(right_type));
......
...@@ -588,11 +588,12 @@ public: ...@@ -588,11 +588,12 @@ public:
static int is_lossless_column_cast(const ObRawExpr* expr, bool& is_lossless); static int is_lossless_column_cast(const ObRawExpr* expr, bool& is_lossless);
static int gen_set_target_list(ObIAllocator* allocator, ObSQLSessionInfo* session_info, static int gen_set_target_list(ObIAllocator* allocator, ObSQLSessionInfo* session_info,
ObRawExprFactory* expr_factory, ObSelectStmt& left_stmt, ObSelectStmt& right_stmt, ObSelectStmt* select_stmt); ObRawExprFactory* expr_factory, ObSelectStmt& left_stmt, ObSelectStmt& right_stmt,
ObSelectStmt* select_stmt, const bool to_left_type = false);
static int gen_set_target_list(ObIAllocator* allocator, ObSQLSessionInfo* session_info, static int gen_set_target_list(ObIAllocator* allocator, ObSQLSessionInfo* session_info,
ObRawExprFactory* expr_factory, ObIArray<ObSelectStmt*>& left_stmts, ObIArray<ObSelectStmt*>& right_stmts, ObRawExprFactory* expr_factory, ObIArray<ObSelectStmt*>& left_stmts, ObIArray<ObSelectStmt*>& right_stmts,
ObSelectStmt* select_stmt); ObSelectStmt* select_stmt, const bool to_left_type = false);
static int gen_set_target_list(ObIAllocator* allocator, ObSQLSessionInfo* session_info, static int gen_set_target_list(ObIAllocator* allocator, ObSQLSessionInfo* session_info,
ObRawExprFactory* expr_factory, ObSelectStmt* select_stmt); ObRawExprFactory* expr_factory, ObSelectStmt* select_stmt);
...@@ -602,7 +603,8 @@ public: ...@@ -602,7 +603,8 @@ public:
static int try_add_cast_to_set_child_list(ObIAllocator* allocator, ObSQLSessionInfo* session_info, static int try_add_cast_to_set_child_list(ObIAllocator* allocator, ObSQLSessionInfo* session_info,
ObRawExprFactory* expr_factory, const bool is_distinct, ObIArray<ObSelectStmt*>& left_stmts, ObRawExprFactory* expr_factory, const bool is_distinct, ObIArray<ObSelectStmt*>& left_stmts,
ObIArray<ObSelectStmt*>& right_stmts, ObIArray<ObExprResType>* res_types); ObIArray<ObSelectStmt*>& right_stmts, ObIArray<ObExprResType>* res_types,
const bool to_left_type = false);
static int add_cast_to_set_list(ObSQLSessionInfo* session_info, ObRawExprFactory* expr_factory, static int add_cast_to_set_list(ObSQLSessionInfo* session_info, ObRawExprFactory* expr_factory,
ObIArray<ObSelectStmt*>& stmts, const ObExprResType& res_type, const int64_t idx); ObIArray<ObSelectStmt*>& stmts, const ObExprResType& res_type, const int64_t idx);
......
...@@ -172,8 +172,13 @@ int ObSelectResolver::do_resolve_set_query_in_cte(const ParseNode& parse_tree) ...@@ -172,8 +172,13 @@ int ObSelectResolver::do_resolve_set_query_in_cte(const ParseNode& parse_tree)
select_stmt->add_set_query(left_select_stmt); select_stmt->add_set_query(left_select_stmt);
select_stmt->add_set_query(right_select_stmt); select_stmt->add_set_query(right_select_stmt);
select_stmt->set_calc_found_rows(left_select_stmt->is_calc_found_rows()); select_stmt->set_calc_found_rows(left_select_stmt->is_calc_found_rows());
if (OB_FAIL(ObOptimizerUtil::gen_set_target_list( if (OB_FAIL(ObOptimizerUtil::gen_set_target_list(allocator_,
allocator_, session_info_, params_.expr_factory_, *left_select_stmt, *right_select_stmt, select_stmt))) { session_info_,
params_.expr_factory_,
*left_select_stmt,
*right_select_stmt,
select_stmt,
!is_oracle_mode()))) {
LOG_WARN("failed to gen set target list.", K(ret)); LOG_WARN("failed to gen set target list.", K(ret));
} else if (!right_resolver.cte_ctx_.is_recursive()) { } else if (!right_resolver.cte_ctx_.is_recursive()) {
/*do nothing*/ /*do nothing*/
...@@ -2169,9 +2174,9 @@ int ObSelectResolver::resolve_with_clause(const ParseNode* node, bool same_level ...@@ -2169,9 +2174,9 @@ int ObSelectResolver::resolve_with_clause(const ParseNode* node, bool same_level
} else { } else {
int num_child = node->num_child_; int num_child = node->num_child_;
if (node->value_ == 0) if (node->value_ == 0)
params_.has_recursive_word = false; params_.has_recursive_word_ = false;
else else
params_.has_recursive_word = true; params_.has_recursive_word_ = true;
for (int64_t i = 0; OB_SUCC(ret) && i < num_child; ++i) { for (int64_t i = 0; OB_SUCC(ret) && i < num_child; ++i) {
// alias tblname [(alia colname1, alia colname2)](subquery) [search clause][cycle clause] // alias tblname [(alia colname1, alia colname2)](subquery) [search clause][cycle clause]
ParseNode* child_node = node->children_[i]; ParseNode* child_node = node->children_[i];
...@@ -2186,7 +2191,13 @@ int ObSelectResolver::resolve_with_clause(const ParseNode* node, bool same_level ...@@ -2186,7 +2191,13 @@ int ObSelectResolver::resolve_with_clause(const ParseNode* node, bool same_level
if (OB_FAIL(select_stmt->check_CTE_name_exist(table_name, duplicate_name))) { if (OB_FAIL(select_stmt->check_CTE_name_exist(table_name, duplicate_name))) {
LOG_WARN("check cte name failed", K(ret)); LOG_WARN("check cte name failed", K(ret));
} else if (duplicate_name) { } else if (duplicate_name) {
// do nothing, oracle ignore the same define cte name. if (is_oracle_mode()) {
// do nothing, oracle ignore the same define cte name.
} else {
ret = OB_ERR_NONUNIQ_TABLE;
LOG_WARN("not unique cte table name", K(ret));
LOG_USER_ERROR(OB_ERR_NONUNIQ_TABLE, table_name.length(), table_name.ptr());
}
} else if (OB_FAIL(resolve_with_clause_subquery(*child_node, table_item))) { } else if (OB_FAIL(resolve_with_clause_subquery(*child_node, table_item))) {
LOG_WARN("resolver with_clause_as's subquery failed", K(ret)); LOG_WARN("resolver with_clause_as's subquery failed", K(ret));
} else if (OB_FAIL(select_stmt->add_cte_table_item(table_item, duplicate_name))) { } else if (OB_FAIL(select_stmt->add_cte_table_item(table_item, duplicate_name))) {
...@@ -3132,10 +3143,7 @@ int ObSelectResolver::resolve_recursive_cte_table(const ParseNode& parse_tree, T ...@@ -3132,10 +3143,7 @@ int ObSelectResolver::resolve_recursive_cte_table(const ParseNode& parse_tree, T
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
ObSelectStmt* base_stmt = cte_ctx_.left_select_stmt_; ObSelectStmt* base_stmt = cte_ctx_.left_select_stmt_;
if (cte_ctx_.cte_col_names_.empty()) { if (OB_ISNULL(base_stmt) && cte_ctx_.is_set_left_resolver_) {
ret = OB_ERR_NEED_COLUMN_ALIAS_LIST_IN_RECURSIVE_CTE;
LOG_WARN("recursive WITH clause must have column alias list", K(ret));
} else if (OB_ISNULL(base_stmt) && cte_ctx_.is_set_left_resolver_) {
ret = OB_ERR_NEED_INIT_BRANCH_IN_RECURSIVE_CTE; ret = OB_ERR_NEED_INIT_BRANCH_IN_RECURSIVE_CTE;
LOG_WARN("recursive WITH clause needs an initialization branch", K(ret)); LOG_WARN("recursive WITH clause needs an initialization branch", K(ret));
} else if (OB_ISNULL(base_stmt)) { } else if (OB_ISNULL(base_stmt)) {
...@@ -3318,8 +3326,11 @@ int ObSelectResolver::resolve_basic_table(const ParseNode& parse_tree, TableItem ...@@ -3318,8 +3326,11 @@ int ObSelectResolver::resolve_basic_table(const ParseNode& parse_tree, TableItem
ObString tblname(table_node->str_len_, table_node->str_value_); ObString tblname(table_node->str_len_, table_node->str_value_);
if (cte_ctx_.is_with_resolver() && ObCharset::case_insensitive_equal(cte_ctx_.current_cte_table_name_, tblname) && if (cte_ctx_.is_with_resolver() && ObCharset::case_insensitive_equal(cte_ctx_.current_cte_table_name_, tblname) &&
tblname.length() && no_defined_database_name) { tblname.length() && no_defined_database_name) {
TableItem* item = NULL; TableItem *item = NULL;
if (OB_FAIL(resolve_recursive_cte_table(parse_tree, item))) { if (!params_.has_recursive_word_) {
ret = OB_TABLE_NOT_EXIST;
LOG_WARN("cte table shows in union stmt without recursive keyword", K(ret));
} else if (OB_FAIL(resolve_recursive_cte_table(parse_tree, item))) {
LOG_WARN("revolve recursive set query's right child failed", K(ret)); LOG_WARN("revolve recursive set query's right child failed", K(ret));
} else if (cte_ctx_.more_than_two_branch()) { } else if (cte_ctx_.more_than_two_branch()) {
ret = OB_ERR_NEED_ONLY_TWO_BRANCH_IN_RECURSIVE_CTE; ret = OB_ERR_NEED_ONLY_TWO_BRANCH_IN_RECURSIVE_CTE;
...@@ -5504,9 +5515,12 @@ int ObSelectResolver::identify_anchor_member( ...@@ -5504,9 +5515,12 @@ int ObSelectResolver::identify_anchor_member(
need_swap_childa = true; need_swap_childa = true;
if (is_oracle_mode()){ if (is_oracle_mode()){
ret = OB_SUCCESS; ret = OB_SUCCESS;
} else if (params_.has_recursive_word) { } else if (params_.has_recursive_word_) {
ret = OB_ERR_CTE_NEED_QUERY_BLOCKS; // mysql error: Recursive Common Table Expression 'cte' should have one or ret = OB_ERR_CTE_NEED_QUERY_BLOCKS; // mysql error: Recursive Common Table Expression 'cte' should have one or
// more non-recursive query blocks followed by one or more recursive ones // more non-recursive query blocks followed by one or more recursive ones
} else {
ret = OB_TABLE_NOT_EXIST;
LOG_WARN("cte table shows in left union stmt without recursive keyword", K(ret));
} }
} else { } else {
LOG_WARN("Failed to find anchor member", K(ret)); LOG_WARN("Failed to find anchor member", K(ret));
......
...@@ -288,7 +288,7 @@ struct ObResolverParams { ...@@ -288,7 +288,7 @@ struct ObResolverParams {
is_multi_table_insert_(false), is_multi_table_insert_(false),
is_resolve_table_function_expr_(false), is_resolve_table_function_expr_(false),
has_cte_param_list_(false), has_cte_param_list_(false),
has_recursive_word(false), has_recursive_word_(false),
is_column_ref_(true) is_column_ref_(true)
{} {}
bool is_force_trace_log() bool is_force_trace_log()
...@@ -343,7 +343,7 @@ public: ...@@ -343,7 +343,7 @@ public:
bool is_multi_table_insert_; // used to mark is multi table insert bool is_multi_table_insert_; // used to mark is multi table insert
bool is_resolve_table_function_expr_; // used to mark resolve table function expr. bool is_resolve_table_function_expr_; // used to mark resolve table function expr.
bool has_cte_param_list_; bool has_cte_param_list_;
bool has_recursive_word; bool has_recursive_word_;
bool is_column_ref_; // used to mark normal column ref bool is_column_ref_; // used to mark normal column ref
}; };
} // end namespace sql } // end namespace sql
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册