/** * Copyright (c) 2021 OceanBase * OceanBase CE is licensed under Mulan PubL v2. * You can use this software according to the terms and conditions of the Mulan PubL v2. * You may obtain a copy of Mulan PubL v2 at: * http://license.coscl.org.cn/MulanPubL-2.0 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PubL v2 for more details. */ #define USING_LOG_PREFIX SQL_RESV #include "sql/ob_sql_context.h" #include #include "lib/container/ob_se_array_iterator.h" #include "sql/resolver/dml/ob_sql_hint.h" #include "sql/ob_sql_define.h" #include "sql/optimizer/ob_log_plan.h" #include "share/schema/ob_schema_getter_guard.h" using namespace ::oceanbase::common; namespace oceanbase { using namespace share::schema; namespace sql { bool LocationConstraint::operator==(const LocationConstraint& other) const { return key_ == other.key_ && phy_loc_type_ == other.phy_loc_type_ && constraint_flags_ == other.constraint_flags_; } bool LocationConstraint::operator!=(const LocationConstraint& other) const { return !(*this == other); } int LocationConstraint::calc_constraints_inclusion( const ObLocationConstraint* left, const ObLocationConstraint* right, InclusionType& inclusion_result) { int ret = OB_SUCCESS; inclusion_result = NotSubset; if (OB_ISNULL(left) || OB_ISNULL(right)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(left), K(right)); } else { const ObLocationConstraint *set1 = NULL, *set2 = NULL; bool is_subset = true; // insure set1.count() >= set2.count() if (left->count() >= right->count()) { inclusion_result = LeftIsSuperior; set1 = left; set2 = right; } else { inclusion_result = RightIsSuperior; set1 = right; set2 = left; } for (int64_t i = 0; is_subset && i < set2->count(); i++) { bool detected = false; for (int64_t j = 0; !detected && j < set1->count(); j++) { if (set2->at(i) == set1->at(j)) { detected = true; } } // if the element is not in set1, set1 can not contain all the elements in set2 if (!detected) { is_subset = false; } } if (!is_subset) { inclusion_result = NotSubset; } } return ret; } int ObLocationConstraintContext::calc_constraints_inclusion( const ObPwjConstraint* left, const ObPwjConstraint* right, InclusionType& inclusion_result) { int ret = OB_SUCCESS; inclusion_result = NotSubset; if (OB_ISNULL(left) || OB_ISNULL(right)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret), K(left), K(right)); } else { const ObPwjConstraint *set1 = NULL, *set2 = NULL; bool is_subset = true; // insure set1.count() >= set2.count() if (left->count() >= right->count()) { inclusion_result = LeftIsSuperior; set1 = left; set2 = right; } else { inclusion_result = RightIsSuperior; set1 = right; set2 = left; } for (int64_t i = 0; is_subset && i < set2->count(); i++) { bool detected = false; for (int64_t j = 0; !detected && j < set1->count(); j++) { if (set2->at(i) == set1->at(j)) { detected = true; } } // if the element is not in set1, set1 can not contain all the elements in set2 if (!detected) { is_subset = false; } } if (!is_subset) { inclusion_result = NotSubset; } } return ret; } int ObQueryRetryInfo::init() { int ret = OB_SUCCESS; if (OB_UNLIKELY(inited_)) { ret = OB_INIT_TWICE; LOG_ERROR("init twice", K(ret)); } else { inited_ = true; } return ret; } void ObQueryRetryInfo::reset() { inited_ = false; is_rpc_timeout_ = false; invalid_servers_.reset(); last_query_retry_err_ = OB_SUCCESS; } void ObQueryRetryInfo::clear() { // here cannot set inited_ as false is_rpc_timeout_ = false; invalid_servers_.reset(); // last_query_retry_err_ = OB_SUCCESS; } void ObQueryRetryInfo::clear_state_before_each_retry() { is_rpc_timeout_ = false; // The accumulated members of successive retry cannot be cleared here, such as invalid_servers_, last_query_retry_err_ } // Combine retry information, // used for the retry information combination of the main thread and the scheduling thread int ObQueryRetryInfo::merge(const ObQueryRetryInfo& other) { int ret = OB_SUCCESS; if (other.is_rpc_timeout_) { is_rpc_timeout_ = other.is_rpc_timeout_; } for (int64_t i = 0; OB_SUCC(ret) && i < other.invalid_servers_.count(); ++i) { if (OB_FAIL(add_invalid_server_distinctly(other.invalid_servers_.at(i)))) { LOG_WARN("fail to add invalid server distinctly", K(ret), K(i), K(other.invalid_servers_.at(i)), K(other.invalid_servers_), K(invalid_servers_)); } } // last_query_retry_err_ will not be modified on the scheduling thread, so don't worry about it here return ret; } void ObQueryRetryInfo::set_is_rpc_timeout(bool is_rpc_timeout) { is_rpc_timeout_ = is_rpc_timeout; } bool ObQueryRetryInfo::is_rpc_timeout() const { return is_rpc_timeout_; } int ObQueryRetryInfo::add_invalid_server_distinctly(const ObAddr& invalid_server, bool print_info_log /* = false*/) { int ret = OB_SUCCESS; bool is_found = false; for (int64_t i = 0; OB_SUCC(ret) && !is_found && i < invalid_servers_.count(); ++i) { if (invalid_server == invalid_servers_.at(i)) { is_found = true; } } if (OB_SUCC(ret) && !is_found) { if (OB_FAIL(invalid_servers_.push_back(invalid_server))) { LOG_WARN("fail to push back invalid server", K(ret), K(invalid_server)); } } if (print_info_log) { LOG_INFO("add a server to invalid server list", K(ret), K(invalid_server), K(invalid_servers_)); } return ret; } ObSqlCtx::ObSqlCtx() : multi_stmt_item_(), session_info_(NULL), schema_guard_(NULL), sql_proxy_(NULL), vt_iter_factory_(NULL), use_plan_cache_(true), plan_cache_hit_(false), self_add_plan_(false), disable_privilege_check_(PRIV_CHECK_FLAG_NORMAL), partition_table_operator_(NULL), session_mgr_(NULL), part_mgr_(NULL), partition_location_cache_(NULL), merged_version_(OB_MERGED_VERSION_INIT), force_print_trace_(false), is_show_trace_stmt_(false), retry_times_(OB_INVALID_COUNT), exec_type_(InvalidType), is_prepare_protocol_(false), is_prepare_stage_(false), is_dynamic_sql_(false), is_dbms_sql_(false), is_cursor_(false), is_remote_sql_(false), is_execute_async_(false), statement_id_(common::OB_INVALID_ID), stmt_type_(stmt::T_NONE), partition_infos_(), is_restore_(false), // retry_info_(), need_late_compile_(false), is_bushy_tree_(false), all_plan_const_param_constraints_(nullptr), all_possible_const_param_constraints_(nullptr), all_equal_param_constraints_(nullptr), trans_happened_route_(nullptr), is_ddl_from_primary_(false), cur_stmt_(NULL), can_reroute_sql_(false), reroute_info_(), is_sensitive_(false) { sql_id_[0] = '\0'; sql_id_[common::OB_MAX_SQL_ID_LENGTH] = '\0'; } void ObSqlCtx::reset() { multi_stmt_item_.reset(); session_info_ = NULL; sql_schema_guard_.reset(); schema_guard_ = NULL; sql_proxy_ = NULL; vt_iter_factory_ = NULL; use_plan_cache_ = false; plan_cache_hit_ = false; self_add_plan_ = false; disable_privilege_check_ = PRIV_CHECK_FLAG_NORMAL; partition_table_operator_ = NULL; session_mgr_ = NULL; partition_location_cache_ = NULL; merged_version_ = OB_MERGED_VERSION_INIT; force_print_trace_ = false; is_show_trace_stmt_ = false; retry_times_ = OB_INVALID_COUNT; sql_id_[0] = '\0'; sql_id_[common::OB_MAX_SQL_ID_LENGTH] = '\0'; exec_type_ = InvalidType; is_prepare_protocol_ = false; is_prepare_stage_ = false; is_dynamic_sql_ = false; is_remote_sql_ = false; is_execute_async_ = false; is_restore_ = false; loc_sensitive_hint_.reset(); need_late_compile_ = false; all_plan_const_param_constraints_ = nullptr; all_possible_const_param_constraints_ = nullptr; all_equal_param_constraints_ = nullptr; trans_happened_route_ = nullptr; is_bushy_tree_ = false; is_ddl_from_primary_ = false; can_reroute_sql_ = false; reroute_info_.reset(); is_sensitive_ = false; clear(); } // release dynamic allocated memory void ObSqlCtx::clear() { cur_stmt_ = NULL; acs_index_infos_.reset(); partition_infos_.reset(); related_user_var_names_.reset(); base_constraints_.reset(); strict_constraints_.reset(); non_strict_constraints_.reset(); multi_stmt_rowkey_pos_.reset(); } void ObSqlSchemaGuard::reset() { table_schemas_.reset(); schema_guard_ = NULL; allocator_.reset(); next_link_table_id_ = 1; } int ObSqlSchemaGuard::get_table_schema( uint64_t dblink_id, const ObString& database_name, const ObString& table_name, const ObTableSchema*& table_schema) { int ret = OB_SUCCESS; int64_t schema_count = table_schemas_.count(); table_schema = NULL; for (int64_t i = 0; OB_SUCC(ret) && OB_ISNULL(table_schema) && i < schema_count; i++) { const ObTableSchema* tmp_schema = table_schemas_.at(i); OV(OB_NOT_NULL(tmp_schema)); if (OB_SUCC(ret) && dblink_id == tmp_schema->get_dblink_id() && 0 == database_name.compare(tmp_schema->get_link_database_name()) && 0 == table_name.compare(tmp_schema->get_table_name_str())) { table_schema = tmp_schema; } } if (OB_SUCC(ret) && OB_ISNULL(table_schema)) { ObTableSchema* tmp_schema = NULL; OV(OB_NOT_NULL(schema_guard_), OB_NOT_INIT); OZ(schema_guard_->get_link_table_schema(dblink_id, database_name, table_name, allocator_, tmp_schema)); OV(OB_NOT_NULL(tmp_schema)); OX(tmp_schema->set_link_table_id(tmp_schema->get_table_id())); OX(tmp_schema->set_table_id(combine_link_table_id(dblink_id, next_link_table_id_++))); OV(tmp_schema->get_table_id() != OB_INVALID_ID, OB_ERR_UNEXPECTED, dblink_id, next_link_table_id_); OZ(table_schemas_.push_back(tmp_schema)); OX(table_schema = tmp_schema); } return ret; } int ObSqlSchemaGuard::get_table_schema(uint64_t table_id, const ObTableSchema*& table_schema) const { int ret = OB_SUCCESS; if (is_link_table_id(table_id)) { OZ(get_link_table_schema(table_id, table_schema), table_id); } else { OV(OB_NOT_NULL(schema_guard_)); OZ(schema_guard_->get_table_schema(table_id, table_schema), table_id); } return ret; } int ObSqlSchemaGuard::get_column_schema( uint64_t table_id, const ObString& column_name, const ObColumnSchemaV2*& column_schema) const { int ret = OB_SUCCESS; if (is_link_table_id(table_id)) { OZ(get_link_column_schema(table_id, column_name, column_schema), table_id, column_name); } else { OV(OB_NOT_NULL(schema_guard_)); OZ(schema_guard_->get_column_schema(table_id, column_name, column_schema), table_id, column_name); } return ret; } int ObSqlSchemaGuard::get_column_schema( uint64_t table_id, uint64_t column_id, const ObColumnSchemaV2*& column_schema) const { int ret = OB_SUCCESS; if (is_link_table_id(table_id)) { OZ(get_link_column_schema(table_id, column_id, column_schema), table_id, column_id); } else { OV(OB_NOT_NULL(schema_guard_)); OZ(schema_guard_->get_column_schema(table_id, column_id, column_schema), table_id, column_id); } return ret; } int ObSqlSchemaGuard::get_table_schema_version(const uint64_t table_id, int64_t& schema_version) const { int ret = OB_SUCCESS; if (is_link_table_id(table_id)) { const ObTableSchema* table_schema = NULL; OZ(get_link_table_schema(table_id, table_schema), table_id); OV(OB_NOT_NULL(table_schema), OB_TABLE_NOT_EXIST, table_id); OX(schema_version = table_schema->get_schema_version()); } else { OV(OB_NOT_NULL(schema_guard_)); OZ(schema_guard_->get_table_schema_version(table_id, schema_version), table_id); } return ret; } int ObSqlSchemaGuard::get_partition_cnt(uint64_t table_id, int64_t& part_cnt) const { int ret = OB_SUCCESS; if (is_link_table_id(table_id)) { part_cnt = 1; } else { OV(OB_NOT_NULL(schema_guard_)); OZ(schema_guard_->get_partition_cnt(table_id, part_cnt), table_id); } return ret; } int ObSqlSchemaGuard::get_can_read_index_array(uint64_t table_id, uint64_t* index_tid_array, int64_t& size, bool with_mv, bool with_global_index, bool with_domain_index) { int ret = OB_SUCCESS; if (is_link_table_id(table_id)) { size = 0; } else { OV(OB_NOT_NULL(schema_guard_)); OZ(schema_guard_->get_can_read_index_array( table_id, index_tid_array, size, with_mv, with_global_index, with_domain_index)); } return ret; } int ObSqlSchemaGuard::get_link_table_schema(uint64_t table_id, const ObTableSchema*& table_schema) const { int ret = OB_SUCCESS; int64_t schema_count = table_schemas_.count(); const ObTableSchema* tmp_schema = NULL; table_schema = NULL; for (int64_t i = 0; OB_SUCC(ret) && OB_ISNULL(table_schema) && i < schema_count; i++) { OX(tmp_schema = table_schemas_.at(i)); OV(OB_NOT_NULL(tmp_schema)); if (OB_SUCC(ret) && table_id == tmp_schema->get_table_id()) { table_schema = tmp_schema; } } return ret; } int ObSqlSchemaGuard::get_link_column_schema( uint64_t table_id, const ObString& column_name, const ObColumnSchemaV2*& column_schema) const { int ret = OB_SUCCESS; const ObTableSchema* table_schema = NULL; OZ(get_table_schema(table_id, table_schema), table_id); if (OB_NOT_NULL(table_schema)) { OX(column_schema = table_schema->get_column_schema(column_name)); } return ret; } int ObSqlSchemaGuard::get_link_column_schema( uint64_t table_id, uint64_t column_id, const ObColumnSchemaV2*& column_schema) const { int ret = OB_SUCCESS; const ObTableSchema* table_schema = NULL; OZ(get_table_schema(table_id, table_schema), table_id); if (OB_NOT_NULL(table_schema)) { OX(column_schema = table_schema->get_column_schema(column_id)); } return ret; } int ObQueryCtx::add_stmt_id_name(const int64_t stmt_id, const common::ObString& stmt_name, ObStmt* stmt) { int ret = OB_SUCCESS; bool name_dup = false; if (stmt_id < 0) { ret = OB_INVALID_ARGUMENT; LOG_WARN("Stmt id is invalid", K(ret), K(stmt_id)); } else { // find name dup and equal id for (int64_t idx = 0; OB_SUCC(ret) && idx < stmt_id_name_map_.count(); ++idx) { if (!stmt_name.empty() && 0 == stmt_name.case_compare(stmt_id_name_map_.at(idx).name_)) { if (name_dup) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Names in array duplicate", K(ret)); } else { name_dup = true; } } if (OB_SUCC(ret)) { if (stmt_id == stmt_id_name_map_.at(idx).id_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Stmt id in array duplicate", K(ret)); } } } if (OB_SUCC(ret)) { ObString final_name = name_dup ? ObString::make_empty_string() : stmt_name; if (!name_dup && !stmt_name.empty() && OB_FAIL(valid_qb_name_stmt_ids_.push_back(stmt_id))) { LOG_WARN("fail to push_back stmt_id", K(ret)); } else if (OB_FAIL(stmt_id_name_map_.push_back( IdNamePair(stmt_id, final_name, ObString::make_empty_string(), stmt->get_stmt_type())))) { SQL_LOG(WARN, "Add stmt id, name pair error", K(ret)); } else if (OB_FAIL(id_stmt_map_.push_back(std::pair(stmt_id, stmt)))) { LOG_WARN("Failed to add id stmt pair", K(ret)); } else { // do nothing } } } return ret; } int ObQueryCtx::generate_stmt_name(ObIAllocator* allocator) { int ret = OB_SUCCESS; uint64_t OB_MAX_QB_NAME_LENGTH = 20; char buf[OB_MAX_QB_NAME_LENGTH]; if (OB_ISNULL(allocator)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Allocator should not be NULL", K(ret)); } else if (stmt_id_name_map_.count() > 0) { std::sort(stmt_id_name_map_.begin(), stmt_id_name_map_.end()); int64_t start_ids[5]; for (int64_t i = 0; i < 5; ++i) { start_ids[i] = 1; } for (int64_t idx = 0; OB_SUCC(ret) && idx < stmt_id_name_map_.count(); ++idx) { IdNamePair& id_name_pair = stmt_id_name_map_.at(idx); if (!id_name_pair.origin_name_.empty()) { // do nothing } else if (stmt::T_SELECT == id_name_pair.stmt_type_ || stmt::T_INSERT == id_name_pair.stmt_type_ || stmt::T_REPLACE == id_name_pair.stmt_type_ || stmt::T_DELETE == id_name_pair.stmt_type_ || stmt::T_UPDATE == id_name_pair.stmt_type_) { int64_t pos = 0; int64_t* start_id = NULL; if (stmt::T_SELECT == id_name_pair.stmt_type_) { start_id = &start_ids[0]; } else if (stmt::T_INSERT == id_name_pair.stmt_type_) { start_id = &start_ids[1]; } else if (stmt::T_REPLACE == id_name_pair.stmt_type_) { start_id = &start_ids[2]; } else if (stmt::T_DELETE == id_name_pair.stmt_type_) { start_id = &start_ids[3]; } else if (stmt::T_UPDATE == id_name_pair.stmt_type_) { start_id = &start_ids[4]; } if (OB_FAIL(get_dml_stmt_name(id_name_pair.stmt_type_, buf, OB_MAX_QB_NAME_LENGTH, pos))) { LOG_WARN("Get dml stmt name", K(ret)); } else if (OB_FAIL(append_id_to_stmt_name(buf, OB_MAX_QB_NAME_LENGTH, pos, *start_id))) { LOG_WARN("Failed to append id to stmt name", K(ret)); } else { ObString generate_name(pos, buf); if (OB_FAIL(ob_write_string(*allocator, generate_name, id_name_pair.origin_name_))) { LOG_WARN("Write string error", K(ret)); } else if (!id_name_pair.name_.empty()) { // do nothing } else if (OB_FAIL(ob_write_string(*allocator, generate_name, id_name_pair.name_))) { LOG_WARN("Write string error", K(ret)); } else { } // do nothing. } } else { } // other stmt type need not generate stmt name } } else { } // do nothing return ret; } int ObQueryCtx::get_dml_stmt_name(stmt::StmtType stmt_type, char* buf, int64_t buf_len, int64_t& pos) { int ret = OB_SUCCESS; if (OB_ISNULL(buf)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("Input buf should not be NULL", K(ret)); } else if (pos < buf_len) { switch (stmt_type) { case stmt::T_SELECT: { if (OB_FAIL(BUF_PRINTF("SEL$"))) { LOG_WARN("Append name to buf error", K(ret)); } break; } case stmt::T_INSERT: { if (OB_FAIL(BUF_PRINTF("INS$"))) { LOG_WARN("Append name to buf error", K(ret)); } break; } case stmt::T_REPLACE: { if (OB_FAIL(BUF_PRINTF("REP$"))) { LOG_WARN("Append name to buf error", K(ret)); } break; } case stmt::T_UPDATE: { if (OB_FAIL(BUF_PRINTF("UPD$"))) { LOG_WARN("Append name to buf error", K(ret)); } break; } case stmt::T_DELETE: { if (OB_FAIL(BUF_PRINTF("DEL$"))) { LOG_WARN("Append name to buf error", K(ret)); } break; } default: { ret = OB_INVALID_ARGUMENT; LOG_WARN("Invalid stmt type to get dml name", K(ret)); } } } else { ret = OB_SIZE_OVERFLOW; LOG_WARN("Buffer size not enough", K(ret)); } return ret; } int ObQueryCtx::append_id_to_stmt_name(char* buf, int64_t buf_len, int64_t& pos, int64_t& id_start) { int ret = OB_SUCCESS; if (OB_ISNULL(buf)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("Buf should not be NULL", K(ret)); } else if (pos >= buf_len) { ret = OB_SIZE_OVERFLOW; LOG_WARN("Buf size not enough", K(ret)); } else { bool find_unique = false; int64_t id = id_start; int64_t old_pos = pos; while (!find_unique && OB_SUCC(ret)) { pos = old_pos; if (OB_FAIL(BUF_PRINTF("%ld", id))) { LOG_WARN("Append idx to stmt_name error", K(ret)); } else { bool find_dup = false; for (int64_t i = 0; !find_dup && i < stmt_id_name_map_.count(); ++i) { if (0 == stmt_id_name_map_.at(i).origin_name_.case_compare(buf)) { find_dup = true; } else { } // do nothing } // end of for find_unique = !find_dup; ++id; } } if (OB_SUCC(ret) && find_unique) { id_start = id; } } return ret; } int ObQueryCtx::find_stmt_id(const ObString& stmt_name, int64_t& stmt_id) { int ret = OB_SUCCESS; stmt_id = -1; if (stmt_name.empty()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("Failed to find stmt id", K(ret)); } else { bool find_stmt = false; for (int64_t idx = 0; OB_SUCC(ret) && !find_stmt && idx < stmt_id_name_map_.count(); ++idx) { if (0 == stmt_name.case_compare(stmt_id_name_map_.at(idx).name_)) { stmt_id = stmt_id_name_map_.at(idx).id_; find_stmt = true; } } } return ret; } ObStmt* ObQueryCtx::find_stmt_by_id(const int64_t stmt_id) { ObStmt* stmt = NULL; if (stmt_id == OB_INVALID_STMT_ID) { } else { for (int64_t idx = 0; idx < id_stmt_map_.count(); ++idx) { if (stmt_id == id_stmt_map_.at(idx).first) { stmt = id_stmt_map_.at(idx).second; break; } } } return stmt; } int ObQueryCtx::replace_name_in_tables(const ObSQLSessionInfo& session_info, ObDMLStmt& stmt, ObIArray& arr, uint64_t table_id, ObString& to_db_name, ObString& to_table_name) { int ret = OB_SUCCESS; for (int64_t i = 0; OB_SUCC(ret) && i < arr.count(); i++) { if (OB_FAIL(ObStmtHint::replace_name_in_hint( session_info, stmt, arr.at(i).tables_, table_id, to_db_name, to_table_name))) { LOG_WARN("Failed to replace name", K(ret)); } } return ret; } int ObQueryCtx::replace_name_for_single_table_view(const ObSQLSessionInfo& session_info, ObDMLStmt* stmt, uint64_t table_id, ObString& to_db_name, ObString& to_table_name) { int ret = OB_SUCCESS; if (OB_ISNULL(stmt)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("NULL stmt", K(ret)); } else if (OB_FAIL(replace_name_in_tables(session_info, *stmt, join_order_, table_id, to_db_name, to_table_name))) { LOG_WARN("failed to replace in join_order_", K(ret)); } else if (OB_FAIL(replace_name_in_tables(session_info, *stmt, use_merge_, table_id, to_db_name, to_table_name))) { LOG_WARN("failed to replace in use_merge_", K(ret)); } else if (OB_FAIL(replace_name_in_tables(session_info, *stmt, no_use_merge_, table_id, to_db_name, to_table_name))) { LOG_WARN("failed to replace in no use_merge_", K(ret)); } else if (OB_FAIL(replace_name_in_tables(session_info, *stmt, use_hash_, table_id, to_db_name, to_table_name))) { LOG_WARN("failed to replace in use_hash_", K(ret)); } else if (OB_FAIL(replace_name_in_tables(session_info, *stmt, no_use_hash_, table_id, to_db_name, to_table_name))) { LOG_WARN("failed to replace in no_use_hash_", K(ret)); } else if (OB_FAIL(replace_name_in_tables(session_info, *stmt, use_nl_, table_id, to_db_name, to_table_name))) { LOG_WARN("failed to replace in use_nl_", K(ret)); } else if (OB_FAIL(replace_name_in_tables(session_info, *stmt, no_use_nl_, table_id, to_db_name, to_table_name))) { LOG_WARN("failed to replace in no use_nl_", K(ret)); } else if (OB_FAIL(replace_name_in_tables(session_info, *stmt, use_bnl_, table_id, to_db_name, to_table_name))) { LOG_WARN("failed to replace in use_bnl_", K(ret)); } else if (OB_FAIL(replace_name_in_tables(session_info, *stmt, no_use_bnl_, table_id, to_db_name, to_table_name))) { LOG_WARN("failed to replace in no use_bnl_", K(ret)); } else if (OB_FAIL( replace_name_in_tables(session_info, *stmt, px_join_filter_, table_id, to_db_name, to_table_name))) { LOG_WARN("failed to replace in px join filter", K(ret)); } else if (OB_FAIL(replace_name_in_tables( session_info, *stmt, no_px_join_filter_, table_id, to_db_name, to_table_name))) { LOG_WARN("failed to replace in no px join filter", K(ret)); } return ret; } int ObQueryCtx::distribute_hint_to_stmt() { int ret = OB_SUCCESS; if (OB_FAIL(distribute_index_hint())) { LOG_WARN("Failed to distribute index hint", K(ret)); } else if (OB_FAIL(distribute_pq_hint())) { LOG_WARN("Failed to distribute pq hint", K(ret)); } else if (OB_FAIL(distribute_tables_hint(join_order_, ObStmtHint::LEADING))) { LOG_WARN("Failed to distribute leading hint", K(ret)); } else if (OB_FAIL(distribute_tables_hint(use_merge_, ObStmtHint::USE_MERGE))) { LOG_WARN("Failed to distribute use merge hint", K(ret)); } else if (OB_FAIL(distribute_tables_hint(no_use_merge_, ObStmtHint::NO_USE_MERGE))) { LOG_WARN("Failed to distribute no use merge hint", K(ret)); } else if (OB_FAIL(distribute_tables_hint(use_hash_, ObStmtHint::USE_HASH))) { LOG_WARN("Failed to distribute use hash hint", K(ret)); } else if (OB_FAIL(distribute_tables_hint(no_use_hash_, ObStmtHint::NO_USE_HASH))) { LOG_WARN("Failed to distribute no use hash hint", K(ret)); } else if (OB_FAIL(distribute_tables_hint(use_nl_, ObStmtHint::USE_NL))) { LOG_WARN("Failed to distribute use nl hint", K(ret)); } else if (OB_FAIL(distribute_tables_hint(no_use_nl_, ObStmtHint::NO_USE_NL))) { LOG_WARN("Failed to distribute no use nl hint", K(ret)); } else if (OB_FAIL(distribute_tables_hint(use_bnl_, ObStmtHint::USE_BNL))) { LOG_WARN("Failed to distribute use bnl hint", K(ret)); } else if (OB_FAIL(distribute_tables_hint(no_use_bnl_, ObStmtHint::NO_USE_BNL))) { LOG_WARN("Failed to distribute no use bnl hint", K(ret)); } else if (OB_FAIL(distribute_tables_hint(use_nl_materialization_, ObStmtHint::USE_NL_MATERIALIZATION))) { LOG_WARN("Failed to distribute use material nl hint", K(ret)); } else if (OB_FAIL(distribute_tables_hint(no_use_nl_materialization_, ObStmtHint::NO_USE_NL_MATERIALIZATION))) { LOG_WARN("Failed to distribute no use material nl hint", K(ret)); } else if (OB_FAIL(distribute_tables_hint(px_join_filter_, ObStmtHint::PX_JOIN_FILTER))) { LOG_WARN("Failed to distribute leading hint", K(ret)); } else if (OB_FAIL(distribute_tables_hint(no_px_join_filter_, ObStmtHint::NO_PX_JOIN_FILTER))) { LOG_WARN("Failed to distribute leading hint", K(ret)); } else if (OB_FAIL(distribute_rewrite_hint(no_expand_, ObStmtHint::NO_EXPAND))) { LOG_WARN("Failed to distribute no expand hint", K(ret)); } else if (OB_FAIL(distribute_rewrite_hint(use_concat_, ObStmtHint::USE_CONCAT))) { LOG_WARN("Failed to distribute use concat hint", K(ret)); } else if (OB_FAIL(distribute_rewrite_hint(merge_, ObStmtHint::MERGE))) { LOG_WARN("Failed to distribute merge hint", K(ret)); } else if (OB_FAIL(distribute_rewrite_hint(no_merge_, ObStmtHint::NO_MERGE))) { LOG_WARN("Failed to distribute no merge hint", K(ret)); } else if (OB_FAIL(distribute_rewrite_hint(unnest_, ObStmtHint::UNNEST))) { LOG_WARN("Failed to distribute unnest hint", K(ret)); } else if (OB_FAIL(distribute_rewrite_hint(no_unnest_, ObStmtHint::NO_UNNEST))) { LOG_WARN("Failed to distribute no unnest hint", K(ret)); } else if (OB_FAIL(distribute_rewrite_hint(place_group_by_, ObStmtHint::PLACE_GROUPBY))) { LOG_WARN("Failed to distribute place group by hint", K(ret)); } else if (OB_FAIL(distribute_rewrite_hint(no_place_group_by_, ObStmtHint::NO_PLACE_GROUPBY))) { LOG_WARN("Failed to distribute no place group by hint", K(ret)); } else if (OB_FAIL(distribute_rewrite_hint(no_pred_deduce_, ObStmtHint::NO_PRED_DEDUCE))) { LOG_WARN("Failed to distribute no pred deduce hint", K(ret)); } else { } // do nothing. return ret; } int ObQueryCtx::distribute_index_hint() { int ret = OB_SUCCESS; if (org_indexes_.count() > 0) { ObStmt* stmt = NULL; int64_t stmt_id = OB_INVALID_STMT_ID; for (int64_t idx = 0; OB_SUCC(ret) && idx < org_indexes_.count(); ++idx) { ObQNameIndexHint& q_index_hint = org_indexes_.at(idx); if (q_index_hint.distributed_) { // been distributed. } else if (OB_FAIL(find_stmt_id(q_index_hint.qb_name_, stmt_id))) { LOG_WARN("Failed to find stmt id", K(ret)); } else if (OB_INVALID_STMT_ID != stmt_id) { if (OB_UNLIKELY(NULL == (stmt = find_stmt_by_id(stmt_id)))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Failed to find stmt", K(ret)); } else if (stmt->is_dml_stmt()) { if (OB_FAIL( static_cast(stmt)->get_stmt_hint().org_indexes_.push_back(q_index_hint.index_hint_))) { LOG_WARN("Failed to add index hint to stmt", K(ret)); } else { q_index_hint.distributed_ = true; } } else { } // do nothing } } } return ret; } int ObQueryCtx::distribute_pq_hint() { int ret = OB_SUCCESS; // pq distribute hint FOREACH_X(hint, org_pq_distributes_, OB_SUCC(ret)) { ObStmt* stmt = NULL; int64_t stmt_id = OB_INVALID_STMT_ID; if (hint->distributed_) { // already distributed } else if (OB_FAIL(find_stmt_id(hint->qb_name_, stmt_id))) { LOG_WARN("failed to find stmt id", K(ret), "qb_name", hint->qb_name_); } else if (OB_INVALID_STMT_ID != stmt_id) { if (OB_ISNULL(stmt = find_stmt_by_id(stmt_id))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("find NULL stmt", K(ret), K(stmt_id)); } else if (stmt->is_dml_stmt()) { if (OB_FAIL(static_cast(stmt)->get_stmt_hint().org_pq_distributes_.push_back(*hint))) { LOG_WARN("array push back failed", K(ret)); } else { hint->distributed_ = true; } } } } // pq map hint FOREACH_X(hint, org_pq_maps_, OB_SUCC(ret)) { ObStmt* stmt = NULL; int64_t stmt_id = OB_INVALID_STMT_ID; if (hint->distributed_) { // already distributed } else if (OB_FAIL(find_stmt_id(hint->qb_name_, stmt_id))) { LOG_WARN("failed to find stmt id", K(ret), "qb_name", hint->qb_name_); } else if (OB_INVALID_STMT_ID != stmt_id) { if (OB_ISNULL(stmt = find_stmt_by_id(stmt_id))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("find NULL stmt", K(ret), K(stmt_id)); } else if (stmt->is_dml_stmt()) { if (OB_FAIL(static_cast(stmt)->get_stmt_hint().org_pq_maps_.push_back(*hint))) { LOG_WARN("array push back failed", K(ret)); } else { hint->distributed_ = true; } } } } return ret; } int ObQueryCtx::distribute_rewrite_hint(const common::ObIArray& qb_names, ObStmtHint::RewriteHint hint) { int ret = OB_SUCCESS; ObStmt* stmt = NULL; int64_t stmt_id = OB_INVALID_STMT_ID; for (int64_t idx = 0; OB_SUCC(ret) && idx < qb_names.count(); ++idx) { if (OB_FAIL(find_stmt_id(qb_names.at(idx), stmt_id))) { LOG_WARN("Failed to find stmt id", K(ret)); } else if (OB_INVALID_STMT_ID != stmt_id) { if (OB_ISNULL(stmt = find_stmt_by_id(stmt_id))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Failed to find stmt", K(ret)); } else if (stmt->is_dml_stmt()) { ObStmtHint& stmt_hint = static_cast(stmt)->get_stmt_hint(); if (ObStmtHint::NO_EXPAND == hint) { stmt_hint.use_expand_ = ObUseRewriteHint::NO_EXPAND; } else if (ObStmtHint::USE_CONCAT == hint) { stmt_hint.use_expand_ = ObUseRewriteHint::USE_CONCAT; } else if (ObStmtHint::MERGE == hint) { stmt_hint.use_view_merge_ = ObUseRewriteHint::V_MERGE; } else if (ObStmtHint::NO_MERGE == hint) { stmt_hint.use_view_merge_ = ObUseRewriteHint::NO_V_MERGE; } else if (ObStmtHint::UNNEST == hint) { stmt_hint.use_unnest_ = ObUseRewriteHint::UNNEST; } else if (ObStmtHint::NO_UNNEST == hint) { stmt_hint.use_unnest_ = ObUseRewriteHint::NO_UNNEST; } else if (ObStmtHint::PLACE_GROUPBY == hint) { stmt_hint.use_place_groupby_ = ObUseRewriteHint::PLACE_GROUPBY; } else if (ObStmtHint::NO_PLACE_GROUPBY == hint) { stmt_hint.use_place_groupby_ = ObUseRewriteHint::NO_PLACE_GROUPBY; } else if (ObStmtHint::NO_PRED_DEDUCE == hint) { stmt_hint.use_pred_deduce_ = ObUseRewriteHint::NO_PRED_DEDUCE; } else { } // do nothing. } } } return ret; } int ObQueryCtx::distribute_tables_hint(ObIArray& tables_hint_arr, ObStmtHint::TablesHint hint) { int ret = OB_SUCCESS; if (tables_hint_arr.count() > 0) { ObStmt* stmt = NULL; int64_t stmt_id = OB_INVALID_STMT_ID; for (int64_t idx = 0; OB_SUCC(ret) && idx < tables_hint_arr.count(); ++idx) { ObTablesInHint& tables_hint = tables_hint_arr.at(idx); if (tables_hint.distributed_) { // been distributed. } else if (OB_FAIL(find_stmt_id(tables_hint.qb_name_, stmt_id))) { LOG_WARN("Failed to find stmt id", K(ret)); } else if (OB_INVALID_STMT_ID != stmt_id) { if (OB_UNLIKELY(NULL == (stmt = find_stmt_by_id(stmt_id)))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Failed to find stmt", K(ret)); } else if (stmt->is_dml_stmt()) { ObStmtHint& stmt_hint = static_cast(stmt)->get_stmt_hint(); ObIArray* p_table_hint_arr = stmt_hint.get_join_tables(hint); ObIArray>* p_join_order_pair_arr = &stmt_hint.join_order_pairs_; if (OB_ISNULL(p_table_hint_arr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Hint not known", K(ret), K(hint)); } else if (ObStmtHint::LEADING == hint && p_table_hint_arr->count() > 0 && (OB_FALSE_IT(p_table_hint_arr->reset()) || OB_FALSE_IT(p_join_order_pair_arr->reset()))) { /* prior leading hint ignored if query ctx has leading hint */ } else if (OB_FAIL(append(*p_table_hint_arr, tables_hint.tables_))) { LOG_WARN("Failed to add index hint to stmt", K(ret)); } else if (ObStmtHint::LEADING == hint && OB_FAIL(append(*p_join_order_pair_arr, tables_hint.join_order_pairs_))) { LOG_WARN("Failed to add join order hint to stmt", K(ret)); } else if (ObStmtHint::USE_HASH == hint && OB_FAIL(append(stmt_hint.use_hash_order_pairs_, tables_hint.join_order_pairs_))) { LOG_WARN("Failed to add join order hint to stmt", K(ret)); } else if (ObStmtHint::USE_MERGE == hint && OB_FAIL(append(stmt_hint.use_merge_order_pairs_, tables_hint.join_order_pairs_))) { LOG_WARN("Failed to add join order hint to stmt", K(ret)); } else if (ObStmtHint::USE_NL == hint && OB_FAIL(append(stmt_hint.use_nl_order_pairs_, tables_hint.join_order_pairs_))) { LOG_WARN("Failed to add join order hint to stmt", K(ret)); } else if (ObStmtHint::USE_BNL == hint && OB_FAIL(append(stmt_hint.use_bnl_order_pairs_, tables_hint.join_order_pairs_))) { LOG_WARN("Failed to add join order hint to stmt", K(ret)); } else if (ObStmtHint::NO_USE_HASH == hint && OB_FAIL(append(stmt_hint.no_use_hash_order_pairs_, tables_hint.join_order_pairs_))) { LOG_WARN("Failed to add join order hint to stmt", K(ret)); } else if (ObStmtHint::NO_USE_MERGE == hint && OB_FAIL(append(stmt_hint.no_use_merge_order_pairs_, tables_hint.join_order_pairs_))) { LOG_WARN("Failed to add join order hint to stmt", K(ret)); } else if (ObStmtHint::NO_USE_NL == hint && OB_FAIL(append(stmt_hint.no_use_nl_order_pairs_, tables_hint.join_order_pairs_))) { LOG_WARN("Failed to add join order hint to stmt", K(ret)); } else if (ObStmtHint::NO_USE_BNL == hint && OB_FAIL(append(stmt_hint.no_use_bnl_order_pairs_, tables_hint.join_order_pairs_))) { LOG_WARN("Failed to add join order hint to stmt", K(ret)); } else if (ObStmtHint::USE_NL_MATERIALIZATION == hint && OB_FAIL(append(stmt_hint.use_nl_materialization_order_pairs_, tables_hint.join_order_pairs_))) { LOG_WARN("Failed to add join order hint to stmt", K(ret)); } else if (ObStmtHint::NO_USE_NL_MATERIALIZATION == hint && OB_FAIL(append(stmt_hint.no_use_nl_materialization_order_pairs_, tables_hint.join_order_pairs_))) { LOG_WARN("Failed to add join order hint to stmt", K(ret)); } else if (ObStmtHint::PX_JOIN_FILTER == hint && OB_FAIL(append(stmt_hint.px_join_filter_order_pairs_, tables_hint.join_order_pairs_))) { LOG_WARN("Failed to add join order hint to stmt", K(ret)); } else if (ObStmtHint::NO_PX_JOIN_FILTER == hint && OB_FAIL(append(stmt_hint.no_px_join_filter_order_pairs_, tables_hint.join_order_pairs_))) { LOG_WARN("Failed to add join order hint to stmt", K(ret)); } else { tables_hint.distributed_ = true; } } else { // do nothing } } else { // do nothing } } } return ret; } int ObQueryCtx::get_stmt_name_by_id(const int64_t stmt_id, common::ObString& stmt_name) const { int ret = OB_SUCCESS; bool is_found = false; for (int64_t i = 0; OB_SUCC(ret) && !is_found && i < stmt_id_name_map_.count(); ++i) { if (stmt_id == stmt_id_name_map_.at(i).id_) { stmt_name = stmt_id_name_map_.at(i).name_; is_found = true; } } if (OB_SUCC(ret) && !is_found) { ret = OB_ENTRY_NOT_EXIST; } return ret; } int ObQueryCtx::get_stmt_org_name_by_id(const int64_t stmt_id, common::ObString& org_name) const { int ret = OB_SUCCESS; bool is_found = false; for (int64_t i = 0; OB_SUCC(ret) && !is_found && i < stmt_id_name_map_.count(); ++i) { if (stmt_id == stmt_id_name_map_.at(i).id_) { org_name = stmt_id_name_map_.at(i).origin_name_; is_found = true; } } if (OB_SUCC(ret) && !is_found) { ret = OB_ENTRY_NOT_EXIST; } return ret; } int ObQueryCtx::get_stmt_org_name(const common::ObString& stmt_name, common::ObString& org_name) const { int ret = OB_SUCCESS; bool is_found = false; for (int64_t i = 0; OB_SUCC(ret) && !is_found && i < stmt_id_name_map_.count(); ++i) { if (0 == stmt_name.case_compare(stmt_id_name_map_.at(i).name_)) { org_name = stmt_id_name_map_.at(i).origin_name_; is_found = true; } } if (OB_SUCC(ret) && !is_found) { ret = OB_ENTRY_NOT_EXIST; } return ret; } int ObQueryCtx::print_qb_name_hint(planText& plan_text) const { int ret = OB_SUCCESS; char* buf = plan_text.buf; int64_t& buf_len = plan_text.buf_len; int64_t& pos = plan_text.pos; bool is_oneline = plan_text.is_oneline_; OutlineType outline_type = plan_text.outline_type_; ObString qb_name; if (USED_HINT == outline_type) { for (int64_t i = 0; OB_SUCC(ret) && i < valid_qb_name_stmt_ids_.count(); ++i) { uint64_t cur_stmt_id = valid_qb_name_stmt_ids_.at(i); qb_name.reset(); if (OB_FAIL(get_stmt_name_by_id(cur_stmt_id, qb_name))) { LOG_WARN("fail to get stmt name", K(ret), K(cur_stmt_id)); } else if (!is_oneline && OB_FAIL(BUF_PRINTF("\n"))) { } else if (OB_FAIL(BUF_PRINTF(ObStmtHint::get_outline_indent(is_oneline)))) { } else if (OB_FAIL(BUF_PRINTF(ObStmtHint::QB_NAME_HINT))) { } else if (OB_FAIL(BUF_PRINTF("(%.*s)", qb_name.length(), qb_name.ptr()))) { } else { /*do nothing*/ } } } return ret; } bool ObQueryCtx::is_cross_tenant_query(uint64_t effective_tenant_id) const { bool bret = false; for (int64_t i = 0; !bret && i < table_partition_infos_.count(); ++i) { if (table_partition_infos_.at(i) != NULL) { uint64_t cur_tenant_id = extract_tenant_id(table_partition_infos_.at(i)->get_ref_table_id()); bret = (cur_tenant_id != effective_tenant_id); } } return bret; } int ObSqlCtx::set_partition_infos(const ObTablePartitionInfoArray& info, ObIAllocator& allocator) { int ret = OB_SUCCESS; int64_t count = info.count(); partition_infos_.reset(); if (count > 0) { partition_infos_.set_allocator(&allocator); if (OB_FAIL(partition_infos_.init(count))) { LOG_WARN("init partition info failed", K(ret), K(count)); } else { for (int64_t i = 0; i < count && OB_SUCC(ret); ++i) { if (OB_FAIL(partition_infos_.push_back(info.at(i)))) { LOG_WARN("push partition info failed", K(ret), K(count)); } } } } return ret; } int ObSqlCtx::set_acs_index_info(const ObIArray& acs_index_infos, ObIAllocator& allocator) { int ret = OB_SUCCESS; if (acs_index_infos.count() > 0) { acs_index_infos_.reset(); acs_index_infos_.set_allocator(&allocator); if (OB_FAIL(acs_index_infos_.init(acs_index_infos.count()))) { LOG_WARN("init acs index infos failed", K(ret)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < acs_index_infos.count(); i++) { if (OB_ISNULL(acs_index_infos.at(i))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret)); } else if (OB_FAIL(acs_index_infos_.push_back(acs_index_infos.at(i)))) { LOG_WARN("failed to push back acs index info", K(ret)); } else { /*do nothing*/ } } } } return ret; } int ObSqlCtx::set_related_user_var_names(const ObIArray& user_var_names, ObIAllocator& allocator) { int ret = OB_SUCCESS; if (user_var_names.count() > 0) { related_user_var_names_.reset(); related_user_var_names_.set_allocator(&allocator); if (OB_FAIL(related_user_var_names_.init(user_var_names.count()))) { LOG_WARN("failed to init related_user_var_names", K(ret)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < user_var_names.count(); i++) { if (OB_FAIL(related_user_var_names_.push_back(user_var_names.at(i)))) { LOG_WARN("failed to push back user var names", K(ret)); } } } } if (OB_FAIL(ret)) { related_user_var_names_.reset(); } return ret; } int ObSqlCtx::set_location_constraints(const ObLocationConstraintContext& location_constraint, ObIAllocator& allocator) { int ret = OB_SUCCESS; base_constraints_.reset(); strict_constraints_.reset(); non_strict_constraints_.reset(); const ObIArray& base_constraints = location_constraint.base_table_constraints_; const ObIArray& strict_constraints = location_constraint.strict_constraints_; const ObIArray& non_strict_constraints = location_constraint.non_strict_constraints_; if (base_constraints.count() > 0) { base_constraints_.set_allocator(&allocator); if (OB_FAIL(base_constraints_.init(base_constraints.count()))) { LOG_WARN("init base constraints failed", K(ret)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < base_constraints.count(); i++) { if (OB_FAIL(base_constraints_.push_back(base_constraints.at(i)))) { LOG_WARN("failed to push back base constraint", K(ret)); } else { // sharding_info_ is only used in the plan generation phase base_constraints_.at(i).sharding_info_ = NULL; } } LOG_DEBUG("set base constraints", K(base_constraints.count())); } } if (OB_SUCC(ret) && strict_constraints.count() > 0) { strict_constraints_.set_allocator(&allocator); if (OB_FAIL(strict_constraints_.init(strict_constraints.count()))) { LOG_WARN("init strict constraints failed", K(ret)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < strict_constraints.count(); i++) { if (OB_FAIL(strict_constraints_.push_back(strict_constraints.at(i)))) { LOG_WARN("failed to push back location constraint", K(ret)); } } LOG_DEBUG("set strict constraints", K(strict_constraints.count())); } } if (OB_SUCC(ret) && non_strict_constraints.count() > 0) { non_strict_constraints_.set_allocator(&allocator); if (OB_FAIL(non_strict_constraints_.init(non_strict_constraints.count()))) { LOG_WARN("init non strict constraints failed", K(ret)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < non_strict_constraints.count(); i++) { if (OB_FAIL(non_strict_constraints_.push_back(non_strict_constraints.at(i)))) { LOG_WARN("failed to push back location constraint", K(ret)); } } LOG_DEBUG("set non strict constraints", K(non_strict_constraints.count())); } } return ret; } int ObSqlCtx::set_multi_stmt_rowkey_pos( const common::ObIArray& multi_stmt_rowkey_pos, common::ObIAllocator& alloctor) { int ret = OB_SUCCESS; if (!multi_stmt_rowkey_pos.empty()) { multi_stmt_rowkey_pos_.set_allocator(&alloctor); if (OB_FAIL(multi_stmt_rowkey_pos_.init(multi_stmt_rowkey_pos.count()))) { LOG_WARN("failed to init rowkey count", K(ret)); } else if (OB_FAIL(append(multi_stmt_rowkey_pos_, multi_stmt_rowkey_pos))) { LOG_WARN("failed to append multi stmt rowkey pos", K(ret)); } else { /*do nothing*/ } } return ret; } int ObQueryCtx::add_tracing_hint(ObIArray& tracing_ids) { int ret = OB_SUCCESS; bool find = false; ARRAY_FOREACH(tracing_ids, idx) { find = false; ARRAY_FOREACH(monitoring_ids_, n) { if (tracing_ids.at(idx) == monitoring_ids_.at(n).id_) { monitoring_ids_.at(n).flags_ = monitoring_ids_.at(n).flags_ & OB_MONITOR_TRACING; find = true; } } if (!find) { ObMonitorHint hint; hint.id_ = tracing_ids.at(idx); hint.flags_ = hint.flags_ | OB_MONITOR_TRACING; if (OB_FAIL(monitoring_ids_.push_back(hint))) { LOG_WARN("Failed to push back tracing", K(ret)); } } } LOG_DEBUG("add tracing hint", K(monitoring_ids_)); return ret; } int ObQueryCtx::add_stat_hint(ObIArray& stat_ids) { int ret = OB_SUCCESS; bool find = false; ARRAY_FOREACH(stat_ids, idx) { find = false; ARRAY_FOREACH(monitoring_ids_, n) { if (stat_ids.at(idx) == monitoring_ids_.at(n).id_) { monitoring_ids_.at(n).flags_ = monitoring_ids_.at(n).flags_ | OB_MONITOR_STAT; find = true; } } if (!find) { ObMonitorHint hint; hint.id_ = stat_ids.at(idx); hint.flags_ = hint.flags_ | OB_MONITOR_STAT; if (OB_FAIL(monitoring_ids_.push_back(hint))) { LOG_WARN("Failed to push back stat", K(ret)); } } } LOG_DEBUG("add stat hint", K(monitoring_ids_)); return ret; } int ObQueryCtx::add_pq_map_hint(common::ObString& qb_name, ObOrgPQMapHint& pq_map_hint) { int ret = OB_SUCCESS; ObQBNamePQMapHint hint(qb_name, pq_map_hint); if (OB_FAIL(org_pq_maps_.push_back(hint))) { LOG_WARN("fail to push back pq map", K(ret), K(hint)); } return ret; } int ObQueryCtx::add_temp_table(ObSqlTempTableInfo* temp_table_info) { int ret = OB_SUCCESS; if (OB_ISNULL(temp_table_info)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(temp_table_info), K(ret)); } else if (OB_FAIL(temp_table_infos_.push_back(temp_table_info))) { LOG_WARN("failed to push back temp table info", K(ret)); } else { /*do nothing*/ } return ret; } int ObQueryCtx::get_temp_table_plan(const uint64_t temp_table_id, ObLogicalOperator*& temp_table_insert) { int ret = OB_SUCCESS; bool is_found = false; for (int64_t i = 0; OB_SUCC(ret) && !is_found && i < temp_table_infos_.count(); i++) { if (OB_ISNULL(temp_table_infos_.at(i))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret)); } else if (temp_table_infos_.at(i)->ref_table_id_ == temp_table_id) { temp_table_insert = temp_table_infos_.at(i)->table_plan_; is_found = true; } else { /*do nothing.*/ } } return ret; } } // namespace sql } // namespace oceanbase