Fix: generate column dml scene replace/insert_up fixed
This commit is contained in:
@ -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));
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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);
|
||||||
|
|
||||||
|
|||||||
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user