Skip to content

Commit 131afac

Browse files
LYAcccob-robot
authored andcommitted
fix incorrect data type of high-bound value generated by auto-split
1 parent b6b35e2 commit 131afac

4 files changed

+138
-6
lines changed

src/share/scheduler/ob_partition_auto_split_helper.cpp

+86-5
Original file line numberDiff line numberDiff line change
@@ -1306,13 +1306,13 @@ int ObAutoSplitArgBuilder::build_arg_(const uint64_t tenant_id,
13061306
arg.reset();
13071307
ObTZMapWrap tz_map_wrap;
13081308
share::schema::AlterTableSchema& alter_table_schema = arg.alter_table_schema_;
1309-
13101309
if (tenant_id == OB_INVALID_ID) {
13111310
ret = OB_ERR_UNEXPECTED;
13121311
LOG_WARN("invalid tenant_id", KR(ret), K(tenant_id));
13131312
} else if (OB_FAIL(build_alter_table_schema_(tenant_id, db_name, table_schema,
13141313
split_source_tablet_id,
13151314
ranges,
1315+
arg.tz_info_wrap_.get_time_zone_info(),
13161316
alter_table_schema))) {
13171317
LOG_WARN("fail to build alter_table_schema", KR(ret), K(tenant_id), K(db_name),
13181318
K(table_schema), K(split_source_tablet_id),
@@ -1334,7 +1334,6 @@ int ObAutoSplitArgBuilder::build_arg_(const uint64_t tenant_id,
13341334
LOG_WARN("failed to build ddl stmt str", K(ret), K(tenant_id), K(table_schema.get_table_id()), K(split_source_tablet_id));
13351335
}
13361336
}
1337-
13381337
return ret;
13391338
}
13401339

@@ -1517,6 +1516,7 @@ int ObAutoSplitArgBuilder::build_alter_table_schema_(const uint64_t tenant_id,
15171516
const share::schema::ObTableSchema &table_schema,
15181517
const ObTabletID split_source_tablet_id,
15191518
const ObArray<ObNewRange> &ranges,
1519+
const ObTimeZoneInfo *tz_info,
15201520
share::schema::AlterTableSchema &alter_table_schema)
15211521
{
15221522
int ret = OB_SUCCESS;
@@ -1548,7 +1548,7 @@ int ObAutoSplitArgBuilder::build_alter_table_schema_(const uint64_t tenant_id,
15481548
const ObRowkey& high_bound_val = ranges[i].get_end_key();
15491549

15501550
if (OB_FAIL(build_partition_(tenant_id, table_id,
1551-
split_source_tablet_id, high_bound_val,
1551+
split_source_tablet_id, high_bound_val, tz_info,
15521552
new_part))) {
15531553
LOG_WARN("fail to build partition", KR(ret), K(tenant_id), K(table_id), K(split_source_tablet_id),
15541554
K(high_bound_val), K(table_schema));
@@ -1559,6 +1559,7 @@ int ObAutoSplitArgBuilder::build_alter_table_schema_(const uint64_t tenant_id,
15591559
}
15601560
}
15611561

1562+
15621563
if (OB_FAIL(ret)) {
15631564
} else if (OB_FAIL(rootserver::ObDDLService::fill_part_name(table_schema, alter_table_schema))) {
15641565
LOG_WARN("failed to fill part name", K(ret));
@@ -1588,11 +1589,18 @@ int ObAutoSplitArgBuilder::build_alter_table_schema_(const uint64_t tenant_id,
15881589
int ObAutoSplitArgBuilder::build_partition_(const uint64_t tenant_id, const uint64_t table_id,
15891590
const ObTabletID split_source_tablet_id,
15901591
const ObRowkey &high_bound_val,
1592+
const ObTimeZoneInfo *tz_info,
15911593
share::schema::ObPartition &new_part)
15921594
{
15931595
int ret = OB_SUCCESS;
1594-
1595-
if (OB_FAIL(new_part.set_high_bound_val(high_bound_val))) {
1596+
bool need_cast = false;
1597+
ObRowkey cast_high_bound_val;
1598+
common::ObArenaAllocator cast_allocator;
1599+
if (OB_FAIL(check_and_cast_high_bound(high_bound_val, tz_info, cast_high_bound_val, need_cast, cast_allocator))) {
1600+
LOG_WARN("failed to check cast high bound", K(ret));
1601+
} else if (need_cast && OB_FAIL(new_part.set_high_bound_val(cast_high_bound_val))) {
1602+
LOG_WARN("failed to set high_bound_val", KR(ret));
1603+
} else if (!need_cast && OB_FAIL(new_part.set_high_bound_val(high_bound_val))) {
15961604
LOG_WARN("failed to set high_bound_val", KR(ret));
15971605
} else {
15981606
new_part.set_is_empty_partition_name(true);
@@ -1602,6 +1610,79 @@ int ObAutoSplitArgBuilder::build_partition_(const uint64_t tenant_id, const uint
16021610
new_part.set_partition_type(PartitionType::PARTITION_TYPE_NORMAL);
16031611
}
16041612

1613+
if (OB_NOT_NULL(cast_high_bound_val.get_obj_ptr())) {
1614+
cast_high_bound_val.destroy(cast_allocator);
1615+
}
1616+
return ret;
1617+
}
1618+
1619+
int ObAutoSplitArgBuilder::check_and_cast_high_bound(const ObRowkey &origin_high_bound_val,
1620+
const ObTimeZoneInfo *tz_info,
1621+
ObRowkey &cast_hight_bound_val,
1622+
bool &need_cast,
1623+
ObIAllocator &allocator)
1624+
{
1625+
int ret = OB_SUCCESS;
1626+
const ObObj *ori_obj_ptr = origin_high_bound_val.get_obj_ptr();
1627+
const int64_t obj_count = origin_high_bound_val.get_obj_cnt();
1628+
need_cast = false;
1629+
cast_hight_bound_val.reset();
1630+
if (OB_ISNULL(ori_obj_ptr)) {
1631+
ret = OB_ERR_UNEXPECTED;
1632+
LOG_WARN("object ptr should not be null", K(ret), K(origin_high_bound_val));
1633+
} else {
1634+
for (int64_t i = 0; OB_SUCC(ret) && !need_cast && i < obj_count; ++i) {
1635+
if (OB_FAIL(check_need_to_cast(ori_obj_ptr[i], need_cast))) {
1636+
LOG_WARN("fail to check need to cast", K(ret), K(ori_obj_ptr[i]));
1637+
}
1638+
}
1639+
if (OB_SUCC(ret) && need_cast) {
1640+
ObObj *cast_obj_ptr = nullptr;
1641+
if (OB_FAIL(origin_high_bound_val.deep_copy(cast_hight_bound_val, allocator))) {
1642+
LOG_WARN("failed to copy rowkey", K(origin_high_bound_val));
1643+
} else if (OB_ISNULL(cast_obj_ptr = cast_hight_bound_val.get_obj_ptr())) {
1644+
ret = OB_ERR_UNEXPECTED;
1645+
LOG_WARN("object ptr should not be null", K(ret), K(cast_obj_ptr));
1646+
} else {
1647+
for (int64_t i = 0; OB_SUCC(ret) && i < obj_count; ++i) {
1648+
const ObObj *o_obj_ptr = &ori_obj_ptr[i];
1649+
ObObj *c_obj_ptr = &cast_obj_ptr[i];
1650+
bool need_to_cast = false;
1651+
if (OB_ISNULL(c_obj_ptr) || OB_ISNULL(o_obj_ptr)) {
1652+
ret = OB_ERR_UNEXPECTED;
1653+
LOG_WARN("ptr should not be null", K(ret), K(c_obj_ptr), K(o_obj_ptr));
1654+
} else if (OB_FAIL(check_need_to_cast(*o_obj_ptr, need_to_cast))) {
1655+
LOG_WARN("fail to check need to cast", K(ret), K(*o_obj_ptr));
1656+
} else if (need_to_cast) {
1657+
const ObObjType expected_obj_type = ori_obj_ptr[i].is_timestamp_ltz() ? ObTimestampTZType : (ob_is_int_tc(c_obj_ptr->get_type()) ? ObIntType : ObUInt64Type);
1658+
int64_t cm_mode = CM_NONE;
1659+
ObDataTypeCastParams dtc_params;
1660+
dtc_params.tz_info_ = tz_info;
1661+
ObCastCtx cast_ctx(&allocator, &dtc_params, cm_mode, c_obj_ptr->get_meta().get_collation_type());
1662+
if (OB_FAIL(ObObjCaster::to_type(expected_obj_type, cast_ctx, *o_obj_ptr, *c_obj_ptr))) {
1663+
STORAGE_LOG(WARN, "fail to cast obj",
1664+
K(ret), K(*o_obj_ptr), K(*c_obj_ptr), K(o_obj_ptr->get_type()),
1665+
K(ob_obj_type_str(o_obj_ptr->get_type())),
1666+
K(o_obj_ptr->get_meta().get_type()), K(ob_obj_type_str(o_obj_ptr->get_meta().get_type())));
1667+
}
1668+
}
1669+
}
1670+
}
1671+
}
1672+
}
1673+
return ret;
1674+
}
1675+
1676+
int ObAutoSplitArgBuilder::check_need_to_cast(const ObObj &obj, bool &need_to_cast)
1677+
{
1678+
int ret = OB_SUCCESS;
1679+
if (OB_UNLIKELY(!obj.is_valid_type())) {
1680+
ret = OB_INVALID_ARGUMENT;
1681+
LOG_WARN("invalid type", K(ret), K(obj));
1682+
} else {
1683+
need_to_cast = (ob_is_integer_type(obj.get_type()) && (ObIntType != obj.get_type() || ObUInt64Type != obj.get_type()))
1684+
|| obj.is_timestamp_ltz();
1685+
}
16051686
return ret;
16061687
}
16071688

src/share/scheduler/ob_partition_auto_split_helper.h

+8
Original file line numberDiff line numberDiff line change
@@ -251,11 +251,19 @@ class ObAutoSplitArgBuilder final
251251
const share::schema::ObTableSchema &table_schema,
252252
const ObTabletID split_source_tablet_id,
253253
const ObArray<ObNewRange> &ranges,
254+
const ObTimeZoneInfo *tz_info,
254255
share::schema::AlterTableSchema &alter_table_schema);
255256
int build_partition_(const uint64_t tenant_id, const uint64_t table_id,
256257
const ObTabletID split_source_tablet_id,
257258
const ObRowkey &high_bound_val,
259+
const ObTimeZoneInfo *tz_info,
258260
share::schema::ObPartition &new_part);
261+
int check_and_cast_high_bound(const ObRowkey &origin_high_bound_val,
262+
const ObTimeZoneInfo *tz_info,
263+
ObRowkey &cast_hight_bound_val,
264+
bool &need_cast,
265+
ObIAllocator &allocator);
266+
int check_need_to_cast(const ObObj &obj, bool &need_to_cast);
259267
private:
260268
static const int32_t MAX_SPLIT_PARTITION_NUM = 2;
261269
};

src/storage/ddl/ob_tablet_split_task.cpp

+41-1
Original file line numberDiff line numberDiff line change
@@ -1094,8 +1094,11 @@ int ObTabletSplitWriteTask::prepare_sorted_high_bound_pair(
10941094
LOG_WARN("push back failed", K(ret), K(tablet_id), K(high_bound));
10951095
}
10961096
}
1097+
if (OB_FAIL(ret)) {
1098+
} else if (OB_FAIL(check_and_cast_high_bound(rowkey_read_info_->get_columns_desc(), tablet_bound_arr))) {
1099+
LOG_WARN("failed to check and cast high bound", K(ret), K(tablet_bound_arr), K(rowkey_read_info_->get_columns_desc()));
1100+
}
10971101
}
1098-
10991102
if (OB_SUCC(ret)) {
11001103
// check in ASC rowkey order.
11011104
for (int64_t i = 1; OB_SUCC(ret) && i < tablet_bound_arr.count(); i++) {
@@ -1359,6 +1362,43 @@ int ObTabletSplitWriteTask::process_rows_for_rewrite_task(
13591362
return ret;
13601363
}
13611364

1365+
int ObTabletSplitWriteTask::check_and_cast_high_bound(
1366+
const common::ObIArray<ObColDesc> &col_descs,
1367+
common::ObSArray<TabletBoundPair> &tablet_bound_arr)
1368+
{
1369+
int ret = OB_SUCCESS;
1370+
for (int64_t i = 0; OB_SUCC(ret) && i < tablet_bound_arr.count(); ++i) {
1371+
ObDatumRowkey &drowkey = tablet_bound_arr.at(i).second;
1372+
for (int64_t j = 0; OB_SUCC(ret) && j < drowkey.datum_cnt_; ++j) {
1373+
ObStorageDatum &storage_datum = drowkey.datums_[j];
1374+
if (j >= col_descs.count()) {
1375+
ret = OB_ERR_UNEXPECTED;
1376+
LOG_WARN("rowkey size should equal to the size of col_parameters", K(j), K(drowkey.datums_), K(col_descs));
1377+
} else {
1378+
const ObColDesc &col_desc = col_descs.at(j);
1379+
void *buf = nullptr;
1380+
if (col_desc.col_type_.is_timestamp_ltz()) {
1381+
/*need to convert the high bound from timestamp_tz to timestamp_ltz*/
1382+
if (OB_ISNULL(buf = allocator_.alloc(sizeof(ObOTimestampTinyData)))) {
1383+
ret = OB_ALLOCATE_MEMORY_FAILED;
1384+
LOG_WARN("failed to allocat memory for storage datum", K(ret));
1385+
} else {
1386+
const ObOTimestampData & ts_data = storage_datum.get_otimestamp_tz();
1387+
ObObj *timestamp_ltz_obj = new (buf) ObObj();
1388+
timestamp_ltz_obj->set_timestamp_ltz(ts_data);
1389+
storage_datum.reuse();
1390+
if (OB_FAIL(storage_datum.from_obj_enhance(*timestamp_ltz_obj))) {
1391+
LOG_WARN("failed to from obj", K(ret), K(*timestamp_ltz_obj));
1392+
}
1393+
}
1394+
}
1395+
}
1396+
}
1397+
}
1398+
return ret;
1399+
}
1400+
1401+
13621402
int ObTabletSplitWriteTask::fill_tail_column_datums(const blocksstable::ObDatumRow &scan_row)
13631403
{
13641404
int ret = OB_SUCCESS;

src/storage/ddl/ob_tablet_split_task.h

+3
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,9 @@ class ObTabletSplitWriteTask final : public share::ObITask
233233
const ObStorageSchema &clipped_storage_schema,
234234
const ObIArray<ObMacroBlockWriter *> &macro_block_writer_arr,
235235
const ObDatumRange &query_range);
236+
int check_and_cast_high_bound(
237+
const common::ObIArray<ObColDesc> &col_descs,
238+
common::ObSArray<TabletBoundPair> &bound_pairs);
236239
private:
237240
static const int64_t MAP_BUCKET_NUM = 100;
238241
bool is_inited_;

0 commit comments

Comments
 (0)