patch 4.0
This commit is contained in:
@ -13,23 +13,25 @@
|
||||
#define USING_LOG_PREFIX SERVER
|
||||
|
||||
#include "ob_agent_virtual_table.h"
|
||||
#include "share/ob_i_data_access_service.h"
|
||||
#include "share/ob_i_tablet_scan.h"
|
||||
#include "share/schema/ob_schema_struct.h"
|
||||
#include "observer/ob_server_struct.h"
|
||||
#include "observer/ob_inner_sql_result.h"
|
||||
#include "lib/string/ob_sql_string.h"
|
||||
#include "observer/ob_server_struct.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace oceanbase
|
||||
{
|
||||
|
||||
using namespace common;
|
||||
using namespace share;
|
||||
|
||||
namespace observer {
|
||||
namespace observer
|
||||
{
|
||||
|
||||
// convert mysql type to oracle type, only types used in inter table schema define are supported.
|
||||
// see replace_agent_table_columns_def of generate_inner_table_schema.py.
|
||||
static int int2number(const ObObj& src, ObObj& dst, ObIAllocator& allocator)
|
||||
static int int2number(const ObObj &src, ObObj &dst, ObIAllocator &allocator)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
number::ObNumber num;
|
||||
@ -41,7 +43,7 @@ static int int2number(const ObObj& src, ObObj& dst, ObIAllocator& allocator)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int uint2number(const ObObj& src, ObObj& dst, ObIAllocator& allocator)
|
||||
static int uint2number(const ObObj &src, ObObj &dst, ObIAllocator &allocator)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
number::ObNumber num;
|
||||
@ -53,7 +55,7 @@ static int uint2number(const ObObj& src, ObObj& dst, ObIAllocator& allocator)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int double2number(const ObObj& src, ObObj& dst, ObIAllocator& allocator)
|
||||
static int double2number(const ObObj &src, ObObj &dst, ObIAllocator &allocator)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
@ -71,31 +73,31 @@ static int double2number(const ObObj& src, ObObj& dst, ObIAllocator& allocator)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int varchar2varchar(const ObObj& src, ObObj& dst, ObIAllocator&)
|
||||
static int varchar2varchar(const ObObj &src, ObObj &dst, ObIAllocator &)
|
||||
{
|
||||
if (src.val_len_ <= 0) {
|
||||
dst.set_null();
|
||||
} else {
|
||||
dst = src;
|
||||
// For oracle tenant internal tables, ensure that all collations are CS_TYPE_UTF8MB4_BIN
|
||||
//对于oracle租户内部表,从表、列到字符串类型确保所有collation为CS_TYPE_UTF8MB4_BIN
|
||||
dst.set_collation_type(ObCollationType::CS_TYPE_UTF8MB4_BIN);
|
||||
}
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
static int number2number(const ObObj& src, ObObj& dst, ObIAllocator&)
|
||||
static int number2number(const ObObj &src, ObObj &dst, ObIAllocator &)
|
||||
{
|
||||
dst = src;
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
static int longtext2longtext(const ObObj& src, ObObj& dst, ObIAllocator&)
|
||||
static int longtext2longtext(const ObObj &src, ObObj &dst, ObIAllocator &)
|
||||
{
|
||||
dst = src;
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
static int timestamp2otimestamp(const ObObj& src, ObObj& dst, ObIAllocator&)
|
||||
static int timestamp2otimestamp(const ObObj &src, ObObj &dst, ObIAllocator &)
|
||||
{
|
||||
ObOTimestampData td;
|
||||
td.time_us_ = src.get_timestamp();
|
||||
@ -104,28 +106,37 @@ static int timestamp2otimestamp(const ObObj& src, ObObj& dst, ObIAllocator&)
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
ObAgentVirtualTable::ObAgentVirtualTable() : general_tenant_id_(OB_INVALID_TENANT_ID), only_sys_data_(false)
|
||||
{}
|
||||
ObAgentVirtualTable::ObAgentVirtualTable() : general_tenant_id_(OB_INVALID_TENANT_ID)
|
||||
{
|
||||
}
|
||||
|
||||
ObAgentVirtualTable::~ObAgentVirtualTable()
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
int ObAgentVirtualTable::init(const uint64_t base_table_id, const bool sys_tenant_base_table,
|
||||
const share::schema::ObTableSchema* index_table, const ObVTableScanParam& scan_param, const bool only_sys_data)
|
||||
// if base table is in tenant space, sys_tenant_base_table = true.
|
||||
// if virtual table is sys agent table, only_sys_data = true
|
||||
int ObAgentVirtualTable::init(
|
||||
const uint64_t pure_table_id,
|
||||
const bool sys_tenant_base_table,
|
||||
const share::schema::ObTableSchema *index_table,
|
||||
const ObVTableScanParam &scan_param,
|
||||
const bool only_sys_data)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_INVALID_ID == base_table_id || OB_ISNULL(index_table) || !scan_param.ObVTableScanParam::is_valid()) {
|
||||
if (OB_INVALID_ID == pure_table_id
|
||||
|| OB_ISNULL(index_table)
|
||||
|| !scan_param.ObVTableScanParam::is_valid()) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid argument", K(ret), K(base_table_id), KP(index_table), K(scan_param));
|
||||
LOG_WARN("invalid argument", K(ret), K(pure_table_id), KP(index_table), K(scan_param));
|
||||
} else {
|
||||
only_sys_data_ = only_sys_data;
|
||||
const uint64_t base_table_ten_id =
|
||||
sys_tenant_base_table ? OB_SYS_TENANT_ID : extract_tenant_id(scan_param.pkey_.get_table_id());
|
||||
const uint64_t ten_id = only_sys_data ? OB_SYS_TENANT_ID : base_table_ten_id;
|
||||
if (OB_FAIL(ObAgentTableBase::init(combine_id(ten_id, base_table_id), index_table, scan_param))) {
|
||||
const uint64_t base_tenant_id = (sys_tenant_base_table || only_sys_data) ?
|
||||
OB_SYS_TENANT_ID : scan_param.tenant_id_;
|
||||
if (OB_FAIL(ObAgentTableBase::init(base_tenant_id, pure_table_id, index_table, scan_param))) {
|
||||
LOG_WARN("init base agent table failed", K(ret));
|
||||
} else if (OB_ALL_VIRTUAL_TENANT_PARAMETER_STAT_TID == base_table_id) {
|
||||
general_tenant_id_ = extract_tenant_id(scan_param.pkey_.get_table_id());
|
||||
} else if (OB_ALL_VIRTUAL_TENANT_PARAMETER_STAT_TID == pure_table_id) {
|
||||
general_tenant_id_ = scan_param.tenant_id_;
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,13 +153,13 @@ int ObAgentVirtualTable::do_open()
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(construct_sql(sql))) {
|
||||
LOG_WARN("construct sql failed", K(ret));
|
||||
} else if (OB_FAIL(GCTX.sql_proxy_->read(*sql_res_, extract_tenant_id(base_table_id_), sql.ptr()))) {
|
||||
LOG_WARN("execute sql failed", K(ret), K(sql));
|
||||
} else if (OB_FAIL(GCTX.sql_proxy_->read(*sql_res_, base_tenant_id_, sql.ptr()))) {
|
||||
LOG_WARN("execute sql failed", K(ret), K(base_tenant_id_), K(sql));
|
||||
} else if (OB_ISNULL(sql_res_->get_result())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("NULL sql executing result", K(ret));
|
||||
} else {
|
||||
inner_sql_res_ = static_cast<ObInnerSQLResult*>(sql_res_->get_result());
|
||||
inner_sql_res_ = static_cast<ObInnerSQLResult *>(sql_res_->get_result());
|
||||
if (general_tenant_id_ != OB_INVALID_TENANT_ID) {
|
||||
inner_sql_res_->result_set().get_session().switch_tenant(general_tenant_id_);
|
||||
}
|
||||
@ -158,8 +169,8 @@ int ObAgentVirtualTable::do_open()
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObAgentVirtualTable::set_convert_func(
|
||||
convert_func_t& func, const schema::ObColumnSchemaV2& col, const schema::ObColumnSchemaV2& base_col)
|
||||
int ObAgentVirtualTable::set_convert_func(convert_func_t &func,
|
||||
const schema::ObColumnSchemaV2 &col, const schema::ObColumnSchemaV2 &base_col)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObObjType from = base_col.get_data_type();
|
||||
@ -181,23 +192,25 @@ int ObAgentVirtualTable::set_convert_func(
|
||||
func = longtext2longtext;
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unsupported type convert", K(ret), K(from), K(to), K(col), K(base_col));
|
||||
LOG_WARN("unsupported type convert",
|
||||
K(ret), K(from), K(to), K(col), K(base_col));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObAgentVirtualTable::init_non_exist_map_item(MapItem&, const schema::ObColumnSchemaV2& col)
|
||||
int ObAgentVirtualTable::init_non_exist_map_item(
|
||||
MapItem &, const schema::ObColumnSchemaV2 &col)
|
||||
{
|
||||
int ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("base table's column not found", K(ret), K(col), K(*base_table_));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObAgentVirtualTable::add_extra_condition(common::ObSqlString& sql)
|
||||
int ObAgentVirtualTable::add_extra_condition(common::ObSqlString &sql)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
CompatModeGuard g(ObWorker::CompatMode::MYSQL);
|
||||
lib::CompatModeGuard g(lib::Worker::CompatMode::MYSQL);
|
||||
uint64_t tenant_id = OB_SYS_TENANT_ID;
|
||||
if (NULL == table_schema_) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
@ -219,10 +232,10 @@ int ObAgentVirtualTable::add_extra_condition(common::ObSqlString& sql)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObAgentVirtualTable::inner_get_next_row(common::ObNewRow*& row)
|
||||
int ObAgentVirtualTable::inner_get_next_row(common::ObNewRow *&row)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObNewRow* base_row = NULL;
|
||||
const ObNewRow *base_row = NULL;
|
||||
if (!opened_ && OB_FAIL(do_open())) {
|
||||
LOG_WARN("do open failed", K(ret));
|
||||
} else if (OB_ISNULL(inner_sql_res_) || OB_ISNULL(scan_param_)) {
|
||||
@ -235,24 +248,21 @@ int ObAgentVirtualTable::inner_get_next_row(common::ObNewRow*& row)
|
||||
} else if (OB_ISNULL(base_row = inner_sql_res_->get_row())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("NULL row", K(ret));
|
||||
} else if (OB_ISNULL(cur_row_.cells_) || cur_row_.count_ < scan_param_->column_ids_.count() ||
|
||||
base_row->get_count() < scan_param_->column_ids_.count()) {
|
||||
} else if (OB_ISNULL(cur_row_.cells_) || cur_row_.count_ < scan_param_->column_ids_.count()
|
||||
|| base_row->get_count() < scan_param_->column_ids_.count()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("count mismatch",
|
||||
K(ret),
|
||||
KP(cur_row_.cells_),
|
||||
K(cur_row_.count_),
|
||||
K(base_row->get_count()),
|
||||
K(scan_param_->column_ids_.count()));
|
||||
LOG_WARN("count mismatch", K(ret), KP(cur_row_.cells_), K(cur_row_.count_),
|
||||
K(base_row->get_count()), K(scan_param_->column_ids_.count()));
|
||||
} else {
|
||||
convert_alloc_.reuse();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < scan_param_->column_ids_.count(); i++) {
|
||||
const ObObj& input = base_row->get_cell(i);
|
||||
const ObObj &input = base_row->get_cell(i);
|
||||
if (input.is_null()) {
|
||||
cur_row_.cells_[i].set_null();
|
||||
} else if (OB_FAIL(mapping_[scan_param_->column_ids_.at(i)].convert_func_(
|
||||
input, cur_row_.cells_[i], convert_alloc_))) {
|
||||
LOG_WARN("convert obj failed", K(ret), K(input), K(mapping_[scan_param_->column_ids_.at(i)]));
|
||||
input, cur_row_.cells_[i], convert_alloc_))) {
|
||||
LOG_WARN("convert obj failed", K(ret), K(input),
|
||||
K(mapping_[scan_param_->column_ids_.at(i)]));
|
||||
}
|
||||
}
|
||||
|
||||
@ -265,13 +275,12 @@ int ObAgentVirtualTable::inner_get_next_row(common::ObNewRow*& row)
|
||||
return ret;
|
||||
}
|
||||
|
||||
// if query range is (tenant_id, cond1, cond2, ...) <= (v1, v2, v3, ...) and (tenant_id, cond1, cond2, ...) >= (v1',
|
||||
// v2', v3', ...) then if you add "and tenant_id = v" to the final condition (tenant_id, cond1, cond2, ...) <= (v1, v2,
|
||||
// v3, ...) and (tenant_id, cond1, cond2, ...) >= (v1', v2', v3', ...) and tenant_id = v the optimizer can't extract the
|
||||
// query range at this time, it can only get (tenant_id, min, min), (tenant_id, max, max) for some tables that only
|
||||
// support get operations (such as plan_cache_plan_explain), the result set is always empty so this judgment condition
|
||||
// needs to be added
|
||||
int ObAgentVirtualTable::should_add_tenant_condition(bool& need, const uint64_t tenant_id) const
|
||||
// 如果query range为 (tenant_id, cond1, cond2, ...) <= (v1, v2, v3, ...) and (tenant_id, cond1, cond2, ...) >= (v1', v2', v3', ...)
|
||||
// 那么如果在最后的条件加上 and tenant_id = v,也就是
|
||||
// (tenant_id, cond1, cond2, ...) <= (v1, v2, v3, ...) and (tenant_id, cond1, cond2, ...) >= (v1', v2', v3', ...) and tenant_id = v
|
||||
// 优化器这时候抽不出来query range,只能得到 (tenant_id, min, min), (tenant_id, max, max),
|
||||
// 对于某些只支持get操作的表(比如plan_cache_plan_explain),结果集总为空,所以需要加上这个判断条件
|
||||
int ObAgentVirtualTable::should_add_tenant_condition(bool &need, const uint64_t tenant_id) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
need = true;
|
||||
@ -280,13 +289,12 @@ int ObAgentVirtualTable::should_add_tenant_condition(bool& need, const uint64_t
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid argument", K(scan_param_), K(index_table_), K(ret));
|
||||
} else {
|
||||
const ObRangeArray& ranges = scan_param_->key_ranges_;
|
||||
const ObRowkeyInfo& info = index_table_->get_rowkey_info();
|
||||
const ObRangeArray &ranges = scan_param_->key_ranges_;
|
||||
const ObRowkeyInfo &info = index_table_->get_rowkey_info();
|
||||
if (info.get_size() <= 0) {
|
||||
LOG_DEBUG("rowkeys is empty", K(ret), K(info.get_size()));
|
||||
} else {
|
||||
FOREACH_CNT_X(r, ranges, OB_SUCC(ret))
|
||||
{
|
||||
FOREACH_CNT_X(r, ranges, OB_SUCC(ret)) {
|
||||
if (r->table_id_ != index_table_->get_table_id()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected index table id", K(*r), K(*index_table_));
|
||||
@ -300,10 +308,12 @@ int ObAgentVirtualTable::should_add_tenant_condition(bool& need, const uint64_t
|
||||
} else if (0 == mapping_.at(cid).base_col_name_.compare("`tenant_id`")) {
|
||||
// not need: rowkey start with tenant_id and all ranges' tenant_id equal to %tenant_id
|
||||
const int64_t idx = base_rowkey_offset_;
|
||||
const ObRowkey& s = r->start_key_;
|
||||
const ObRowkey& e = r->end_key_;
|
||||
if (s.get_obj_cnt() > idx && e.get_obj_cnt() > idx && s.get_obj_ptr()[idx] == e.get_obj_ptr()[idx] &&
|
||||
s.get_obj_ptr()[idx].is_number()) {
|
||||
const ObRowkey &s = r->start_key_;
|
||||
const ObRowkey &e = r->end_key_;
|
||||
if (s.get_obj_cnt() > idx
|
||||
&& e.get_obj_cnt() > idx
|
||||
&& s.get_obj_ptr()[idx] == e.get_obj_ptr()[idx]
|
||||
&& s.get_obj_ptr()[idx].is_number()) {
|
||||
number::ObNumber nmb;
|
||||
s.get_obj_ptr()[idx].get_number(nmb);
|
||||
if (nmb.compare(tenant_id) == 0) {
|
||||
@ -321,5 +331,6 @@ int ObAgentVirtualTable::should_add_tenant_condition(bool& need, const uint64_t
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // end namespace observer
|
||||
} // end namespace oceanbase
|
||||
} // end namespace observer
|
||||
} // end namespace oceanbase
|
||||
|
||||
|
||||
Reference in New Issue
Block a user