Skip to content

Commit aab4a79

Browse files
LYAcccob-robot
authored andcommitted
add defensive codes for setting partition keys of hbase table
1 parent 4ec3fbd commit aab4a79

File tree

4 files changed

+139
-8
lines changed

4 files changed

+139
-8
lines changed

src/share/schema/ob_table_schema.cpp

Lines changed: 106 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7886,15 +7886,50 @@ int ObTableSchema::get_presetting_partition_keys(common::ObIArray<uint64_t> &par
78867886
ret = OB_ERR_UNEXPECTED;
78877887
LOG_WARN("invalid table type", KR(ret), KPC(this));
78887888
} else if (ori_part_func_str.empty()) {
7889-
const ObRowkeyInfo &partition_keys = is_global_index_table() ? get_index_info() : get_rowkey_info();
7890-
for (int64_t i = 0; OB_SUCC(ret) && i < partition_keys.get_size(); ++i) {
7891-
const ObRowkeyColumn *partition_column = partition_keys.get_column(i);
7892-
if (OB_ISNULL(partition_column)) {
7889+
bool is_h_t = false;
7890+
if (OB_FAIL(is_hbase_table(is_h_t))) {
7891+
LOG_WARN("failed to check if it is hbase_table", K(ret), K(*this));
7892+
} else if (!is_h_t) {
7893+
const ObRowkeyInfo &partition_keys = is_global_index_table() ? get_index_info() : get_rowkey_info();
7894+
for (int64_t i = 0; OB_SUCC(ret) && i < partition_keys.get_size(); ++i) {
7895+
const ObRowkeyColumn *partition_column = partition_keys.get_column(i);
7896+
if (OB_ISNULL(partition_column)) {
7897+
ret = OB_ERR_UNEXPECTED;
7898+
LOG_WARN("the partition key is NULL, ", KR(ret), K(i), K(partition_keys), KPC(this));
7899+
} else if (!is_shadow_column(partition_column->column_id_) &&
7900+
OB_FAIL(partition_key_ids.push_back(partition_column->column_id_))) {
7901+
LOG_WARN("failed to push back rowkey column id", KR(ret), KPC(this));
7902+
}
7903+
}
7904+
} else {
7905+
const ObRowkeyInfo &rowkey_info = get_rowkey_info();
7906+
const char* K_COLULMN = "K";
7907+
ObColumnIterByPrevNextID pre_next_id_iter(*this);
7908+
const ObColumnSchemaV2 *column_schema = NULL;
7909+
ObCompareNameWithTenantID name_cmp;
7910+
if (OB_FAIL(pre_next_id_iter.next(column_schema))) {
7911+
LOG_ERROR("pre_next_id_iter next fail", KR(ret), KPC(column_schema));
7912+
} else if (OB_ISNULL(column_schema)) {
78937913
ret = OB_ERR_UNEXPECTED;
7894-
LOG_WARN("the partition key is NULL, ", KR(ret), K(i), K(partition_keys), KPC(this));
7895-
} else if (!is_shadow_column(partition_column->column_id_) &&
7896-
OB_FAIL(partition_key_ids.push_back(partition_column->column_id_))) {
7897-
LOG_WARN("failed to push back rowkey column id", KR(ret), KPC(this));
7914+
LOG_WARN("column schema should not be null", K(ret), K(*this));
7915+
} else {
7916+
ObString col_name;
7917+
col_name.reset();
7918+
bool is_col_existed = false;
7919+
uint64_t col_id = column_schema->get_column_id();
7920+
get_column_name_by_column_id(col_id, col_name, is_col_existed);
7921+
if (!is_col_existed) {
7922+
ret = OB_ERR_UNEXPECTED;
7923+
LOG_WARN("the col should exist", K(ret), K(col_id));
7924+
} else if (OB_ISNULL(col_name.ptr())) {
7925+
ret = OB_ERR_UNEXPECTED;
7926+
LOG_WARN("col_name ptr should not be null", K(ret));
7927+
} else if (OB_UNLIKELY(0 != strcmp(col_name.ptr(), K_COLULMN))) {
7928+
ret = OB_ERR_UNEXPECTED;
7929+
LOG_WARN("the first column of a hbase table should be column K", K(ret));
7930+
} else if (OB_FAIL(partition_key_ids.push_back(col_id))) {
7931+
LOG_WARN("failed to push back", K(ret));
7932+
}
78987933
}
78997934
}
79007935
} else if (!is_user_table()) {
@@ -8763,6 +8798,69 @@ int ObTableSchema::check_rowkey_column(const common::ObIArray<uint64_t> &parent_
87638798
return ret;
87648799
}
87658800

8801+
int ObTableSchema::is_hbase_table(bool &is_h_table) const
8802+
{
8803+
int ret = OB_SUCCESS;
8804+
const int64_t HBASE_TABLE_COLUMN_COUNT = 4;
8805+
is_h_table = false;
8806+
if (get_column_count() != HBASE_TABLE_COLUMN_COUNT) {
8807+
//do nothing
8808+
} else {
8809+
const char* K_COLULMN = "K";
8810+
const char* Q_COLULMN = "Q";
8811+
const char* T_COLULMN = "T";
8812+
const char* V_COLULMN = "V";
8813+
ObSEArray<bool, HBASE_TABLE_COLUMN_COUNT> col_flags;
8814+
for (int64_t i = 0; OB_SUCC(ret) && i < HBASE_TABLE_COLUMN_COUNT; ++i) {
8815+
if (OB_FAIL(col_flags.push_back(false))) {
8816+
LOG_WARN("failed to push back into col_falgs", K(ret));
8817+
}
8818+
}
8819+
// Mark column T as bigint or not
8820+
bool is_T_column_bigint_type = false;
8821+
ObColumnIterByPrevNextID pre_next_id_iter(*this);
8822+
while (OB_SUCC(ret)) {
8823+
const ObColumnSchemaV2 *column_schema = NULL;
8824+
if (OB_FAIL(pre_next_id_iter.next(column_schema))) {
8825+
if (OB_ITER_END != ret) {
8826+
LOG_ERROR("pre_next_id_iter next fail", KR(ret), KPC(column_schema));
8827+
}
8828+
} else if (OB_ISNULL(column_schema)) {
8829+
ret = OB_ERR_UNEXPECTED;
8830+
LOG_ERROR("column_schema is null", K(ret), KPC(column_schema));
8831+
} else {
8832+
const char *column_name_ptr = column_schema->get_column_name();
8833+
if (OB_ISNULL(column_name_ptr)) {
8834+
ret = OB_ERR_UNEXPECTED;
8835+
LOG_ERROR("column_name should not be null", K(ret), K(column_name_ptr));
8836+
} else if (0 == strcmp(column_name_ptr, K_COLULMN)) {
8837+
col_flags.at(0) = true;
8838+
} else if (0 == strcmp(column_name_ptr, Q_COLULMN)) {
8839+
col_flags.at(1) = true;
8840+
} else if (0 == strcmp(column_name_ptr, T_COLULMN)) {
8841+
col_flags.at(2) = true;
8842+
/*The T column must be int type for mysql mode*/
8843+
/*Since the oralce mode hasn't officially specified the htable schema so we do a strict denfensive here*/
8844+
if (lib::is_oracle_mode()) {
8845+
is_h_table = true;
8846+
} else if (!lib::is_oracle_mode() && ObIntType == column_schema->get_data_type()) {
8847+
is_h_table = true;
8848+
}
8849+
} else if (0 == strcmp(column_name_ptr, V_COLULMN)) {
8850+
col_flags.at(3) = true;
8851+
}
8852+
}
8853+
}
8854+
if (OB_ITER_END == ret) {
8855+
ret = OB_SUCCESS;
8856+
}
8857+
for (int64_t i = 0; is_h_table && OB_SUCC(ret) && i < col_flags.count(); ++i) {
8858+
is_h_table &= col_flags.at(i);
8859+
}
8860+
}
8861+
return ret;
8862+
}
8863+
87668864

87678865
int ObTableSchema::add_simple_index_info(const ObAuxTableMetaInfo &simple_index_info)
87688866
{

src/share/schema/ob_table_schema.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,6 +1811,7 @@ class ObTableSchema : public ObSimpleTableSchemaV2
18111811

18121812
int get_fk_check_index_tid(ObSchemaGetterGuard &schema_guard, const common::ObIArray<uint64_t> &parent_column_ids, uint64_t &scan_index_tid) const;
18131813
int check_rowkey_column(const common::ObIArray<uint64_t> &parent_column_ids, bool &is_rowkey) const;
1814+
int is_hbase_table(bool &is_h_table) const;
18141815

18151816
// trigger
18161817
inline const common::ObIArray<uint64_t> &get_trigger_list() const

src/sql/resolver/ddl/ob_ddl_resolver.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5870,6 +5870,14 @@ int ObDDLResolver::resolve_part_func(ObResolverParams &params,
58705870
LOG_WARN("too may partition func fields", K(ret));
58715871
}
58725872
}
5873+
if (OB_SUCC(ret)) {
5874+
bool is_h_t = false;
5875+
if (OB_FAIL(table_schema.is_hbase_table(is_h_t))) {
5876+
LOG_WARN("failed to check is hbase table", K(ret));
5877+
} else if (is_h_t && OB_FAIL(verify_hbase_table_part_keys(partition_keys))) {
5878+
LOG_WARN("failed to verify hbase table part keys", K(ret), K(table_schema.get_partition_key_info()));
5879+
}
5880+
}
58735881
if (OB_SUCC(ret)) {
58745882
//check duplicate of PARTITION_FUNC_TYPE_RANGE_COLUMNS
58755883
/* because key range has checked as sys(c1,c1) before, so here key is no need check */
@@ -6214,6 +6222,29 @@ int ObDDLResolver::check_partition_name_duplicate(ParseNode *node, bool is_oracl
62146222
return ret;
62156223
}
62166224

6225+
int ObDDLResolver::verify_hbase_table_part_keys(const ObIArray<ObString> &part_keys)
6226+
{
6227+
int ret = OB_SUCCESS;
6228+
if (part_keys.count() != 1) {
6229+
ret = OB_NOT_SUPPORTED;
6230+
LOG_WARN("the number of partition keys of range partitioned hbase table can only be 1", K(ret), K(part_keys));
6231+
LOG_USER_ERROR(OB_NOT_SUPPORTED, "settting the number of partition keys of hbase table other than 1 is");
6232+
} else {
6233+
const ObString &col_name = part_keys.at(0);
6234+
const char* K_COLUMN = "K";
6235+
ObCompareNameWithTenantID name_cmp;
6236+
6237+
if (OB_ISNULL(col_name.ptr())) {
6238+
ret = OB_ERR_UNEXPECTED;
6239+
LOG_WARN("col_name ptr should not be null", K(ret));
6240+
} else if (OB_UNLIKELY(0 != strcmp(col_name.ptr(), K_COLUMN))) {
6241+
ret = OB_NOT_SUPPORTED;
6242+
LOG_WARN("the partition key column of the hbase table can only be K column", K(ret), K(part_keys));
6243+
LOG_USER_ERROR(OB_NOT_SUPPORTED, "settting the partition key column of the hbase other than K column is");
6244+
}
6245+
}
6246+
return ret;
6247+
}
62176248

62186249
int ObDDLResolver::resolve_collection_column(const ParseNode *type_node, ObColumnSchemaV2 &column)
62196250
{

src/sql/resolver/ddl/ob_ddl_resolver.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ class ObDDLResolver : public ObStmtResolver
407407
const share::schema::ObColumnSchemaV2 &column,
408408
common::ObObjCastParams &params, common::ObObj &def_val);
409409
int check_partition_name_duplicate(ParseNode *node, bool is_oracle_modle = false);
410+
static int verify_hbase_table_part_keys(const ObIArray<ObString> &part_keys);
410411
static int check_text_column_length_and_promote(share::schema::ObColumnSchemaV2 &column,
411412
int64_t table_id,
412413
const bool is_byte_length = false);

0 commit comments

Comments
 (0)