Fix: generate column dml scene replace/insert_up fixed

This commit is contained in:
obdev
2023-03-02 16:49:46 +00:00
committed by ob-robot
parent da9dd32a49
commit 5088aa012d
4 changed files with 112 additions and 24 deletions

View File

@ -587,6 +587,12 @@ int ObDmlCgService::get_table_unique_key_exprs(ObLogDelUpd &op,
// When generating an insert to generate a primary key conflict, // When generating an insert to generate a primary key conflict,
// the conflicting column information needs to be returned // the conflicting column information needs to be returned
// For a partitioned table without primary key, return hidden primary key + partition key // For a partitioned table without primary key, return hidden primary key + partition key
// The partition key is a generated column, and there is no need to replace
// it with a real generated column calculation expression here, for the following reasons:
// 1. The generated columns on the main table are not used as primary keys,
// and the generated columns on the index table are actually stored, and can be read directly
// 2. For non-primary key partition tables (generated columns are used as partition keys),
// primary table writing will not cause primary key conflicts, unless it is a bug
int ObDmlCgService::table_unique_key_for_conflict_checker(ObLogDelUpd &op, int ObDmlCgService::table_unique_key_for_conflict_checker(ObLogDelUpd &op,
const IndexDMLInfo &index_dml_info, const IndexDMLInfo &index_dml_info,
ObIArray<ObRawExpr*> &rowkey_exprs) ObIArray<ObRawExpr*> &rowkey_exprs)
@ -762,12 +768,15 @@ int ObDmlCgService::generate_conflict_checker_ctdef(ObLogInsert &op,
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
ObSEArray<ObRawExpr *, 8> rowkey_exprs; ObSEArray<ObRawExpr *, 8> rowkey_exprs;
bool is_heap_table = false;
// todo @jingfeng.jf need fix some bug of generated_column // When the partition key is a virtual generated column,
// the table with the primary key needs to be replaced,
// and the table without the primary key does not need to be replaced
if (OB_FAIL(table_unique_key_for_conflict_checker(op, index_dml_info, rowkey_exprs))) { if (OB_FAIL(table_unique_key_for_conflict_checker(op, index_dml_info, rowkey_exprs))) {
LOG_WARN("get table unique key exprs failed", K(ret), K(index_dml_info)); LOG_WARN("get table unique key exprs failed", K(ret), K(index_dml_info));
} else if (OB_FAIL(adjust_unique_key_exprs(rowkey_exprs))) { } else if (OB_FAIL(check_is_heap_table(op, index_dml_info.ref_table_id_, is_heap_table))) {
// 替换其中的生成列 LOG_WARN("check is heap table failed", K(ret));
} else if (!is_heap_table && OB_FAIL(adjust_unique_key_exprs(rowkey_exprs))) {
LOG_WARN("fail to replace generated column exprs", K(ret), K(rowkey_exprs)); LOG_WARN("fail to replace generated column exprs", K(ret), K(rowkey_exprs));
} else if (OB_FAIL(cg_.generate_rt_exprs(rowkey_exprs, conflict_checker_ctdef.data_table_rowkey_expr_))) { } else if (OB_FAIL(cg_.generate_rt_exprs(rowkey_exprs, conflict_checker_ctdef.data_table_rowkey_expr_))) {
LOG_WARN("fail to generate data_table rowkey_expr", K(ret), K(rowkey_exprs)); LOG_WARN("fail to generate data_table rowkey_expr", K(ret), K(rowkey_exprs));

View File

@ -1192,6 +1192,22 @@ int ObLogDelUpd::generate_old_calc_partid_expr(IndexDMLInfo &index_info)
return ret; return ret;
} }
// for replace and insert_up conflict scene, generate lookup_part_id_expr.
int ObLogDelUpd::generate_lookup_part_id_expr(IndexDMLInfo &index_info)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(get_plan())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("plan is null", K(ret));
} else if (OB_FAIL(get_plan()->gen_calc_part_id_expr(index_info.loc_table_id_,
index_info.ref_table_id_,
CALC_PARTITION_TABLET_ID,
index_info.lookup_part_id_expr_))) {
LOG_WARN("failed to gen calc part id expr", K(ret));
}
return ret;
}
int ObLogDelUpd::generate_insert_new_calc_partid_expr(IndexDMLInfo &index_dml_info) int ObLogDelUpd::generate_insert_new_calc_partid_expr(IndexDMLInfo &index_dml_info)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;

View File

