提交 73e34017 编写于 作者: B bf0 提交者: wangzelin.wzl

fix single partition opt bug

上级 86697041
......@@ -21,9 +21,9 @@ using namespace common;
using namespace share::schema;
namespace sql {
// for hash/key/range_func part or insert statement
int ObPartMgrAD::get_part(ObPartMgr* part_mgr, const int64_t table_id, const ObPartitionLevel part_level,
const ObPartitionFuncType part_type, const bool insert_or_replace, const int64_t p_id, const ObObj& value,
ObIArray<int64_t>& partition_ids, int64_t* part_idx)
int ObPartMgrAD::get_part(ObPartMgr *part_mgr, const int64_t table_id, const ObPartitionLevel part_level,
const ObPartitionFuncType part_type, const bool report_err_if_partition_not_exist, const int64_t p_id,
const ObObj &value, ObIArray<int64_t> &partition_ids, int64_t *part_idx)
{
int ret = common::OB_SUCCESS;
ObRowkey rowkey(const_cast<ObObj*>(&value), 1);
......@@ -31,8 +31,15 @@ int ObPartMgrAD::get_part(ObPartMgr* part_mgr, const int64_t table_id, const ObP
ObSEArray<int64_t, 1> part_ids;
if (OB_FAIL(range.build_range(table_id, rowkey))) {
LOG_WARN("Failed to build range", K(ret));
} else if (OB_FAIL(get_part(
part_mgr, table_id, part_level, part_type, insert_or_replace, p_id, range, partition_ids, part_idx))) {
} else if (OB_FAIL(get_part(part_mgr,
table_id,
part_level,
part_type,
report_err_if_partition_not_exist,
p_id,
range,
partition_ids,
part_idx))) {
LOG_WARN("Failed to get part", K(ret));
} else {
} // do nothing
......@@ -42,8 +49,8 @@ int ObPartMgrAD::get_part(ObPartMgr* part_mgr, const int64_t table_id, const ObP
int ObPartMgrAD::get_part(common::ObPartMgr* part_mgr, const int64_t table_id,
const share::schema::ObPartitionLevel part_level, const share::schema::ObPartitionFuncType part_type,
const bool insert_or_replace, const int64_t p_id, const common::ObNewRow& row,
common::ObIArray<int64_t>& partition_ids, int64_t* part_idx)
const bool report_err_if_partition_not_exist, const int64_t p_id, const common::ObNewRow &row,
common::ObIArray<int64_t> &partition_ids, int64_t *part_idx)
{
int ret = OB_SUCCESS;
ObSEArray<int64_t, 1> part_ids;
......@@ -53,7 +60,7 @@ int ObPartMgrAD::get_part(common::ObPartMgr* part_mgr, const int64_t table_id,
} else if (OB_FAIL(part_mgr->get_part(table_id, part_level, p_id, row, part_ids))) {
LOG_WARN("Failed to get part from part_mgr", K(ret));
} else if (0 == part_ids.count()) {
if (insert_or_replace) { // For Insert or replace stmt, if no partition, report error
if (report_err_if_partition_not_exist) {
ret = OB_NO_PARTITION_FOR_GIVEN_VALUE;
LOG_USER_WARN(OB_NO_PARTITION_FOR_GIVEN_VALUE);
} else if (share::schema::is_hash_like_part(part_type)) { // For other stmt
......@@ -126,8 +133,8 @@ int ObPartMgrAD::get_all_part(ObPartMgr* part_mgr, const int64_t table_id, const
int ObPartMgrAD::get_part(common::ObPartMgr* part_mgr, const int64_t table_id,
const share::schema::ObPartitionLevel part_level, const share::schema::ObPartitionFuncType part_type,
const bool insert_or_replace, const int64_t p_id, const common::ObNewRange& range,
common::ObIArray<int64_t>& partition_ids, int64_t* part_idx)
const bool report_err_if_partition_not_exist, const int64_t p_id, const common::ObNewRange &range,
common::ObIArray<int64_t> &partition_ids, int64_t *part_idx)
{
int ret = OB_SUCCESS;
ObSEArray<int64_t, 1> part_ids;
......@@ -137,7 +144,7 @@ int ObPartMgrAD::get_part(common::ObPartMgr* part_mgr, const int64_t table_id,
} else if (OB_FAIL(part_mgr->get_part(table_id, part_level, p_id, range, false, part_ids))) {
LOG_WARN("Failed to get part from part_mgr", K(ret));
} else if (0 == part_ids.count()) {
if (insert_or_replace) { // For Insert or replace stmt, if no partition, report error
if (report_err_if_partition_not_exist) {
ret = OB_NO_PARTITION_FOR_GIVEN_VALUE;
LOG_USER_WARN(OB_NO_PARTITION_FOR_GIVEN_VALUE);
} else if (PARTITION_FUNC_TYPE_RANGE != part_type && PARTITION_FUNC_TYPE_RANGE_COLUMNS != part_type &&
......
......@@ -34,15 +34,15 @@ public:
// for hash/key/range_func part or insert statement
static int get_part(common::ObPartMgr* part_mgr, const int64_t table_id,
const share::schema::ObPartitionLevel part_level, const share::schema::ObPartitionFuncType part_type,
const bool insert_or_replace, const int64_t p_id,
const common::ObObj& value, // part func result
common::ObIArray<int64_t>& partition_ids, int64_t* part_idx);
const bool report_err_if_partition_not_exist, const int64_t p_id,
const common::ObObj &value, // part func result
common::ObIArray<int64_t> &partition_ids, int64_t *part_idx);
// For range columns
static int get_part(common::ObPartMgr* part_mgr, const int64_t table_id,
const share::schema::ObPartitionLevel part_level, const share::schema::ObPartitionFuncType part_type,
const bool insert_or_replace, const int64_t p_id, const common::ObNewRow& row,
common::ObIArray<int64_t>& partition_ids, int64_t* part_idx = NULL);
const bool report_err_if_partition_not_exist, const int64_t p_id, const common::ObNewRow &row,
common::ObIArray<int64_t> &partition_ids, int64_t *part_idx = NULL);
/////////The for range range partition must only contain column. If there are multiple columns, range represents the
/// column vector in the schema//////
......@@ -58,8 +58,8 @@ private:
// Get point values range partition id
static int get_part(common::ObPartMgr* part_mgr, const int64_t table_id,
const share::schema::ObPartitionLevel part_level, const share::schema::ObPartitionFuncType part_type,
const bool insert_or_replace, const int64_t p_id, const common::ObNewRange& value,
common::ObIArray<int64_t>& partition_ids, int64_t* part_idx = NULL);
const bool report_err_if_partition_not_exist, const int64_t p_id, const common::ObNewRange &value,
common::ObIArray<int64_t> &partition_ids, int64_t *part_idx = NULL);
};
} // namespace sql
......
......@@ -127,7 +127,7 @@ int ObMultiPartInsertOp::shuffle_insert_row(bool& got_row)
} else if (OB_FAIL(calc_part_id_expr->eval(eval_ctx_, partition_id_datum))) {
LOG_WARN("fail to calc part id", K(ret), K(calc_part_id_expr));
} else if (ObExprCalcPartitionId::NONE_PARTITION_ID == partition_id_datum->get_int()) {
ret = OB_INVALID_ARGUMENT;
ret = OB_NO_PARTITION_FOR_GIVEN_VALUE;
LOG_WARN("no partition matched", K(ret), K(child_->get_spec().output_));
} else {
if (OB_FAIL(add_var_to_array_no_dup(part_ids, partition_id_datum->get_int(), &part_idx))) {
......
......@@ -3890,3 +3890,16 @@ int ObSQLUtils::handle_audit_record(
session.reset_audit_record();
return ret;
}
bool ObSQLUtils::is_one_part_table_can_skip_part_calc(const ObTableSchema &schema)
{
bool can_skip = false;
if (!schema.is_partitioned_table()) {
can_skip = true;
} else if (schema.get_all_part_num() == 1 && schema.is_hash_part()) {
can_skip = true;
} else {
can_skip = false;
}
return can_skip;
}
......@@ -332,6 +332,7 @@ public:
static int print_identifier(char* buf, const int64_t buf_len, int64_t& pos,
common::ObCollationType connection_collation, const common::ObString& identifier_name);
static bool is_one_part_table_can_skip_part_calc(const share::schema::ObTableSchema &schema);
private:
static int check_ident_name(const common::ObCollationType cs_type, common::ObString& name,
......
......@@ -690,6 +690,7 @@ int ObLogInsert::need_multi_table_dml(AllocExchContext& ctx, ObShardingInfo& sha
bool has_rand_part_key = false;
bool has_subquery_part_key = false;
bool trigger_exist = false;
bool is_one_part_table = false;
bool is_match = false;
ObInsertStmt* insert_stmt = static_cast<ObInsertStmt*>(get_stmt());
is_needed = false;
......@@ -702,9 +703,12 @@ int ObLogInsert::need_multi_table_dml(AllocExchContext& ctx, ObShardingInfo& sha
} else if (OB_ISNULL(tbl_schema)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("table schema is null", K(ret), K(insert_stmt));
} else if (FALSE_IT(is_one_part_table = ObSQLUtils::is_one_part_table_can_skip_part_calc(*tbl_schema))) {
} else if (insert_stmt->is_ignore() && !is_one_part_table) {
is_needed = true;
} else if (modify_multi_tables()) {
is_needed = true;
} else if (is_table_update_part_key() && tbl_schema->get_all_part_num() > 1) {
} else if (is_table_update_part_key() && !is_one_part_table) {
is_needed = true;
}
......@@ -731,12 +735,16 @@ int ObLogInsert::need_multi_table_dml(AllocExchContext& ctx, ObShardingInfo& sha
} else if (get_part_hint() != NULL && insert_stmt->value_from_select()) {
is_needed = true;
} else if (target_sharding_info.is_local()) {
is_needed = false;
sharding_info.copy_with_part_keys(target_sharding_info);
if (is_one_part_table || !table_partition_info_.get_table_location().is_all_partition()) {
is_needed = false;
sharding_info.copy_with_part_keys(target_sharding_info);
} else {
is_needed = true;
}
} else if (OB_FAIL(input_sharding.push_back(&target_sharding_info)) ||
OB_FAIL(input_sharding.push_back(&child->get_sharding_info()))) {
LOG_WARN("failed to push back sharding info", K(ret));
} else if (ObLogicalOperator::compute_basic_sharding_info(input_sharding, output_sharding, is_basic)) {
} else if (OB_FAIL(ObLogicalOperator::compute_basic_sharding_info(input_sharding, output_sharding, is_basic))) {
LOG_WARN("failed to compute basic sharding info", K(ret));
} else if (is_basic) {
is_needed = false;
......
......@@ -269,7 +269,7 @@ int ObLogUpdate::need_multi_table_dml(AllocExchContext& ctx, ObShardingInfo& sha
LOG_WARN("schema guard is null");
} else if (OB_FAIL(schema_guard->get_table_schema(ref_table_id, tbl_schema))) {
LOG_WARN("get table schema failed", K(ret));
} else if (is_update_part_key && tbl_schema->get_all_part_num() > 1) {
} else if (is_update_part_key && !ObSQLUtils::is_one_part_table_can_skip_part_calc(*tbl_schema)) {
is_needed = true;
sharding_info.reset();
}
......
......@@ -960,6 +960,7 @@ ObTableLocation& ObTableLocation::operator=(const ObTableLocation& other)
use_calc_part_by_rowid_ = other.use_calc_part_by_rowid_;
is_valid_range_columns_part_range_ = other.is_valid_range_columns_part_range_;
is_valid_range_columns_subpart_range_ = other.is_valid_range_columns_subpart_range_;
report_err_for_pruned_partition_not_exist_ = other.report_err_for_pruned_partition_not_exist_;
for (int64_t i = 0; OB_SUCC(ret) && i < other.list_part_array_.count(); i++) {
ObListPartMapValue value;
value.part_id_ = other.list_part_array_.at(i).part_id_;
......@@ -1214,6 +1215,7 @@ int ObTableLocation::init_table_location(ObSqlSchemaGuard& schema_guard, uint64_
is_contain_mv_ = stmt.get_query_ctx()->is_contain_mv_;
if (stmt.is_insert_stmt()) {
set_simple_insert_or_replace();
report_err_for_pruned_partition_not_exist_ = true;
}
}
if (OB_FAIL(ret)) {
......@@ -1396,6 +1398,9 @@ int ObTableLocation::init(const ObTableSchema* table_schema, ObDMLStmt& stmt, Ob
is_contain_mv_ = stmt.get_query_ctx()->is_contain_mv_;
is_partitioned_ = true;
// direction_ = direction;
if (stmt.is_insert_stmt()) {
report_err_for_pruned_partition_not_exist_ = true;
}
if (OB_UNLIKELY(inited_)) {
ret = OB_INIT_TWICE;
......@@ -4055,13 +4060,12 @@ int ObTableLocation::calc_partition_id_by_func_value(ObExprCtx& expr_ctx, common
} else {
}
} else {
bool insert_or_replace = is_simple_insert_or_replace();
if (NULL == part_ids) {
if (OB_FAIL(ObPartMgrAD::get_part(part_mgr,
ref_table_id_,
PARTITION_LEVEL_ONE,
part_type_,
insert_or_replace,
report_err_for_pruned_partition_not_exist_,
-1,
result,
partition_ids,
......@@ -4074,7 +4078,7 @@ int ObTableLocation::calc_partition_id_by_func_value(ObExprCtx& expr_ctx, common
ref_table_id_,
PARTITION_LEVEL_TWO,
subpart_type_,
insert_or_replace,
report_err_for_pruned_partition_not_exist_,
part_ids->at(idx),
result,
partition_ids,
......@@ -4138,6 +4142,7 @@ int ObTableLocation::calc_partition_ids_by_rowkey(ObExecContext& exec_ctx, ObPar
int ObTableLocation::get_list_part(
const ObNewRow& row, bool insert_or_replace, common::ObIArray<int64_t>& partition_ids, int64_t* part_idx) const
{
UNUSED(insert_or_replace);
int ret = OB_SUCCESS;
ObListPartMapValue* value = NULL;
ObListPartMapKey key;
......@@ -4146,7 +4151,7 @@ int ObTableLocation::get_list_part(
if (ret == OB_HASH_NOT_EXIST) {
LOG_TRACE("get list part not exist", K(key));
if (list_default_part_id_ == OB_INVALID_ID) {
if (insert_or_replace) {
if (report_err_for_pruned_partition_not_exist_) {
ret = OB_NO_PARTITION_FOR_GIVEN_VALUE;
} else {
ret = OB_SUCCESS;
......@@ -4213,6 +4218,7 @@ int ObTableLocation::get_hash_part(
int ObTableLocation::get_range_part(
const ObNewRow& row, bool insert_or_replace, common::ObIArray<int64_t>& partition_ids, int64_t* part_idx) const
{
UNUSED(insert_or_replace);
int ret = OB_SUCCESS;
int64_t high = partition_num_ - 1;
int64_t low = 0;
......@@ -4224,7 +4230,7 @@ int ObTableLocation::get_range_part(
LOG_WARN("get range part with optimization should have 1 column", K(ret), K(row.get_count()));
} else if (cur_obj.is_null()) {
// For Insert or replace stmt, if no partition, report error
if (!range_obj_arr_[high].is_max_value() && insert_or_replace) {
if (!range_obj_arr_[high].is_max_value() && report_err_for_pruned_partition_not_exist_) {
ret = OB_NO_PARTITION_FOR_GIVEN_VALUE;
LOG_USER_WARN(OB_NO_PARTITION_FOR_GIVEN_VALUE);
}
......@@ -4243,7 +4249,7 @@ int ObTableLocation::get_range_part(
if (!range_obj_arr_[res].is_max_value() &&
!ObObjCmpFuncs::compare_oper_nullsafe(
range_obj_arr_[res], cur_obj, range_obj_arr_[mid].get_collation_type(), CO_GT)) {
if (insert_or_replace) { // For Insert or replace stmt, if no partition, report error
if (report_err_for_pruned_partition_not_exist_) {
ret = OB_NO_PARTITION_FOR_GIVEN_VALUE;
LOG_USER_WARN(OB_NO_PARTITION_FOR_GIVEN_VALUE);
}
......@@ -4312,11 +4318,11 @@ int ObTableLocation::calc_partition_id_by_row(ObExecContext& exec_ctx, common::O
part_projector_.project_part_row(PARTITION_LEVEL_ONE, row);
if (related_part_expr_idx_ == OB_INVALID_INDEX) {
if (use_list_part_map_) {
if (OB_FAIL(get_list_part(row, insert_or_replace, partition_ids, &part_idx))) {
if (OB_FAIL(get_list_part(row, report_err_for_pruned_partition_not_exist_, partition_ids, &part_idx))) {
LOG_WARN("fail to get list part", K(row), K(ret));
}
} else if (use_range_part_opt_) {
if (OB_FAIL(get_range_part(row, insert_or_replace, partition_ids, &part_idx))) {
if (OB_FAIL(get_range_part(row, report_err_for_pruned_partition_not_exist_, partition_ids, &part_idx))) {
LOG_WARN("fail to get range part", K(row), K(ret));
}
} else {
......@@ -4324,7 +4330,7 @@ int ObTableLocation::calc_partition_id_by_row(ObExecContext& exec_ctx, common::O
ref_table_id_,
PARTITION_LEVEL_ONE,
part_type_,
insert_or_replace,
report_err_for_pruned_partition_not_exist_,
-1,
row,
partition_ids,
......@@ -4343,11 +4349,12 @@ int ObTableLocation::calc_partition_id_by_row(ObExecContext& exec_ctx, common::O
LOG_WARN("Failed to calc hash expr", K(ret), K(row), K(ref_table_id_));
} else {
if (use_list_part_map_) {
if (OB_FAIL(get_list_part(func_result, insert_or_replace, partition_ids, &part_idx))) {
if (OB_FAIL(get_list_part(
func_result, report_err_for_pruned_partition_not_exist_, partition_ids, &part_idx))) {
LOG_WARN("fail to get list part", K(ret));
}
} else if (use_range_part_opt_) {
if (OB_FAIL(get_range_part(row, insert_or_replace, partition_ids, &part_idx))) {
if (OB_FAIL(get_range_part(row, report_err_for_pruned_partition_not_exist_, partition_ids, &part_idx))) {
LOG_WARN("fail to get range part", K(ret));
}
} else {
......@@ -4355,7 +4362,7 @@ int ObTableLocation::calc_partition_id_by_row(ObExecContext& exec_ctx, common::O
ref_table_id_,
PARTITION_LEVEL_ONE,
part_type_,
insert_or_replace,
report_err_for_pruned_partition_not_exist_,
-1,
func_result,
partition_ids,
......@@ -4384,7 +4391,7 @@ int ObTableLocation::calc_partition_id_by_row(ObExecContext& exec_ctx, common::O
ref_table_id_,
PARTITION_LEVEL_TWO,
subpart_type_,
insert_or_replace,
report_err_for_pruned_partition_not_exist_,
part_ids->at(idx),
row,
partition_ids,
......@@ -4406,7 +4413,7 @@ int ObTableLocation::calc_partition_id_by_row(ObExecContext& exec_ctx, common::O
if (OB_FAIL(ret) || range_columns) {
} else {
if (use_hash_part_opt_) {
if (OB_FAIL(get_hash_part(func_result, insert_or_replace, partition_ids, &part_idx))) {
if (OB_FAIL(get_hash_part(func_result, report_err_for_pruned_partition_not_exist_, partition_ids, &part_idx))) {
LOG_WARN("fail to get hash part", K(ret));
}
} else if (OB_FAIL(calc_partition_id_by_func_value(
......
......@@ -482,7 +482,8 @@ public:
range_part_id_arr_(NULL),
use_calc_part_by_rowid_(false),
is_valid_range_columns_part_range_(false),
is_valid_range_columns_subpart_range_(false)
is_valid_range_columns_subpart_range_(false),
report_err_for_pruned_partition_not_exist_(false)
{}
// Used in situations where the optimizer does not adjust the destructor, to ensure that
......@@ -555,7 +556,8 @@ public:
hash_part_array_(common::OB_MALLOC_NORMAL_BLOCK_SIZE, common::ModulePageAllocator(allocator_)),
use_calc_part_by_rowid_(false),
is_valid_range_columns_part_range_(false),
is_valid_range_columns_subpart_range_(false)
is_valid_range_columns_subpart_range_(false),
report_err_for_pruned_partition_not_exist_(false)
{}
virtual ~ObTableLocation()
{
......@@ -839,6 +841,13 @@ public:
int calculate_partition_ids_with_rowid(ObExecContext& exec_ctx, share::schema::ObSchemaGetterGuard& schema_guard,
const ParamStore& params, common::ObIArray<int64_t>& part_ids) const;
inline bool is_all_partition() const
{
return (part_level_ == share::schema::PARTITION_LEVEL_ZERO) ||
(part_get_all_ && (part_level_ == share::schema::PARTITION_LEVEL_ONE)) ||
(part_get_all_ && subpart_get_all_ && (part_level_ == share::schema::PARTITION_LEVEL_TWO));
}
TO_STRING_KV(K_(table_id), K_(ref_table_id), K_(part_num), K_(is_global_index), K_(duplicate_type),
K_(part_expr_param_idxs), K_(part_projector), K_(part_expr), K_(gen_col_expr));
......@@ -1134,6 +1143,8 @@ private:
bool use_calc_part_by_rowid_;
bool is_valid_range_columns_part_range_;
bool is_valid_range_columns_subpart_range_;
bool report_err_for_pruned_partition_not_exist_;
};
} // namespace sql
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册