[FEAT MERGE] patch 423 sql compatible features to 432

Co-authored-by: akaError <lzg020616@163.com>
Co-authored-by: JinmaoLi <ljm.csmaster@gmail.com>
Co-authored-by: qingzhu521 <q15000557748@gmail.com>
This commit is contained in:
yinyj17
2024-05-27 11:18:00 +00:00
committed by ob-robot
parent a718b67350
commit 5ce9ef5136
208 changed files with 11028 additions and 495 deletions

View File

@ -63,11 +63,51 @@ int ObLogForUpdate::get_plan_item_info(PlanText &plan_text,
OB_ISNULL(table = stmt->get_table_item_by_id(index_dml_info_.at(i)->table_id_))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("index dml info is null", K(ret), K(index_dml_info_.at(i)), K(table));
} else if (OB_FAIL(BUF_PRINTF("%c%.*s%c",
i == 0 ? '(' : ' ',
table->get_table_name().length(),
table->get_table_name().ptr(),
i == index_dml_info_.count() - 1 ? ')' : ','))) {
} else if (table->is_generated_table()) {
// For hierarchical query, we only lock table in right view which is mocked by transform preprocess,
// the name of right view is meaningless, hence we only print the base table name here.
if (OB_ISNULL(table->ref_query_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("ref query is NULL", K(ret));
} else if (stmt->is_hierarchical_query()) {
if (OB_ISNULL(table = table->ref_query_->get_table_item_by_id(index_dml_info_.at(i)->loc_table_id_))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("table item is NULL", K(ret));
}
} else if (table->ref_query_->is_hierarchical_query()) {
// for split hierarchical query
TableItem *base_table = NULL;
for (int j = 0; OB_SUCC(ret) && j < table->ref_query_->get_table_size(); ++j) {
TableItem *mocked_join_table = table->ref_query_->get_table_item(j);
if(OB_ISNULL(mocked_join_table)
|| OB_UNLIKELY(!mocked_join_table->is_generated_table())
|| OB_ISNULL(mocked_join_table->ref_query_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected mocked join table", K(ret), KPC(mocked_join_table));
} else {
base_table = mocked_join_table->ref_query_->get_table_item_by_id(index_dml_info_.at(i)->loc_table_id_);
if (base_table != NULL) {
break;
}
}
}
if (OB_FAIL(ret)) {
} else if (OB_ISNULL(base_table)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("base table is not find", K(ret));
} else {
table = base_table;
}
} else {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("not a hierarchical query", K(ret), KPC(stmt));
}
}
if (OB_SUCC(ret) && OB_FAIL(BUF_PRINTF("%c%.*s%c",
i == 0 ? '(' : ' ',
table->get_table_name().length(),
table->get_table_name().ptr(),
i == index_dml_info_.count() - 1 ? ')' : ','))) {
LOG_WARN("failed to print lock table name", K(ret));
}
}
@ -158,17 +198,14 @@ int ObLogForUpdate::generate_multi_part_partition_id_expr()
LOG_WARN("get unexpected null", K(get_stmt()), K(ret));
}
for (int64_t i = 0; OB_SUCC(ret) && i < index_dml_info_.count(); ++i) {
const TableItem *table_item = NULL;
ObRawExpr *part_expr = NULL;
if (OB_ISNULL(index_dml_info_.at(i)) ||
OB_ISNULL(table_item = get_stmt()->get_table_item_by_id(
index_dml_info_.at(i)->table_id_))) {
if (OB_ISNULL(index_dml_info_.at(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret), K(index_dml_info_.at(i)), K(table_item));
} else if (OB_FAIL(get_plan()->gen_calc_part_id_expr(table_item->table_id_,
table_item->ref_id_,
CALC_PARTITION_TABLET_ID,
part_expr))) {
LOG_WARN("get unexpected null", K(ret));
} else if (OB_FAIL(get_plan()->gen_calc_part_id_expr(index_dml_info_.at(i)->loc_table_id_,
index_dml_info_.at(i)->ref_table_id_,
CALC_PARTITION_TABLET_ID,
part_expr))) {
LOG_WARN("failed to gen calc part id expr", K(ret));
} else if (OB_ISNULL(part_expr)) {
ret = OB_ERR_UNEXPECTED;

View File

@ -11843,6 +11843,10 @@ int ObLogPlan::allocate_for_update_as_top(ObLogicalOperator *&top,
ObIArray<uint64_t> &sfu_table_list)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(get_stmt())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
}
for (int64_t i = 0; OB_SUCC(ret) && i < sfu_table_list.count(); ++i) {
ObSEArray<uint64_t, 1> need_alloc_list;
if (table_is_allocated_for_update(sfu_table_list.at(i))) {
@ -11861,11 +11865,21 @@ int ObLogPlan::allocate_for_update_as_top(ObLogicalOperator *&top,
ObSEArray<IndexDMLInfo*, 1> index_dml_infos;
for (int64_t j = 0; OB_SUCC(ret) && j < need_alloc_list.count(); ++j) {
IndexDMLInfo *index_dml_info = NULL;
if (OB_FAIL(get_table_for_update_info(need_alloc_list.at(j),
index_dml_info,
wait_ts,
skip_locked))) {
LOG_WARN("failed to get for update info", K(ret));
bool is_hierarchical = false;
if (OB_FAIL(is_hierarchical_for_update(is_hierarchical))) {
LOG_WARN("failed to check hierarchical query", K(ret));
} else if (is_hierarchical) {
if (OB_FAIL(get_table_for_update_info_for_hierarchical(need_alloc_list.at(j),
index_dml_infos,
wait_ts,
skip_locked))) {
LOG_WARN("failed to get table for update info for hierarchical", K(ret), KPC(get_stmt()));
}
} else if (OB_FAIL(get_table_for_update_info(need_alloc_list.at(j),
index_dml_info,
wait_ts,
skip_locked))) {
LOG_WARN("failed to get for update info", K(ret), KPC(get_stmt()));
} else if (OB_ISNULL(index_dml_info)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret), K(index_dml_info));
@ -11904,6 +11918,37 @@ int ObLogPlan::allocate_for_update_as_top(ObLogicalOperator *&top,
return ret;
}
int ObLogPlan::is_hierarchical_for_update(bool &is_hierarchical)
{
int ret = OB_SUCCESS;
is_hierarchical = false;
const TableItem *table = NULL;
const ObSelectStmt *ref_view = NULL;
if (OB_ISNULL(get_stmt())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("stmt is NULL", K(ret));
} else if (get_stmt()->is_hierarchical_query()) {
is_hierarchical = true;
} else if (get_stmt()->get_table_size() != 1) {
is_hierarchical = false;
} else if (OB_ISNULL(table = get_stmt()->get_table_item(0))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("table item is NULL", K(ret));
} else if (!table->for_update_ || !table->is_generated_table()) {
is_hierarchical = false;
} else if (OB_UNLIKELY(static_cast<const ObSelectStmt*>(get_stmt())->get_for_update_dml_infos().count() == 0)) {
// For "select * from (select c1 from t1 connect by xxx) view1 where xxx for update;"
ret = OB_ERR_FOR_UPDATE_SELECT_VIEW_CANNOT;
LOG_WARN("for update dml info is null", K(ret), KPC(static_cast<const ObSelectStmt*>(get_stmt())));
} else if (OB_ISNULL(ref_view = table->ref_query_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("ref query is NULL", K(ret));
} else if (ref_view->is_hierarchical_query()) {
is_hierarchical = true;
}
return ret;
}
int ObLogPlan::merge_same_sfu_table_list(uint64_t target_id,
int64_t begin_idx,
ObIArray<uint64_t> &src_table_list,
@ -12045,6 +12090,148 @@ int ObLogPlan::get_table_for_update_info(const uint64_t table_id,
return ret;
}
int ObLogPlan::get_table_for_update_info_for_hierarchical(const uint64_t table_id,
ObIArray<IndexDMLInfo*> &index_dml_infos,
int64_t &wait_ts,
bool &skip_locked)
{
int ret = OB_SUCCESS;
const ObSelectStmt *select_stmt = NULL;
const TableItem *table = NULL;
skip_locked = false;
wait_ts = 0;
if (OB_ISNULL(get_stmt()) ||
OB_ISNULL(table = get_stmt()->get_table_item_by_id(table_id)) ||
OB_UNLIKELY(!table->for_update_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected error", K(ret), K(get_stmt()), KPC(table));
} else if (OB_UNLIKELY(!get_stmt()->is_select_stmt())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("stmt is not a select stmt", K(ret), KPC(get_stmt()));
} else if (OB_FALSE_IT(select_stmt = static_cast<const ObSelectStmt*>(get_stmt()))) {
} else if (table->is_generated_table()) {
for (int64_t i = 0; OB_SUCC(ret) && i < select_stmt->get_for_update_dml_infos().count(); ++i) {
const ForUpdateDMLInfo *for_update_info = NULL;
IndexDMLInfo *index_dml_info = NULL;
const TableItem *base_table = NULL;
if (OB_ISNULL(for_update_info = select_stmt->get_for_update_dml_infos().at(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("for update info is null", K(ret), KPC(select_stmt));
} else if (table_id != for_update_info->table_id_) {
// do nothing
} else if (OB_ISNULL(index_dml_info = static_cast<IndexDMLInfo *>(
get_optimizer_context().get_allocator().alloc(sizeof(IndexDMLInfo))))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("failed to allocate memory for index dml info", K(ret));
} else if (OB_ISNULL(table->ref_query_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("ref query is null", K(ret), KPC(table));
} else if (OB_FAIL(check_hierarchical_for_update(table, for_update_info->base_table_id_))) {
LOG_WARN("failed to check hierarchical for update", K(ret), KPC(for_update_info));
} else {
index_dml_info = new (index_dml_info) IndexDMLInfo();
index_dml_info->table_id_ = for_update_info->table_id_;
index_dml_info->loc_table_id_ = for_update_info->base_table_id_;
index_dml_info->ref_table_id_ = for_update_info->ref_table_id_;
index_dml_info->distinct_algo_ = T_DISTINCT_NONE;
index_dml_info->rowkey_cnt_ = for_update_info->rowkey_cnt_;
index_dml_info->need_filter_null_ = for_update_info->is_nullable_;
index_dml_info->is_primary_index_ = true;
skip_locked = for_update_info->skip_locked_;
wait_ts = for_update_info->for_update_wait_us_;
for (int64_t j = 0; OB_SUCC(ret) && j < for_update_info->unique_column_ids_.count(); ++j) {
ObColumnRefRawExpr *col_expr = select_stmt->get_column_expr_by_id(for_update_info->table_id_,
for_update_info->unique_column_ids_.at(j));
if (OB_ISNULL(col_expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("column expr is null", K(ret));
} else if (OB_FAIL(index_dml_info->column_exprs_.push_back(col_expr))) {
LOG_WARN("failed to push back column expr", K(ret));
} else {
col_expr->set_explicited_reference();
}
}
if (OB_FAIL(ret)){
// do nothing
} else if (OB_SUCC(ret) && OB_FAIL(index_dml_infos.push_back(index_dml_info))) {
LOG_WARN("failed to push back", K(ret));
} else {
LOG_TRACE("Succeed to get table for update info for hierarchical", K(table_id), K(for_update_info),
KPC(index_dml_info), K(wait_ts), K(skip_locked));
}
}
}
} else if (table->is_basic_table()) {
IndexDMLInfo *index_dml_info = NULL;
if (OB_FAIL(get_table_for_update_info(table_id,
index_dml_info,
wait_ts,
skip_locked))) {
LOG_WARN("failed to get for update info", K(ret));
} else if (OB_ISNULL(index_dml_info)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret), K(index_dml_info));
} else if (OB_FAIL(index_dml_infos.push_back(index_dml_info))) {
LOG_WARN("failed to push back", K(ret));
}
} else {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected table table type", K(ret), KPC(table));
}
return ret;
}
int ObLogPlan::check_hierarchical_for_update(const TableItem *table,
uint64_t base_tid)
{
int ret = OB_SUCCESS;
TableItem *base_table = NULL;
if (OB_ISNULL(get_stmt()) || OB_ISNULL(table)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret), K(get_stmt()), K(table));
} else if (OB_UNLIKELY(!table->is_generated_table())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("table is not a generated table", K(ret), KPC(table));
} else if (OB_ISNULL(table->ref_query_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("ref query is NULL", K(ret));
} else if (get_stmt()->is_hierarchical_query()) {
base_table = table->ref_query_->get_table_item_by_id(base_tid);
} else if (table->ref_query_->is_hierarchical_query()) {
for (int i = 0; OB_SUCC(ret) && i < table->ref_query_->get_table_size(); ++i) {
TableItem *mocked_join_table = table->ref_query_->get_table_item(i);
if(OB_ISNULL(mocked_join_table)
|| OB_UNLIKELY(!mocked_join_table->is_generated_table())
|| OB_ISNULL(mocked_join_table->ref_query_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected mocked join table", K(ret), KPC(mocked_join_table));
} else {
base_table = mocked_join_table->ref_query_->get_table_item_by_id(base_tid);
if (base_table != NULL) {
break;
}
}
}
} else {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("not a hierarchical query", K(ret), KPC(get_stmt()));
}
// check base table
if (OB_FAIL(ret)) {
} else if (OB_ISNULL(base_table)) {
// base table is not in hierarchical query mocked view, maybe in the
// inner generated table which not be merged.
ret = OB_ERR_FOR_UPDATE_SELECT_VIEW_CANNOT;
LOG_WARN("base table is not in hierarchical query mocked view", K(ret), KPC(table->ref_query_), K(base_tid));
} else if (OB_UNLIKELY(!base_table->is_basic_table() || is_virtual_table(base_table->ref_id_))) {
// invalid usage
ret = OB_ERR_FOR_UPDATE_SELECT_VIEW_CANNOT;
LOG_WARN("base table is not basic table", K(ret), KPC(base_table));
}
return ret;
}
int ObLogPlan::create_for_update_plan(ObLogicalOperator *&top,
const ObIArray<IndexDMLInfo *> &index_dml_infos,
int64_t wait_ts,

View File

@ -1311,6 +1311,12 @@ public:
IndexDMLInfo *&index_dml_info,
int64_t &wait_ts,
bool &skip_locked);
int get_table_for_update_info_for_hierarchical(const uint64_t table_id,
ObIArray<IndexDMLInfo *> &index_dml_infos,
int64_t &wait_ts,
bool &skip_locked);
int is_hierarchical_for_update(bool &is_hierarchical);
int check_hierarchical_for_update(const TableItem *table, uint64_t base_tid);
int get_part_column_exprs(const uint64_t table_id,
const uint64_t ref_table_id,