@ -152,11 +152,13 @@ public:
bool is_update_unique_key_; bool is_update_unique_key_;
bool is_update_part_key_; bool is_update_part_key_;
DistinctType distinct_algo_; DistinctType distinct_algo_;
ObRawExpr *lookup_part_id_expr_; ObRawExpr *lookup_part_id_expr_; // for replace and insert_up conflict scene
ObRawExpr *old_part_id_expr_; ObRawExpr *old_part_id_expr_;
ObRawExpr *new_part_id_expr_; ObRawExpr *new_part_id_expr_;
ObRawExpr *old_rowid_expr_; ObRawExpr *old_rowid_expr_;
ObRawExpr *new_rowid_expr_; ObRawExpr *new_rowid_expr_;
// for generated column, the diff between column_exprs_ and column_old_values_exprs_
// is virtual generated column is replaced.
common::ObSEArray<ObRawExpr*, 64, common::ModulePageAllocator, true> column_old_values_exprs_; common::ObSEArray<ObRawExpr*, 64, common::ModulePageAllocator, true> column_old_values_exprs_;
// local index id related to current dml // local index id related to current dml
TableIDArray related_index_ids_; TableIDArray related_index_ids_;
@ -311,6 +313,7 @@ protected:
int generate_update_new_rowid_expr(IndexDMLInfo &table_dml_info); int generate_update_new_rowid_expr(IndexDMLInfo &table_dml_info);
int generate_insert_new_rowid_expr(IndexDMLInfo &table_dml_info); int generate_insert_new_rowid_expr(IndexDMLInfo &table_dml_info);
int generate_old_calc_partid_expr(IndexDMLInfo &index_info); int generate_old_calc_partid_expr(IndexDMLInfo &index_info);
int generate_lookup_part_id_expr(IndexDMLInfo &index_info);
int generate_insert_new_calc_partid_expr(IndexDMLInfo &index_dml_info); int generate_insert_new_calc_partid_expr(IndexDMLInfo &index_dml_info);
int generate_update_new_calc_partid_expr(IndexDMLInfo &index_dml_info); int generate_update_new_calc_partid_expr(IndexDMLInfo &index_dml_info);

View File

