Files
oceanbase/src/sql/ob_sql_context.cpp

1315 lines
47 KiB
C++

/**
* 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 <algorithm>
#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<int64_t, ObStmt*>(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<ObTablesInHint>& 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<ObDMLStmt*>(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<ObDMLStmt*>(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<ObDMLStmt*>(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<ObString>& 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<ObDMLStmt*>(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<ObTablesInHint>& 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<ObDMLStmt*>(stmt)->get_stmt_hint();
ObIArray<ObTableInHint>* p_table_hint_arr = stmt_hint.get_join_tables(hint);
ObIArray<std::pair<uint8_t, uint8_t>>* 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<ObAcsIndexInfo*>& 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<ObString>& 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<LocationConstraint>& base_constraints = location_constraint.base_table_constraints_;
const ObIArray<ObPwjConstraint*>& strict_constraints = location_constraint.strict_constraints_;
const ObIArray<ObPwjConstraint*>& 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<int64_t>& 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<uint64_t>& 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<uint64_t>& 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