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,21 +390,68 @@ 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); | ||||||
|  |       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; | ||||||
|  |         LOG_WARN("get unexpected null", K(ret)); | ||||||
|  |       } else if (OB_FAIL(schema_guard->get_table_schema(index_info->ref_table_id_, table_schema))) { | ||||||
|  |         LOG_WARN("failed to get table schema", K(ret)); | ||||||
|  |       } else if (table_schema != NULL && FALSE_IT(is_heap_table = table_schema->is_heap_table())) { | ||||||
|  |         // do nothing. | ||||||
|  |       } else { | ||||||
|  |         // 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)) { |         if (OB_ISNULL(index_info)) { | ||||||
|           ret = OB_ERR_UNEXPECTED; |           ret = OB_ERR_UNEXPECTED; | ||||||
|           LOG_WARN("replae dml info is null", K(ret)); |           LOG_WARN("replae dml info is null", K(ret)); | ||||||
|         } else if (OB_FAIL(generate_old_calc_partid_expr(*index_info))) { |         } else if (OB_FAIL(generate_old_calc_partid_expr(*index_info))) { | ||||||
|           LOG_WARN("failed to generate calc partid expr", K(ret)); |           LOG_WARN("failed to generate calc partid expr", K(ret)); | ||||||
|       } else if (OB_FAIL(ObLogTableScan::replace_gen_column(get_plan(), |         } else if (!is_heap_table && OB_FAIL(ObLogTableScan::replace_gen_column(get_plan(), | ||||||
|                                             index_info->old_part_id_expr_, |                                             index_info->old_part_id_expr_, | ||||||
|                                             index_info->lookup_part_id_expr_))){ |                                             index_info->lookup_part_id_expr_))){ | ||||||
|           LOG_WARN("failed to replace expr", K(ret)); |           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); | ||||||
|  |       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; | ||||||
|  |         LOG_WARN("get unexpected null", K(ret)); | ||||||
|  |       } else if (OB_FAIL(schema_guard->get_table_schema(dml_info->ref_table_id_, table_schema))) { | ||||||
|  |         LOG_WARN("failed to get table schema", K(ret)); | ||||||
|  |       } else if (table_schema != NULL && FALSE_IT(is_heap_table = table_schema->is_heap_table())) { | ||||||
|  |         // do nothing. | ||||||
|  |       } else { | ||||||
|  |         // 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()); | ||||||
|         // insert on duplicate update stmt |         // insert on duplicate update stmt | ||||||
|         if (OB_ISNULL(dml_info)) { |         if (OB_ISNULL(dml_info)) { | ||||||
|           ret = OB_ERR_UNEXPECTED; |           ret = OB_ERR_UNEXPECTED; | ||||||
| @ -413,10 +460,23 @@ int ObLogInsert::generate_multi_part_partition_id_expr() | |||||||
|           LOG_WARN("fail to generate calc partid expr", K(ret)); |           LOG_WARN("fail to generate calc partid expr", K(ret)); | ||||||
|         } else if (OB_FAIL(generate_update_new_calc_partid_expr(*dml_info))) { |         } else if (OB_FAIL(generate_update_new_calc_partid_expr(*dml_info))) { | ||||||
|           LOG_WARN("failed to generate update new part id expr", K(ret)); |           LOG_WARN("failed to generate update new part id expr", K(ret)); | ||||||
|       } else if (OB_FAIL(ObLogTableScan::replace_gen_column(get_plan(), |         } else if (!is_heap_table && OB_FAIL(ObLogTableScan::replace_gen_column(get_plan(), | ||||||
|                                             dml_info->old_part_id_expr_, |                                             dml_info->old_part_id_expr_, | ||||||
|                                             dml_info->lookup_part_id_expr_))){ |                                             dml_info->lookup_part_id_expr_))){ | ||||||
|           LOG_WARN("failed to replace expr", K(ret)); |           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
	 obdev
					obdev