@ -390,33 +390,93 @@ int ObLogInsert::generate_multi_part_partition_id_expr()
// delete in replace only old part id expr is required // delete in replace only old part id expr is required
for (int64_t i = 0; OB_SUCC(ret) && i < get_replace_index_dml_infos().count(); ++i) { for (int64_t i = 0; OB_SUCC(ret) && i < get_replace_index_dml_infos().count(); ++i) {
IndexDMLInfo *index_info = get_replace_index_dml_infos().at(i); IndexDMLInfo *index_info = get_replace_index_dml_infos().at(i);
if (OB_ISNULL(index_info)) { ObSqlSchemaGuard *schema_guard = NULL;
const ObTableSchema *table_schema = NULL;
bool is_heap_table = false;
ObArray<ObRawExpr *> column_exprs;
if (OB_ISNULL(get_plan()) ||
OB_ISNULL(schema_guard = get_plan()->get_optimizer_context().get_sql_schema_guard())) {
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
LOG_WARN("replae dml info is null", K(ret)); LOG_WARN("get unexpected null", K(ret));
} else if (OB_FAIL(generate_old_calc_partid_expr(*index_info))) { } else if (OB_FAIL(schema_guard->get_table_schema(index_info->ref_table_id_, table_schema))) {
LOG_WARN("failed to generate calc partid expr", K(ret)); LOG_WARN("failed to get table schema", K(ret));
} else if (OB_FAIL(ObLogTableScan::replace_gen_column(get_plan(), } else if (table_schema != NULL && FALSE_IT(is_heap_table = table_schema->is_heap_table())) {
index_info->old_part_id_expr_, // do nothing.
index_info->lookup_part_id_expr_))){ } else {
LOG_WARN("failed to replace expr", K(ret)); // When lookup_part_id_expr is a virtual generated column,
// the table with the primary key needs to be replaced,
// and the table without the primary key does not need to be replaced
ObRawExprCopier copier(get_plan()->get_optimizer_context().get_expr_factory());
if (OB_ISNULL(index_info)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("replae dml info is null", K(ret));
} else if (OB_FAIL(generate_old_calc_partid_expr(*index_info))) {
LOG_WARN("failed to generate calc partid expr", K(ret));
} else if (!is_heap_table && OB_FAIL(ObLogTableScan::replace_gen_column(get_plan(),
index_info->old_part_id_expr_,
index_info->lookup_part_id_expr_))){
LOG_WARN("failed to replace expr", K(ret));
} else if (is_heap_table) {
if (OB_FAIL(generate_lookup_part_id_expr(*index_info))) {
LOG_WARN("failed to generate lookup part id expr", K(ret));
} else if (OB_FAIL(ObRawExprUtils::extract_column_exprs(
index_info->lookup_part_id_expr_, column_exprs))) {
LOG_WARN("failed to extract column exprs", K(ret));
} else if (OB_FAIL(copier.add_skipped_expr(column_exprs))) {
LOG_WARN("failed to add skipped exprs", K(ret));
} else if (OB_FAIL(copier.copy(index_info->lookup_part_id_expr_,
index_info->lookup_part_id_expr_))) {
LOG_WARN("failed to copy lookup part id expr", K(ret));
}
}
} }
} }
} else if (get_insert_up()) { } else if (get_insert_up()) {
// generate the calc_part_id_expr_ of update caluse // generate the calc_part_id_expr_ of update caluse
for (int64_t i = 0; OB_SUCC(ret) && i < get_insert_up_index_dml_infos().count(); ++i) { for (int64_t i = 0; OB_SUCC(ret) && i < get_insert_up_index_dml_infos().count(); ++i) {
IndexDMLInfo *dml_info = get_insert_up_index_dml_infos().at(i); IndexDMLInfo *dml_info = get_insert_up_index_dml_infos().at(i);
// insert on duplicate update stmt ObSqlSchemaGuard *schema_guard = NULL;
if (OB_ISNULL(dml_info)) { const ObTableSchema *table_schema = NULL;
bool is_heap_table = false;
ObArray<ObRawExpr *> column_exprs;
if (OB_ISNULL(get_plan()) ||
OB_ISNULL(schema_guard = get_plan()->get_optimizer_context().get_sql_schema_guard())) {
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
LOG_WARN("insert_up dml info is null", K(ret)); LOG_WARN("get unexpected null", K(ret));
} else if (OB_FAIL(generate_old_calc_partid_expr(*dml_info))) { } else if (OB_FAIL(schema_guard->get_table_schema(dml_info->ref_table_id_, table_schema))) {
LOG_WARN("fail to generate calc partid expr", K(ret)); LOG_WARN("failed to get table schema", K(ret));
} else if (OB_FAIL(generate_update_new_calc_partid_expr(*dml_info))) { } else if (table_schema != NULL && FALSE_IT(is_heap_table = table_schema->is_heap_table())) {
LOG_WARN("failed to generate update new part id expr", K(ret)); // do nothing.
} else if (OB_FAIL(ObLogTableScan::replace_gen_column(get_plan(), } else {
dml_info->old_part_id_expr_, // When lookup_part_id_expr is a virtual generated column,
dml_info->lookup_part_id_expr_))){ // the table with the primary key needs to be replaced,
LOG_WARN("failed to replace expr", K(ret)); // and the table without the primary key does not need to be replaced
ObRawExprCopier copier(get_plan()->get_optimizer_context().get_expr_factory());
// insert on duplicate update stmt
if (OB_ISNULL(dml_info)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("insert_up dml info is null", K(ret));
} else if (OB_FAIL(generate_old_calc_partid_expr(*dml_info))) {
LOG_WARN("fail to generate calc partid expr", K(ret));
} else if (OB_FAIL(generate_update_new_calc_partid_expr(*dml_info))) {
LOG_WARN("failed to generate update new part id expr", K(ret));
} else if (!is_heap_table && OB_FAIL(ObLogTableScan::replace_gen_column(get_plan(),
dml_info->old_part_id_expr_,
dml_info->lookup_part_id_expr_))){
LOG_WARN("failed to replace expr", K(ret));
} else if (is_heap_table) {
if (OB_FAIL(generate_lookup_part_id_expr(*dml_info))) {
LOG_WARN("failed to generate lookup part id expr", K(ret));
} else if (OB_FAIL(ObRawExprUtils::extract_column_exprs(
dml_info->lookup_part_id_expr_, column_exprs))) {
LOG_WARN("failed to extract column exprs", K(ret));
} else if (OB_FAIL(copier.add_skipped_expr(column_exprs))) {
LOG_WARN("failed to add skipped exprs", K(ret));
} else if (OB_FAIL(copier.copy(dml_info->lookup_part_id_expr_,
dml_info->lookup_part_id_expr_))) {
LOG_WARN("failed to copy lookup part id expr", K(ret));
}
}
} }
} }
} }