diff --git a/src/sql/resolver/dml/ob_select_resolver.cpp b/src/sql/resolver/dml/ob_select_resolver.cpp index 996e192d8..d8515a5eb 100644 --- a/src/sql/resolver/dml/ob_select_resolver.cpp +++ b/src/sql/resolver/dml/ob_select_resolver.cpp @@ -1430,7 +1430,7 @@ int ObSelectResolver::resolve_for_update_clause_oracle(const ParseNode &node) } else if (OB_ISNULL(expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr is invalid", K(ret), K(expr)); - } else if (is_oracle_mode() && expr->get_data_type() == ObURowIDType) { + } else if (is_oracle_mode() && expr->get_expr_type() == T_FUN_SYS_CALC_UROWID) { ret = OB_ERR_USE_ROWID_FOR_UPDATE; LOG_WARN("FOR UPDATE OF ROWID is illegal", K(ret), K(*expr)); } else if (OB_UNLIKELY(!expr->is_column_ref_expr())) { diff --git a/src/sql/rewrite/ob_key_part.cpp b/src/sql/rewrite/ob_key_part.cpp index 7b9dfc4a4..e2574e708 100644 --- a/src/sql/rewrite/ob_key_part.cpp +++ b/src/sql/rewrite/ob_key_part.cpp @@ -847,8 +847,14 @@ int ObInKeyPart::remove_in_dup_vals() int val_cnt = get_param_val_cnt(); common::hash::ObHashSet distinct_param_val_set; ObSEArray distinct_param_val_arr; - if (OB_FAIL(distinct_param_val_set.create(val_cnt))) { + ObSEArray cmp_funcs; + if (OB_UNLIKELY(param_cnt == 0 || val_cnt == 0)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get invalid in keypart", K(ret), K(param_cnt), K(val_cnt)); + } else if (OB_FAIL(distinct_param_val_set.create(val_cnt))) { LOG_WARN("failed to create partition macro id set", K(ret)); + } else if (OB_FAIL(get_obj_cmp_funcs(cmp_funcs))) { + LOG_WARN("failed to get cmp funcs", K(ret)); } bool has_dup = false; for (int64_t i = 0; OB_SUCC(ret) && i < val_cnt; ++i) { @@ -863,6 +869,8 @@ int ObInKeyPart::remove_in_dup_vals() } } if (OB_FAIL(ret)) { + } else if (OB_FAIL(cur_param_vals.cmp_funcs_.assign(cmp_funcs))) { + LOG_WARN("failed to assign cmp func", K(ret)); } else if (OB_HASH_EXIST == (ret = distinct_param_val_set.set_refactored(cur_param_vals, 0))) { ret = OB_SUCCESS; has_dup = true; @@ -897,6 +905,28 @@ int ObInKeyPart::remove_in_dup_vals() return ret; } +int ObInKeyPart::get_obj_cmp_funcs(ObIArray &cmp_funcs) +{ + int ret = OB_SUCCESS; + for (int64_t i = 0; OB_SUCC(ret) && i < in_params_.count(); ++i) { + InParamMeta *cur_param = in_params_.at(i); + obj_cmp_func cmp_op_func = NULL; + if (OB_ISNULL(cur_param) || OB_UNLIKELY(cur_param->vals_.count() == 0)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get invalid argument", K(ret), K(cur_param), K(i)); + } else { + const ObObjTypeClass obj_tc = cur_param->vals_.at(0).get_meta().get_type_class(); + if (OB_FAIL(ObObjCmpFuncs::get_cmp_func(obj_tc, obj_tc, CO_EQ, cmp_op_func))) { + LOG_WARN("failed to get cmp func", K(ret), K(obj_tc)); + } else { + OB_ASSERT(cmp_op_func != NULL); + ret = cmp_funcs.push_back(cmp_op_func); + } + } + } + return ret; +} + // TODO: can be optimized by hash join algorithm, see ObKeyPart::intersect_two_in_keys, @zhenglailei.zll int ObKeyPart::union_in_dup_vals(ObKeyPart *other, bool &is_unioned) { diff --git a/src/sql/rewrite/ob_key_part.h b/src/sql/rewrite/ob_key_part.h index ca6d3d66e..bc8717b3f 100644 --- a/src/sql/rewrite/ob_key_part.h +++ b/src/sql/rewrite/ob_key_part.h @@ -16,6 +16,7 @@ #include "share/ob_define.h" #include "lib/objectpool/ob_tc_factory.h" #include "lib/container/ob_array_serialization.h" +#include "common/object/ob_obj_compare.h" #include "common/object/ob_object.h" #include "sql/engine/expr/ob_expr_res_type.h" #include "lib/hash/ob_placement_hashmap.h" @@ -175,15 +176,34 @@ struct InParamMeta struct InParamValsWrapper { - InParamValsWrapper(): param_vals_() { } - int assign(const InParamValsWrapper &other) { return param_vals_.assign(other.param_vals_); } + InParamValsWrapper(): + param_vals_(), + cmp_funcs_() + { } + int assign(const InParamValsWrapper &other) + { + int ret = OB_SUCCESS; + if (OB_FAIL(param_vals_.assign(other.param_vals_))) { + SQL_REWRITE_LOG(WARN, "failed to assign param vals", K(ret)); + } else if (OB_FAIL(cmp_funcs_.assign(other.cmp_funcs_))) { + SQL_REWRITE_LOG(WARN, "failed to assign cmp funcs", K(ret)); + } + return ret; + } inline bool operator==(const InParamValsWrapper &other) const { - bool bret = param_vals_.count() == other.param_vals_.count(); - for (int64_t i = 0; bret && i < other.param_vals_.count(); ++i) { - if (param_vals_.at(i) != other.param_vals_.at(i)) { - bret = false; - } + int ret = OB_SUCCESS; + int64_t param_cnt = param_vals_.count(); + int64_t other_param_cnt = other.param_vals_.count(); + int64_t cmp_funcs_cnt = cmp_funcs_.count(); + int64_t other_cmp_funcs_cnt = other.cmp_funcs_.count(); + bool bret = param_cnt == other_param_cnt && cmp_funcs_cnt == other_cmp_funcs_cnt && + param_cnt == cmp_funcs_cnt; + ObCompareCtx cmp_ctx(ObMaxType, CS_TYPE_INVALID, true, INVALID_TZ_OFF, default_null_pos()); + for (int64_t i = 0; bret && i < param_cnt; ++i) { + obj_cmp_func cmp_op_func = cmp_funcs_.at(i); + OB_ASSERT(NULL != cmp_op_func); + bret = (ObObjCmpFuncs::CR_TRUE == cmp_op_func(param_vals_.at(i), other.param_vals_.at(i), cmp_ctx)); } return bret; } @@ -191,21 +211,17 @@ struct InParamValsWrapper { return !(*this == other); } - inline uint64_t hash() const - { - uint64_t hash_code = 0; - for (int64_t i = 0; i < param_vals_.count(); ++i) { - hash_code = param_vals_.at(i).hash(hash_code); - } - return hash_code; - } inline int hash(uint64_t &hash_code) const { int ret = OB_SUCCESS; - hash_code = hash(); + for (int64_t i = 0; OB_SUCC(ret) && i < param_vals_.count(); ++i) { + // no need to calculate hash for cmp_funcs_ + ret = param_vals_.at(i).hash(hash_code, hash_code); + } return ret; } ObSEArray param_vals_; + ObSEArray cmp_funcs_; TO_STRING_KV(K_(param_vals)); }; @@ -246,6 +262,7 @@ struct ObInKeyPart int get_dup_vals(int64_t offset, const common::ObObj &val, common::ObIArray &dup_val_idx); int remove_in_dup_vals(); InParamMeta* create_param_meta(common::ObIAllocator &alloc); + int get_obj_cmp_funcs(ObIArray &cmp_funcs); uint64_t table_id_; InParamsArr in_params_; diff --git a/src/sql/rewrite/ob_query_range.cpp b/src/sql/rewrite/ob_query_range.cpp index d5c1e9bdd..dfee14fc5 100644 --- a/src/sql/rewrite/ob_query_range.cpp +++ b/src/sql/rewrite/ob_query_range.cpp @@ -3786,6 +3786,8 @@ int ObQueryRange::preliminary_extract(const ObRawExpr *node, LOG_WARN("extract in_op failed", K(ret)); } } + LOG_TRACE("succeed to extract range from in_expr", + K(use_in_optimization), K(contain_in_), K(is_single_in), K(*out_key_part)); } else if (T_OP_NOT_IN == node->get_expr_type()) { if (OB_FAIL(pre_extract_not_in_op(b_expr, out_key_part, dtc_params))) { LOG_WARN("extract in_op failed", K(ret));