Files
oceanbase/src/share/ob_virtual_table_iterator.cpp
2024-02-06 14:49:36 +00:00

573 lines
23 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 COMMON
#include "share/ob_virtual_table_iterator.h"
#include "share/schema/ob_schema_getter_guard.h"
#include "share/config/ob_server_config.h"
#include "share/object/ob_obj_cast.h"
#include "common/rowkey/ob_rowkey_info.h"
#include "share/inner_table/ob_inner_table_schema.h"
#include "sql/engine/ob_operator.h"
#include "sql/engine/basic/ob_pushdown_filter.h"
#include "sql/engine/expr/ob_expr_column_conv.h"
#include "sql/session/ob_sql_session_info.h"
#include "sql/das/ob_das_location_router.h"
#include "sql/engine/basic/ob_pushdown_filter.h"
#include "sql/engine/expr/ob_expr_lob_utils.h"
#include "deps/oblib/src/lib/alloc/memory_sanity.h"
using namespace oceanbase::common;
using namespace oceanbase::share;
using namespace oceanbase::sql;
using namespace oceanbase::share::schema;
namespace oceanbase
{
namespace common
{
void ObVirtualTableIterator::reset()
{
output_column_ids_.reset();
reserved_column_cnt_ = 0;
schema_guard_ = NULL;
table_schema_ = NULL;
index_schema_ = NULL;
//Since ObObj's destructor does not do meaningful operations, in order to save performance, ObObj's destructor call is omitted, and the cells_memory is directly released.
if (OB_LIKELY(NULL != allocator_ && NULL != cur_row_.cells_)) {
allocator_->free(cur_row_.cells_);
}
cur_row_.cells_ = NULL;
cur_row_.count_ = 0;
key_ranges_.reset();
row_calc_buf_.reset();
reset_convert_ctx();
allocator_ = NULL;
session_ = NULL;
}
void ObVirtualTableIterator::reset_convert_ctx()
{
if (OB_LIKELY(NULL != allocator_ && NULL != convert_row_.cells_)) {
allocator_->free(convert_row_.cells_);
}
saved_key_ranges_.reset();
cols_schema_.reset();
convert_row_.cells_ = NULL;
convert_row_.count_ = 0;
need_convert_ = false;
convert_alloc_.reset();
}
int ObVirtualTableIterator::free_convert_ctx()
{
int ret = OB_SUCCESS;
if (!need_convert_) {
} else if (OB_UNLIKELY(convert_row_.count_ < 0 || NULL == convert_row_.cells_)) {
ret = OB_NOT_INIT;
LOG_WARN("convert row is not init", K(ret), K(convert_row_));
} else {
if (OB_ISNULL(allocator_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("allocator is NULL", K(ret));
} else {
key_ranges_.reset();
if (OB_FAIL(key_ranges_.assign(saved_key_ranges_))) {
LOG_WARN("failed to assign key ranges", K(ret));
}
saved_key_ranges_.reset();
//Since ObObj's destructor does not do meaningful operations, in order to save performance, ObObj's destructor call is omitted, and the cells_memory is directly released.
allocator_->free(convert_row_.cells_);
convert_row_.cells_ = NULL;
convert_row_.count_ = 0;
convert_alloc_.reset();
cols_schema_.reset();
}
}
return ret;
}
int ObVirtualTableIterator::convert_key(const ObRowkey &src, ObRowkey &dst, common::ObIArray<const ObColumnSchemaV2*> &key_cols)
{
int ret = OB_SUCCESS;
if (src.get_obj_cnt() > 0) {
const ObObj *src_key_objs = src.get_obj_ptr();
void *tmp_ptr = NULL;
ObObj *new_key_obj = NULL;
tmp_ptr = allocator_->alloc(src.get_obj_cnt() * sizeof(ObObj));
if (OB_ISNULL(tmp_ptr)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("fail to alloc new obj", K(ret));
} else if (OB_ISNULL(new_key_obj = new (tmp_ptr) ObObj[src.get_obj_cnt()])) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("fail to alloc new obj", K(ret));
} else if (src.get_obj_cnt() > key_cols.count()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("keys are not match with columns", K(ret));
}
lib::CompatModeGuard g(lib::Worker::CompatMode::MYSQL);
const ObDataTypeCastParams dtc_params = ObBasicSessionInfo::create_dtc_params(session_);
ObCastCtx cast_ctx(allocator_, &dtc_params, CM_NONE, ObCharset::get_system_collation());
for (uint64_t nth_obj = 0; OB_SUCC(ret) && nth_obj < src.get_obj_cnt(); ++nth_obj) {
const ObObj &src_obj = src_key_objs[nth_obj];
if (src_obj.is_min_value()) {
new_key_obj[nth_obj].set_min_value();
} else if (src_obj.is_max_value()) {
new_key_obj[nth_obj].set_max_value();
} else if (src_obj.is_null()) {
new_key_obj[nth_obj].set_null();
} else {
if (OB_FAIL(ObObjCaster::to_type(key_cols.at(nth_obj)->get_data_type(),
cast_ctx,
src_key_objs[nth_obj],
new_key_obj[nth_obj]))) {
LOG_WARN("fail to cast obj", K(ret), K(allocator_), K(key_cols.at(nth_obj)->get_data_type()), K(src_key_objs[nth_obj]));
}
}
}//end for
if (OB_SUCC(ret)) {
dst.assign(new_key_obj, src.get_obj_cnt());
}
}
return ret;
}
// get origin type of keys in mysql mode
// first find the column name that is same as origin virtual table in mysql mode
// then find column type by column name
int ObVirtualTableIterator::get_key_cols(common::ObIArray<const ObColumnSchemaV2*> &key_cols)
{
int ret = OB_SUCCESS;
common::ObArray<uint64_t> column_ids;
key_cols.reset();
if (need_convert_ && !key_ranges_.empty()) {
if (index_schema_->get_rowkey_info().is_valid()
&& index_schema_->get_rowkey_info().get_column_ids(column_ids)) {
LOG_WARN("get key column ids failed", K(ret));
}
if (OB_SUCC(ret)) {
common::ObArray<const ObString*> column_names;
for (int64_t i = 0; OB_SUCC(ret) && i < column_ids.count(); ++i) {
const ObColumnSchemaV2 * col_schema = table_schema_->get_column_schema(column_ids.at(i));
if (OB_ISNULL(col_schema)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("column schema is null", K(ret));
} else if (OB_FAIL(column_names.push_back(&col_schema->get_column_name_str()))) {
LOG_WARN("fail to push back column name", K(ret));
}
}
if (OB_SUCC(ret) && column_ids.count() != column_names.count()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("column infos are not match ", K(ret));
}
// get origin key type by column name
if (OB_SUCC(ret)) {
const ObTableSchema *org_table_schema = NULL;
uint64_t org_table_id = get_origin_tid_by_oracle_mapping_tid(table_schema_->get_table_id());
if (OB_INVALID_ID == org_table_id) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("failed to get origin table id", K(ret), K(table_schema_->get_table_id()));
} else if (OB_FAIL(schema_guard_->get_table_schema(OB_SYS_TENANT_ID, org_table_id, org_table_schema))) {
LOG_WARN("get table schema failed", K(org_table_id), K(ret));
} else if (NULL == org_table_schema) {
ret = OB_TABLE_NOT_EXIST;
LOG_WARN("get table schema failed", K(ret));
} else {
// switch mysql mode, find column schema by column name
lib::CompatModeGuard g(lib::Worker::CompatMode::MYSQL);
for (int64_t i = 0; OB_SUCC(ret) && i < column_names.count(); ++i) {
const ObString *column_name = column_names.at(i);
const ObColumnSchemaV2 *col_schema = org_table_schema->get_column_schema(*column_name);
if (OB_ISNULL(col_schema)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("column schema is null", K(ret), K(*column_name));
} else if (OB_FAIL(key_cols.push_back(col_schema))) {
LOG_WARN("fail to push back column name", K(ret));
}
}
if (OB_SUCC(ret) && key_cols.count() != column_names.count()) {
LOG_WARN("column infos are not match ", K(ret));
}
}
}
}
}
return ret;
}
// If key objects are in oracle mode, then need to convert to obj in mysql mode
// and it's find the origin type in mysql mode
// every virtual table in oracle mode must be match with one virtual table in mysql mode
int ObVirtualTableIterator::convert_key_ranges()
{
int ret = OB_SUCCESS;
if (OB_ISNULL(table_schema_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("table schema is NULL", K(ret));
} else if (!key_ranges_.empty()) {
common::ObSEArray<common::ObNewRange, 16> tmp_range;
common::ObArray<const ObColumnSchemaV2*> key_cols;
if (OB_FAIL(get_key_cols(key_cols))) {
LOG_WARN("failed to get key types", K(ret));
} else if (key_cols.empty() && 1 == key_ranges_.count() && key_ranges_.at(0).is_whole_range()) {
ObNewRange new_range;
new_range.table_id_ = key_ranges_.at(0).table_id_;
new_range.set_whole_range();
} else {
for (int64_t i = 0; OB_SUCC(ret) && i < key_ranges_.count(); ++i) {
ObNewRange new_range;
new_range.table_id_ = key_ranges_.at(i).table_id_;
new_range.border_flag_ = key_ranges_.at(i).border_flag_;
if (OB_FAIL(convert_key(key_ranges_.at(i).start_key_, new_range.start_key_, key_cols))) {
LOG_WARN("fail to convert start key", K(ret), K(allocator_));
} else if (OB_FAIL(convert_key(key_ranges_.at(i).end_key_, new_range.end_key_, key_cols))) {
LOG_WARN("fail to convert end key", K(ret), K(allocator_));
} else if (OB_FAIL(tmp_range.push_back(new_range))) {
LOG_WARN("fail to push back new range", K(ret), K(allocator_));
}
}//end for
}
if (OB_SUCC(ret)) {
if (OB_FAIL(saved_key_ranges_.assign(key_ranges_))) {
LOG_WARN("fail to assign new range", K(ret), K(allocator_));
} else {
key_ranges_.reset();
if (OB_FAIL(key_ranges_.assign(tmp_range))) {
LOG_WARN("fail to assign new range", K(ret), K(allocator_));
}
}
}
}
return ret;
}
int ObVirtualTableIterator::init_convert_ctx()
{
int ret = OB_SUCCESS;
row_calc_buf_.set_tenant_id(table_schema_->get_tenant_id());
convert_alloc_.set_tenant_id(table_schema_->get_tenant_id());
const ObDataTypeCastParams dtc_params = ObBasicSessionInfo::create_dtc_params(session_);
ObCastCtx cast_ctx(&convert_alloc_, &dtc_params, CM_NONE, table_schema_->get_collation_type());
cast_ctx_ = cast_ctx;
if (need_convert_) {
ObObj *cells = NULL;
void *tmp_ptr = NULL;
if (OB_UNLIKELY(NULL == allocator_ || NULL == table_schema_ || NULL == session_)) {
ret = OB_NOT_INIT;
LOG_WARN("data member is not init", K(ret), K(allocator_));
} else if (OB_ISNULL(tmp_ptr = allocator_->alloc(reserved_column_cnt_ <= 0 ? 1 * sizeof(ObObj): reserved_column_cnt_ * sizeof(ObObj)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
COMMON_LOG(ERROR, "fail to alloc cells", K(ret), K(reserved_column_cnt_));
} else if (OB_ISNULL(cells = new (tmp_ptr) ObObj[reserved_column_cnt_ <= 0 ? 1 : reserved_column_cnt_])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("fail to new cell array", K(ret), K(reserved_column_cnt_));
} else {
convert_row_.cells_ = cells;
convert_row_.count_ = reserved_column_cnt_;
if (OB_FAIL(convert_key_ranges())) {
LOG_WARN("fail to convert key ranges", K(ret), K(key_ranges_), K(reserved_column_cnt_));
}
}
}
LOG_DEBUG("key ranges", K(ret), K(key_ranges_));
return ret;
}
int ObVirtualTableIterator::open()
{
int ret = OB_SUCCESS;
void *tmp_ptr = NULL;
ObObj *cells = NULL;
if (OB_UNLIKELY(NULL == allocator_)) {
ret = OB_NOT_INIT;
LOG_WARN("data member is not init", K(ret), K(allocator_));
} else if (OB_ISNULL(scan_param_)
|| (NULL != scan_param_->output_exprs_ && NULL == scan_param_->op_)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument", K(ret));
} else if (OB_ISNULL(tmp_ptr = allocator_->alloc( (reserved_column_cnt_ > 0 ? reserved_column_cnt_ : 1) * sizeof(ObObj)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
COMMON_LOG(ERROR, "fail to alloc cells", K(ret), K(reserved_column_cnt_));
} else if (OB_ISNULL(cells = new (tmp_ptr) ObObj[(reserved_column_cnt_ > 0 ? reserved_column_cnt_ : 1)])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("fail to new cell array", K(ret), K(reserved_column_cnt_));
} else {
cur_row_.cells_ = cells;
cur_row_.count_ = reserved_column_cnt_;
if (OB_FAIL(init_convert_ctx())) {
LOG_WARN("fail to init convert context", K(ret));
} else if (OB_FAIL(inner_open())) {
LOG_WARN("fail to inner open", K(ret));
}
}
return ret;
}
int ObVirtualTableIterator::get_all_columns_schema()
{
int ret = OB_SUCCESS;
for (int64_t i = 0; OB_SUCC(ret) && i < output_column_ids_.count(); ++i) {
const uint64_t column_id = output_column_ids_.at(i);
const ObColumnSchemaV2 *col_schema = table_schema_->get_column_schema(column_id);
if (OB_ISNULL(col_schema)) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("col_schema is NULL", K(ret), K(column_id));
} else if (OB_FAIL(cols_schema_.push_back(col_schema))) {
LOG_WARN("failed to push back column schema", K(ret));
}
}
return ret;
}
int ObVirtualTableIterator::convert_output_row(ObNewRow *&cur_row)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(cur_row)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("current row is NULL", K(ret));
} else if (!need_convert_) {
// don't convert
} else {
convert_alloc_.reuse();
if (cols_schema_.empty() && OB_FAIL(get_all_columns_schema())) {
LOG_WARN("failed to get columns schema", K(ret));
}
for (int64_t i = 0; OB_SUCC(ret) && i < output_column_ids_.count(); ++i) {
const uint64_t column_id = output_column_ids_.at(i);
const ObColumnSchemaV2 *col_schema = cols_schema_.at(i);
if (cur_row->get_cell(i).is_null()
|| (cur_row->get_cell(i).is_string_type() && 0 == cur_row->get_cell(i).get_data_length())
|| ob_is_empty_lob(cur_row->get_cell(i))) {
convert_row_.cells_[i].set_null();
} else if (OB_FAIL(ObObjCaster::to_type(col_schema->get_data_type(),
col_schema->get_collation_type(),
cast_ctx_,
cur_row->get_cell(i),
convert_row_.cells_[i]))) {
LOG_WARN("failed to cast obj in oracle mode", K(ret), K(column_id));
}
}
cur_row = &convert_row_;
}
return ret;
}
int ObVirtualTableIterator::get_next_row(ObNewRow *&row)
{
ACTIVE_SESSION_FLAG_SETTER_GUARD(in_storage_read);
int ret = OB_SUCCESS;
ObNewRow *cur_row = NULL;
row_calc_buf_.reuse();
if (OB_FAIL(inner_get_next_row(cur_row))) {
if (OB_UNLIKELY(OB_ITER_END != ret)) {
LOG_WARN("fail to inner get next row", K(ret), KPC(scan_param_));
}
} else if (OB_ISNULL(cur_row)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("succ to inner get next row, but row is NULL", K(ret));
} else if (OB_UNLIKELY(cur_row->count_ < output_column_ids_.count())) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("row count is less than output column count", K(ret),
K(cur_row->count_), K(output_column_ids_.count()));
} else if (cur_row->count_ > 0 &&
OB_ISNULL(cur_row->cells_)) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("cur_row->cells_ is NULL", K(ret));
} else if (OB_ISNULL(table_schema_)) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("table schema is NULL", K(ret));
} else if (OB_FAIL(convert_output_row(cur_row))) {
LOG_WARN("failed to convert row", K(ret));
}
for (int64_t i = 0; OB_SUCC(ret) && i < output_column_ids_.count(); ++i) {
const uint64_t column_id = output_column_ids_.at(i);
const ObColumnSchemaV2 *col_schema = table_schema_->get_column_schema(column_id);
if (OB_ISNULL(col_schema)) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("col_schema is NULL", K(ret), K(column_id));
} else if (OB_UNLIKELY(col_schema->get_data_type() != cur_row->cells_[i].get_type()
&& ObNullType != cur_row->cells_[i].get_type())) {
ret = OB_ERR_UNEXPECTED;
if (GCONF.in_upgrade_mode()) {
LOG_WARN("column type in this row is not expected type", K(ret), K(i),
"table_name", table_schema_->get_table_name_str(),
"column_name", col_schema->get_column_name_str(),
K(column_id), K(cur_row->cells_[i]),
K(col_schema->get_data_type()), K(output_column_ids_));
} else {
LOG_ERROR("column type in this row is not expected type", K(ret), K(i),
"table_name", table_schema_->get_table_name_str(),
"column_name", col_schema->get_column_name_str(),
K(column_id), K(cur_row->cells_[i]), K(cur_row->cells_[i].get_type()),
K(col_schema->get_data_type()), K(output_column_ids_));
}
}
if (OB_SUCC(ret)
&& is_lob_storage(col_schema->get_data_type())
&& !cur_row->cells_[i].has_lob_header()) { // cannot be json type;
ObObj &obj_convert = cur_row->cells_[i];
if (OB_FAIL(ObTextStringResult::ob_convert_obj_temporay_lob(obj_convert, row_calc_buf_))) {
LOG_WARN("fail to add lob header", KR(ret), "object", cur_row->cells_[i]);
}
}
if (OB_SUCC(ret) && ob_is_string_tc(col_schema->get_data_type())
&& (col_schema->get_data_length() < cur_row->cells_[i].get_string_len()
// do charset convert when obj meta is different from expr meta
|| (CS_TYPE_INVALID != cur_row->cells_[i].get_collation_type()
&& col_schema->get_collation_type() != cur_row->cells_[i].get_collation_type()))) {
//Check the column schema to ensure that it meets the schema definition;
//But currently, only strings that exceed the length limit are processed to prevent occupying too many performance resources and causing too much interface delay
ObObj output_obj;
ObArray<ObString> *type_infos = NULL;
const bool is_strict = false;
ObExprResType res_type;
res_type.set_accuracy(col_schema->get_accuracy());
res_type.set_collation_type(col_schema->get_collation_type());
res_type.set_type(col_schema->get_data_type());
ObCastCtx cast_ctx = cast_ctx_;
cast_ctx.cast_mode_ = cast_ctx_.cast_mode_ | CM_WARN_ON_FAIL;
if (OB_FAIL(ObExprColumnConv::convert_skip_null_check(output_obj, cur_row->cells_[i],
res_type, is_strict, cast_ctx,
type_infos))) {
LOG_WARN("fail to convert skip null check", KR(ret), "object", cur_row->cells_[i]);
} else {
cur_row->cells_[i] = output_obj;
if (OB_SUCCESS != cast_ctx.warning_) {
LOG_WARN("invalid row result, check schema", "warning_num", cast_ctx.warning_,
"object", cur_row->cells_[i], K(res_type));
}
}
}
}
if (OB_SUCC(ret)) {
row = cur_row;
}
LOG_DEBUG("check result row", K(ret), KPC(row));
return ret;
}
int ObVirtualTableIterator::get_next_row()
{
ACTIVE_SESSION_FLAG_SETTER_GUARD(in_storage_read);
int ret = OB_SUCCESS;
ObNewRow *row = NULL;
if (OB_ISNULL(scan_param_)
|| OB_ISNULL(scan_param_->output_exprs_)
|| OB_ISNULL(scan_param_->op_)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument", K(ret));
} else if (VirtualSvrPair::EMPTY_VIRTUAL_TABLE_TABLET_ID == scan_param_->tablet_id_.id()) {
row = NULL;
ret = OB_ITER_END;
} else if (OB_FAIL(get_next_row(row))) {
if (OB_ITER_END != ret) {
LOG_WARN("get next row failed", K(ret));
}
}
if (OB_FAIL(ret)) {
} else if (OB_ISNULL(row)) {
LOG_WARN("NULL row returned", K(ret));
} else if (scan_param_->output_exprs_->count() > row->count_) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("row count less than output exprs", K(ret), K(*row),
"output_exprs_cnt", scan_param_->output_exprs_->count());
} else {
for (int64_t i = 0; OB_SUCC(ret) && i < scan_param_->output_exprs_->count(); i++) {
ObExpr *expr = scan_param_->output_exprs_->at(i);
ObDatum &datum = expr->locate_datum_for_write(scan_param_->op_->get_eval_ctx());
if (OB_FAIL(datum.from_obj(row->cells_[i], expr->obj_datum_map_))) {
LOG_WARN("convert ObObj to ObDatum failed", K(ret));
} else if (is_lob_storage(row->cells_[i].get_type()) &&
OB_FAIL(ob_adjust_lob_datum(row->cells_[i], expr->obj_meta_,
expr->obj_datum_map_, *allocator_, datum))) {
LOG_WARN("adjust lob datum failed", K(ret), K(i), K(row->cells_[i].get_meta()), K(expr->obj_meta_));
} else {
SANITY_CHECK_RANGE(datum.ptr_, datum.len_);
}
}
}
return ret;
}
int ObVirtualTableIterator::close()
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(cur_row_.count_ > 0 && NULL == cur_row_.cells_)) {
ret = OB_NOT_INIT;
LOG_WARN("cur_row is not init", K(ret), K(cur_row_));
} else if (OB_FAIL(inner_close())) {
LOG_WARN("fail to execute inner close", K(ret));
} else if (OB_FAIL(free_convert_ctx())) {
LOG_WARN("fail to free convert context", K(ret));
} else {
if (OB_ISNULL(allocator_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("allocator is NULL", K(ret));
} else {
//Since ObObj's destructor does not do meaningful operations, in order to save performance, ObObj's destructor call is omitted, and the cells_memory is directly released.
if (cur_row_.cells_ != NULL) {
allocator_->free(cur_row_.cells_);
}
cur_row_.cells_ = NULL;
cur_row_.count_ = 0;
}
}
row_calc_buf_.reset();
return ret;
}
// level_str support: db_acc, table_acc
// reference: ob_expr_sys_privilege_check.cpp:calc_resultN
int ObVirtualTableIterator::check_priv(const ObString &level_str,
const ObString &db_name,
const ObString &table_name,
int64_t tenant_id,
bool &passed)
{
int ret = OB_SUCCESS;
share::schema::ObSessionPrivInfo session_priv;
CK (OB_NOT_NULL(session_) && OB_NOT_NULL(schema_guard_));
OX (session_->get_session_priv_info(session_priv));
// bool allow_show = true;
if (OB_SUCC(ret)) {
//tenant_id in table is static casted to int64_t,
//and use statis_cast<uint64_t> for retrieving(same with schema_service)
// schema拆分后,普通租户schema表的tenant_id为0,此时鉴权取session_priv.tenant_id_
if (session_priv.tenant_id_ != static_cast<uint64_t>(tenant_id)
&& OB_INVALID_TENANT_ID != tenant_id) {
//not current tenant's row
} else if (0 == level_str.case_compare("db_acc")) {
if (OB_FAIL(schema_guard_->check_db_show(session_priv, db_name, passed))) {
LOG_WARN("Check db show failed", K(ret));
}
} else if (0 == level_str.case_compare("table_acc")) {
//if (OB_FAIL(priv_mgr.check_table_show(session_priv,
if (OB_FAIL(schema_guard_->check_table_show(session_priv, db_name, table_name, passed))) {
LOG_WARN("Check table show failed", K(ret));
}
} else {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("Check priv level error", K(ret));
}
}
return ret;
}
void ObVirtualTableIterator::set_effective_tenant_id(const uint64_t tenant_id)
{
effective_tenant_id_ = tenant_id;
}
}// common
}// oceanbase