Files
oceanbase/src/sql/ob_sql_mock_schema_utils.cpp
oceanbase-admin cea7de1475 init push
2021-05-31 22:56:52 +08:00

357 lines
14 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
#include "ob_sql_mock_schema_utils.h"
#include "share/schema/ob_table_schema.h"
#include "share/schema/ob_column_schema.h"
#include "share/schema/ob_schema_utils.h"
#include "share/schema/ob_table_param.h"
#include "lib/allocator/ob_allocator.h"
#include "lib/rc/context.h"
#include "lib/string/ob_sql_string.h"
#include "lib/thread_local/ob_tsi_factory.h"
#define GET_MOCKED_TBLS(mocked_tables) \
ObSQLMockedTables* mocked_tables = GET_TSI_MULT(ObSQLMockedTables, ObSQLMockedTables::MOCKED_TABLE_IDENTIFIER); \
OB_ASSERT(NULL != mocked_tables)
namespace oceanbase {
namespace sql {
using namespace oceanbase::common;
using namespace oceanbase::share;
using namespace oceanbase::share::schema;
using namespace oceanbase::lib;
const char* const ROWID_IDX_TABLE_NAME = "__idx__rowid_index";
uint64_t ObSQLMockSchemaUtils::get_rowid_index_table_id(const uint64_t table_id)
{
return (extract_pure_id(table_id) | ObSQLMockedTables::ROWID_INDEX_MASK);
}
void ObSQLMockSchemaUtils::pop_mock_table()
{
GET_MOCKED_TBLS(mocked_tables);
mocked_tables->pop_mock_table_and_index();
}
const ObIArray<uint64_t>& ObSQLMockSchemaUtils::get_all_mocked_tables()
{
GET_MOCKED_TBLS(mocked_tables);
return mocked_tables->get_table_ids();
}
int ObSQLMockSchemaUtils::add_mock_index(const uint64_t table_id)
{
int ret = OB_SUCCESS;
GET_MOCKED_TBLS(mocked_tables);
const uint64_t mocked_rowid_idx_id = get_rowid_index_table_id(table_id);
ObSQLMockedTables::ObMockedRowIDIndexInfo mocked_idx_info(table_id, mocked_rowid_idx_id);
ret = mocked_tables->add_index(mocked_idx_info);
LOG_TRACE("add mock index", K(mocked_idx_info));
return ret;
}
int ObSQLMockSchemaUtils::add_mock_table(const uint64_t table_id)
{
int ret = OB_SUCCESS;
GET_MOCKED_TBLS(mocked_tables);
LOG_TRACE("add mock table", K(table_id));
if (OB_FAIL(mocked_tables->add_table(table_id))) {
LOG_WARN("failed to mock rowid column", K(ret));
} else if (OB_FAIL(add_mock_index(table_id))) {
LOG_WARN("failed to mock rowid index", K(ret));
}
return ret;
}
bool ObSQLMockSchemaUtils::is_mock_table(const uint64_t table_id)
{
GET_MOCKED_TBLS(mocked_tables);
bool is_found = false;
for (int i = 0; !is_found && i < mocked_tables->get_table_ids().count(); i++) {
if (table_id == mocked_tables->get_table_ids().at(i)) {
is_found = true;
}
} // for end
return is_found;
}
bool ObSQLMockSchemaUtils::is_mock_index(const uint64_t index_id, uint64_t& base_table_id)
{
GET_MOCKED_TBLS(mocked_tables);
bool is_found = false;
base_table_id = OB_INVALID_ID;
for (int i = 0; !is_found && i < mocked_tables->get_index_ids().count(); i++) {
if (index_id == mocked_tables->get_index_ids().at(i).mocked_table_id_) {
is_found = true;
base_table_id = mocked_tables->get_index_ids().at(i).org_table_id_;
}
} // for end
return is_found;
}
bool ObSQLMockSchemaUtils::is_mock_index(const uint64_t index_id)
{
uint64_t unused_base_table_id = OB_INVALID_ID;
bool ret_bool = is_mock_index(index_id, unused_base_table_id);
if (ret_bool) {
OB_ASSERT(OB_INVALID_ID != unused_base_table_id); // debug
}
return ret_bool;
}
bool ObSQLMockSchemaUtils::contain_mock_index(const uint64_t table_id)
{
bool is_contain = false;
GET_MOCKED_TBLS(mocked_tables);
for (int i = 0; !is_contain && i < mocked_tables->get_index_ids().count(); i++) {
if (table_id == mocked_tables->get_index_ids().at(i).org_table_id_) {
is_contain = true;
}
} // for end
return is_contain;
}
const char* ObSQLMockSchemaUtils::get_rowid_index_name()
{
const static char* ret_idx_name = "ROWID_INDEX";
return ret_idx_name;
}
int ObSQLMockSchemaUtils::reset_mock_table()
{
int ret = OB_SUCCESS;
GET_MOCKED_TBLS(mocked_tables);
mocked_tables->reset();
return ret;
}
uint64_t ObSQLMockSchemaUtils::get_baseid_from_rowid_index_id(const uint64_t mocked_index_id)
{
GET_MOCKED_TBLS(mocked_tables);
uint64_t real_table_id = OB_INVALID_ID;
for (int i = 0; OB_INVALID_ID == real_table_id && i < mocked_tables->get_index_ids().count(); i++) {
if (mocked_index_id == mocked_tables->get_index_ids().at(i).mocked_table_id_) {
real_table_id = mocked_tables->get_index_ids().at(i).org_table_id_;
}
} // for end;
return real_table_id;
}
int ObSQLMockSchemaUtils::prepare_mocked_schemas(const common::ObIArray<uint64_t>& mock_rowid_tables)
{
int ret = OB_SUCCESS;
// prepare mocked schemas
for (int i = 0; OB_SUCC(ret) && i < mock_rowid_tables.count(); i++) {
if (OB_FAIL(add_mock_table(mock_rowid_tables.at(i)))) {
LOG_WARN("failed to mock rowid column", K(ret));
}
} // for end
return ret;
}
ObSQLMockSchemaGuard::ObSQLMockSchemaGuard()
{
ObSQLMockSchemaUtils::reset_mock_table();
}
ObSQLMockSchemaGuard::~ObSQLMockSchemaGuard()
{
ObSQLMockSchemaUtils::reset_mock_table();
}
int ObSQLMockSchemaUtils::mock_rowid_index(
const ObTableSchema* base_table_schema, const ObTableSchema*& mocked_rowid_index_schema)
{
int ret = OB_SUCCESS;
OB_ASSERT(NULL != base_table_schema);
ObIAllocator& allocator = THIS_WORKER.get_sql_arena_allocator();
const uint64_t tenant_id = base_table_schema->get_tenant_id();
ObTableSchema rowid_idx_schema;
ObTableSchema* mocked_schema = NULL;
if (OB_ISNULL(base_table_schema)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null table schema", K(ret));
} else {
rowid_idx_schema.set_tenant_id(tenant_id);
rowid_idx_schema.set_table_id(get_rowid_index_table_id(base_table_schema->get_table_id()));
rowid_idx_schema.set_database_id(base_table_schema->get_database_id());
rowid_idx_schema.set_tablespace_id(base_table_schema->get_tablespace_id());
rowid_idx_schema.set_tablegroup_id(OB_INVALID_ID);
rowid_idx_schema.set_table_type(USER_INDEX);
rowid_idx_schema.set_index_type(INDEX_TYPE_UNIQUE_LOCAL);
rowid_idx_schema.set_index_using_type(USING_BTREE);
rowid_idx_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK);
rowid_idx_schema.set_def_type(TABLE_DEF_TYPE_USER);
rowid_idx_schema.set_rowkey_column_num(base_table_schema->get_rowkey_column_num() + 1);
rowid_idx_schema.set_index_column_num(1);
rowid_idx_schema.set_replica_num(-1);
rowid_idx_schema.set_autoinc_column_id(0);
rowid_idx_schema.set_auto_increment(0);
rowid_idx_schema.set_read_only(true);
rowid_idx_schema.set_rowkey_split_pos(0);
rowid_idx_schema.set_max_used_column_id(base_table_schema->get_max_used_column_id());
rowid_idx_schema.set_part_level(PARTITION_LEVEL_ZERO);
rowid_idx_schema.set_create_mem_version(base_table_schema->get_create_mem_version());
rowid_idx_schema.set_schema_version(base_table_schema->get_schema_version());
rowid_idx_schema.set_block_size(OB_DEFAULT_SSTABLE_BLOCK_SIZE);
rowid_idx_schema.set_progressive_merge_num(base_table_schema->get_progressive_merge_num());
rowid_idx_schema.set_table_name(ROWID_IDX_TABLE_NAME);
rowid_idx_schema.set_compress_func_name(ObString::make_string("none"));
rowid_idx_schema.set_is_use_bloomfilter(false);
rowid_idx_schema.set_collation_type(CS_TYPE_UTF8MB4_BIN);
rowid_idx_schema.set_charset_type(ObCharset::charset_type_by_coll(CS_TYPE_UTF8MB4_BIN));
rowid_idx_schema.set_data_table_id(base_table_schema->get_table_id());
rowid_idx_schema.set_index_status(INDEX_STATUS_AVAILABLE);
rowid_idx_schema.set_partition_status(PARTITION_STATUS_ACTIVE);
rowid_idx_schema.set_partition_schema_version(base_table_schema->get_partition_schema_version());
rowid_idx_schema.set_comment(ObString::make_string(""));
rowid_idx_schema.set_locality(base_table_schema->get_locality());
rowid_idx_schema.set_previous_locality(base_table_schema->get_previous_locality());
rowid_idx_schema.set_parser_name(base_table_schema->get_parser_name());
rowid_idx_schema.set_tablet_size(base_table_schema->get_tablet_size());
rowid_idx_schema.set_pctfree(base_table_schema->get_pctfree());
// TODO set rest infomation
const ObColumnSchemaV2* col_schema = NULL;
const ObRowkeyInfo& rowkey_info = base_table_schema->get_rowkey_info();
uint64_t cur_rowkey_pos = 1;
ObArray<uint64_t> rowkey_column_ids;
ObArray<ObColDesc> normal_column_descs;
if (OB_FAIL(ObSchemaUtils::alloc_schema(allocator, rowid_idx_schema, mocked_schema))) {
LOG_WARN("failed ti allocate schema", K(ret));
} else if (OB_FAIL(rowkey_info.get_column_ids(rowkey_column_ids))) {
LOG_WARN("failed to get column ids", K(ret));
} else if (OB_FAIL(base_table_schema->get_column_ids_without_rowkey(normal_column_descs))) {
LOG_WARN("failed to get all normal column descs", K(ret));
} else {
if (OB_ISNULL(col_schema = base_table_schema->get_column_schema(OB_HIDDEN_LOGICAL_ROWID_COLUMN_ID))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("got unexpected null column schema", K(ret));
} else {
ObColumnSchemaV2 tmp_column = *col_schema;
tmp_column.set_rowkey_position(cur_rowkey_pos++);
tmp_column.set_index_position(1);
tmp_column.set_table_id(mocked_schema->get_table_id());
if (OB_FAIL(mocked_schema->add_column(tmp_column))) {
LOG_WARN("failed to add column schema", K(ret));
}
}
for (int i = 0; OB_SUCC(ret) && i < rowkey_column_ids.count(); i++) {
if (OB_ISNULL(col_schema = base_table_schema->get_column_schema(rowkey_column_ids.at(i)))) {
LOG_WARN("failed to get column schema", K(ret));
} else {
ObColumnSchemaV2 tmp_column = *col_schema;
tmp_column.set_rowkey_position(cur_rowkey_pos++);
tmp_column.set_index_position(0);
tmp_column.set_table_id(mocked_schema->get_table_id());
if (OB_FAIL(mocked_schema->add_column(tmp_column))) {
LOG_WARN("failed to add column schema", K(ret));
}
}
} // for end
for (int i = 0; OB_SUCC(ret) && i < normal_column_descs.count(); i++) {
if (OB_HIDDEN_LOGICAL_ROWID_COLUMN_ID == normal_column_descs.at(i).col_id_) {
// do nothing
} else if (OB_ISNULL(col_schema = base_table_schema->get_column_schema(normal_column_descs.at(i).col_id_))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null column schema", K(ret));
} else {
ObColumnSchemaV2 tmp_column = *col_schema;
tmp_column.set_index_position(0);
tmp_column.set_table_id(mocked_schema->get_table_id());
if (OB_FAIL(mocked_schema->add_column(tmp_column))) {
LOG_WARN("failed to add column schema", K(ret));
}
}
}
}
}
if (OB_FAIL(ret)) {
if (mocked_schema != NULL) {
mocked_schema->~ObTableSchema();
allocator.free(mocked_schema);
}
} else {
mocked_rowid_index_schema = mocked_schema;
LOG_TRACE("get mocked rowid index", K(*mocked_schema));
}
return ret;
}
int ObSQLMockSchemaUtils::mock_rowid_column(share::schema::ObTableSchema& table_schema)
{
int ret = OB_SUCCESS;
bool is_rowid_exists = false;
if (NULL != table_schema.get_column_schema(OB_HIDDEN_LOGICAL_ROWID_COLUMN_NAME)) {
is_rowid_exists = true;
}
if (is_virtual_table(table_schema.get_table_id()) || share::is_mysql_mode() || table_schema.is_index_table() ||
is_rowid_exists) {
LOG_DEBUG("do not mock rowid column",
K(table_schema.get_table_name_str()),
K(share::is_mysql_mode()),
K(table_schema.is_index_table()));
} else {
ObColumnSchemaV2 rowid_schema;
const uint64_t tenant_id = table_schema.get_tenant_id();
const uint64_t table_id = extract_pure_id(table_schema.get_table_id());
const int64_t schema_version = table_schema.get_schema_version();
ObObj null_obj;
null_obj.set_null();
rowid_schema.set_tenant_id(tenant_id);
if (OB_INVALID_ID == table_id || 0 == table_id || OB_SYS_TENANT_ID == tenant_id) {
rowid_schema.set_table_id(table_id);
} else {
rowid_schema.set_table_id(combine_id(tenant_id, table_id));
}
rowid_schema.set_column_id(OB_HIDDEN_LOGICAL_ROWID_COLUMN_ID);
rowid_schema.set_rowkey_position(0);
rowid_schema.set_index_position(0);
rowid_schema.set_tbl_part_key_pos(0);
rowid_schema.set_data_type(ObURowIDType);
rowid_schema.set_data_length(OB_MAX_USER_ROW_KEY_LENGTH);
rowid_schema.set_data_precision(-1);
rowid_schema.set_zero_fill(false);
rowid_schema.set_nullable(true);
rowid_schema.set_autoincrement(false);
rowid_schema.set_is_hidden(true);
rowid_schema.set_on_update_current_timestamp(false);
rowid_schema.set_order_in_rowkey(ASC); // what this column means?
rowid_schema.set_collation_type(CS_TYPE_BINARY);
rowid_schema.set_charset_type(ObCharset::charset_type_by_coll(CS_TYPE_BINARY));
rowid_schema.set_schema_version(schema_version);
rowid_schema.set_column_name(OB_HIDDEN_LOGICAL_ROWID_COLUMN_NAME);
rowid_schema.set_comment("");
rowid_schema.set_column_flags(0);
rowid_schema.set_orig_default_value(null_obj);
rowid_schema.set_cur_default_value(null_obj);
rowid_schema.set_orig_default_value_v2(null_obj);
rowid_schema.set_cur_default_value_v2(null_obj);
if (OB_FAIL(table_schema.add_column(rowid_schema))) {
LOG_ERROR("failed to add rowid column", K(ret));
} else {
LOG_TRACE(
"mocked rowid column", K(table_schema.get_column_schema(OB_HIDDEN_LOGICAL_ROWID_COLUMN_ID)), K(table_schema));
}
}
return ret;
}
} // end namespace sql
} // end namespace oceanbase