diff --git a/src/sql/engine/expr/ob_expr_operator.cpp b/src/sql/engine/expr/ob_expr_operator.cpp index 3c4cf08245..003e414c03 100644 --- a/src/sql/engine/expr/ob_expr_operator.cpp +++ b/src/sql/engine/expr/ob_expr_operator.cpp @@ -2268,11 +2268,17 @@ int ObRelationalExprOperator::is_equal_transitive(const common::ObObjMeta &meta1 { int ret = OB_SUCCESS; result = false; - ObObjMeta equal_meta; - if (OB_FAIL(get_equal_meta(equal_meta, meta1, meta2))) { - LOG_WARN("get equal meta failed", K(ret), K(meta1), K(meta2)); + ObObjType type = ObMaxType; + if (OB_FAIL(ObExprResultTypeUtil::get_relational_equal_type(type, + meta1.get_type(), + meta2.get_type()))) { + LOG_WARN("get equal type failed", K(ret), K(meta1), K(meta2)); + } else if (ObMaxType == type) { + // do nothing + } else if (!ob_is_string_or_lob_type(type)) { + result = true; } else { - result = equal_meta.get_type() != ObMaxType; + result = meta1.get_collation_type() == meta2.get_collation_type(); } return ret; } @@ -2283,7 +2289,6 @@ int ObRelationalExprOperator::get_equal_meta(ObObjMeta &meta, { int ret = OB_SUCCESS; ObObjType type = ObMaxType; - ObExprTypeCtx type_ctx; if (OB_FAIL(ObExprResultTypeUtil::get_relational_equal_type(type, meta1.get_type(), meta2.get_type()))) { diff --git a/src/sql/optimizer/ob_fd_item.cpp b/src/sql/optimizer/ob_fd_item.cpp index 01cf12e590..6f944e5f46 100644 --- a/src/sql/optimizer/ob_fd_item.cpp +++ b/src/sql/optimizer/ob_fd_item.cpp @@ -116,7 +116,6 @@ int ObTableFdItem::check_expr_in_child(const ObRawExpr *expr, { int ret = OB_SUCCESS; const ObRawExpr *cur_expr = NULL; - bool is_consistent = false; is_in_child = false; if (OB_ISNULL(expr)) { ret = OB_ERR_UNEXPECTED; @@ -143,9 +142,7 @@ int ObTableFdItem::check_expr_in_child(const ObRawExpr *expr, } else if (cur_expr->get_relation_ids().is_empty() || !child_tables_.is_superset(cur_expr->get_relation_ids())) { // do nothing - } else if (OB_FAIL(ObRawExprUtils::expr_is_order_consistent(cur_expr, expr, is_consistent))) { - LOG_WARN("failed to check expr is order consistent", K(ret)); - } else if (is_consistent) { + } else { is_in_child = true; } } diff --git a/src/sql/optimizer/ob_optimizer_util.cpp b/src/sql/optimizer/ob_optimizer_util.cpp index 650aa95521..76c6e5da1a 100644 --- a/src/sql/optimizer/ob_optimizer_util.cpp +++ b/src/sql/optimizer/ob_optimizer_util.cpp @@ -637,9 +637,9 @@ bool ObOptimizerUtil::is_expr_equivalent(const ObRawExpr *from, bret = true; } else if (equal_sets.empty()) { // do nothing - } else if (ObRawExprUtils::expr_is_order_consistent(from, to, is_consistent) - != OB_SUCCESS) { - LOG_WARN_RET(OB_ERR_UNEXPECTED, "check expr is order consist ent failed"); + } else if (ObRelationalExprOperator::is_equal_transitive(from->get_result_type(), + to->get_result_type(), is_consistent) != OB_SUCCESS) { + LOG_WARN_RET(OB_ERR_UNEXPECTED, "failed to check is equal transitive"); } else if (is_consistent) { int64_t N = equal_sets.count(); for (int64_t i = 0; !l_found && !r_found && i < N; ++i) { @@ -836,8 +836,9 @@ int ObOptimizerUtil::is_root_expr_const(const ObRawExpr *expr, if (OB_ISNULL(cur_expr = equal_set->at(j))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr passed in should not be NULL", K(j), K(ret)); - } else if (OB_FAIL(ObRawExprUtils::expr_is_order_consistent(cur_expr, expr, is_consistent))) { - LOG_WARN("check expr is order consistent failed", K(ret)); + } else if (OB_FAIL(ObRelationalExprOperator::is_equal_transitive(cur_expr->get_result_type(), + expr->get_result_type(), is_consistent))) { + LOG_WARN("failed to check is equal transitive", K(ret)); } else if (is_consistent && OB_FAIL(is_const_expr(cur_expr, const_exprs, is_const))) { LOG_WARN("failed to check const expr", K(cur_expr), K(ret)); } else { /*do nothing*/ } @@ -5263,7 +5264,7 @@ int ObOptimizerUtil::simplify_ordered_exprs(const ObFdItemSet &fd_item_set, ObIArray &order_exprs) { int ret = OB_SUCCESS; - ObSqlBitSet<> eliminate_set; + ObSqlBitSet<> candi_set; ObSqlBitSet<> checked_fd_item; ObFdItem *fd_item = NULL; bool is_contain = false; @@ -5272,34 +5273,37 @@ int ObOptimizerUtil::simplify_ordered_exprs(const ObFdItemSet &fd_item_set, order_exprs.reset(); ObSEArray extended_order_exprs; ObSEArray fd_set_parent_exprs; - ObRawExpr *first_removed_expr = NULL; if (OB_FAIL(get_fd_set_parent_exprs(fd_item_set, fd_set_parent_exprs))) { LOG_WARN("failed to get fd set parent exprs ", K(ret)); + } else if (OB_FAIL(candi_set.init_mask(candi_exprs.count()))) { + LOG_WARN("failed to init mask", K(ret)); } for (int64_t i = 0; OB_SUCC(ret) && i < candi_exprs.count(); ++i) { ObRawExpr *expr = NULL; if (OB_ISNULL(expr = candi_exprs.at(i))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get null fd item", K(ret)); + } else if (!candi_set.has_member(i)) { + /*do nothing*/ } else if (OB_FAIL(is_const_or_equivalent_expr(candi_exprs, equal_sets, const_exprs, exec_ref_exprs, i, is_const))) { LOG_WARN("failed to check is const expr", K(ret)); } else if (is_const) {//const expr 不需要排序 /*do nothing*/ - } else if (eliminate_set.has_member(i)) { - first_removed_expr = NULL == first_removed_expr ? expr : first_removed_expr; } else if (OB_FAIL(order_exprs.push_back(expr))) { LOG_WARN("failed to push back exprs", K(ret)); } else if (OB_FAIL(extended_order_exprs.push_back(expr))) { LOG_WARN("failed to push back exprs", K(ret)); } else if (OB_FAIL(remove_item(fd_set_parent_exprs, expr))) { LOG_WARN("failed to remove expr", K(ret)); + } else if (OB_FAIL(candi_set.del_member(i))) { + LOG_WARN("failed to add member", K(ret)); } else { //查找目前 extended_order_exprs 中包含的 fd, 并使用 fd 查找并标记 candi_exprs i 位置后需要移除的expr int64_t last_count = -1; - while (extended_order_exprs.count() > last_count) { + while (extended_order_exprs.count() > last_count && !candi_set.is_empty()) { last_count = extended_order_exprs.count(); - for (int64_t fd_idx = 0; OB_SUCC(ret) && fd_idx < fd_item_set.count(); ++fd_idx) { + for (int64_t fd_idx = 0; OB_SUCC(ret) && fd_idx < fd_item_set.count() && !candi_set.is_empty(); ++fd_idx) { if (checked_fd_item.has_member(fd_idx)) {//对于已经进行检查的 fd 不再重复检查 /*do nothing*/ } else if (OB_ISNULL(fd_item = fd_item_set.at(fd_idx))) { @@ -5311,7 +5315,7 @@ int ObOptimizerUtil::simplify_ordered_exprs(const ObFdItemSet &fd_item_set, LOG_WARN("failed to check is exprs contain fd parent", K(ret)); } else if (is_contain) { for (int64_t j = i+1; OB_SUCC(ret) && j < candi_exprs.count(); ++j) { - if (eliminate_set.has_member(j)) { + if (!candi_set.has_member(j)) { /*do nothing*/ } else if (OB_FAIL(fd_item->check_expr_in_child(candi_exprs.at(j), equal_sets, is_in_child))) { @@ -5320,7 +5324,7 @@ int ObOptimizerUtil::simplify_ordered_exprs(const ObFdItemSet &fd_item_set, /*do nothing*/ } else if (candi_exprs.at(j)->has_flag(CNT_SUB_QUERY)) { /* to check output more than one row, do not remove subquery in order expr. */ - } else if (OB_FAIL(eliminate_set.add_member(j))) { + } else if (OB_FAIL(candi_set.del_member(j))) { LOG_WARN("failed to add member", K(ret)); } } @@ -5336,10 +5340,10 @@ int ObOptimizerUtil::simplify_ordered_exprs(const ObFdItemSet &fd_item_set, } } } - } - if (OB_FAIL(ret) && order_exprs.empty() && NULL != first_removed_expr - && OB_FAIL(order_exprs.push_back(first_removed_expr))) { - LOG_WARN("failed to push back exprs", K(ret)); + if (OB_FAIL(ret)) { + } else if (OB_FAIL(candi_set.del_member(i))) { + LOG_WARN("failed to add member", K(ret)); + } } return ret; } diff --git a/src/sql/resolver/expr/ob_raw_expr.h b/src/sql/resolver/expr/ob_raw_expr.h index 6e870a5296..d11adf622e 100644 --- a/src/sql/resolver/expr/ob_raw_expr.h +++ b/src/sql/resolver/expr/ob_raw_expr.h @@ -530,6 +530,38 @@ public: return ret; } + int init_mask(int64_t mask_bits) + { + int ret = OB_SUCCESS; + if (!is_valid()) { + ret = desc_.init_errcode_; + SQL_RESV_LOG(WARN, "got init error", K(desc_.init_errcode_)); + } else if (OB_UNLIKELY (mask_bits < 0)) { + ret = OB_INVALID_ARGUMENT; + SQL_RESV_LOG(WARN, "negative bitmap member not allowed", K(ret), K(index)); + } else if (0 == mask_bits) { + // do nothing + } else { + int64_t pos = mask_bits >> PER_BITSETWORD_MOD_BITS; + if (OB_UNLIKELY(pos + 1 > INT16_MAX)) { + ret = OB_SIZE_OVERFLOW; + SQL_RESV_LOG(WARN, "ObSqlBitSet pos overflow", K(ret), K(index), K(pos)); + } else if (OB_UNLIKELY(pos >= desc_.cap_)) { + int64_t new_word_cnt = pos + 1; + if (OB_FAIL(alloc_new_buf(new_word_cnt))) { + SQL_RESV_LOG(WARN, "failed to alloc new buf", K(ret)); + } + } + if (OB_SUCC(ret)) { + desc_.len_ = pos + 1; + MEMSET(bit_set_word_array_, UINT8_MAX, pos * sizeof(BitSetWord)); + MEMSET(bit_set_word_array_ + pos, 0, (desc_.cap_ - pos) * sizeof(BitSetWord)); + bit_set_word_array_[pos] |= (1 << (mask_bits % PER_BITSETWORD_BITS)) - 1; + } + } + return ret; + } + template int add_members(const ObSqlBitSet &other) { diff --git a/src/sql/resolver/expr/ob_raw_expr_util.cpp b/src/sql/resolver/expr/ob_raw_expr_util.cpp index 5f14e79b86..b3e08aeaba 100644 --- a/src/sql/resolver/expr/ob_raw_expr_util.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_util.cpp @@ -7224,21 +7224,6 @@ int ObRawExprUtils::init_column_expr(const ObColumnSchemaV2 &column_schema, ObCo return ret; } -int ObRawExprUtils::expr_is_order_consistent(const ObRawExpr *from, const ObRawExpr *to, bool &is_consistent) -{ - int ret = OB_SUCCESS; - is_consistent = false; - if (OB_ISNULL(from) || OB_ISNULL(to)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("expr is null", K(from), K(to)); - } else if (OB_FAIL(ObObjCaster::is_order_consistent(from->get_result_type(), - to->get_result_type(), - is_consistent))) { - LOG_WARN("check is order consistent failed", K(ret)); - } - return ret; -} - int ObRawExprUtils::is_expr_comparable(const ObRawExpr *expr, bool &can_be) { int ret = OB_SUCCESS; diff --git a/src/sql/resolver/expr/ob_raw_expr_util.h b/src/sql/resolver/expr/ob_raw_expr_util.h index 68e19724d7..4be3fa075b 100644 --- a/src/sql/resolver/expr/ob_raw_expr_util.h +++ b/src/sql/resolver/expr/ob_raw_expr_util.h @@ -910,7 +910,6 @@ public: static ObCollationLevel get_column_collation_level(const common::ObObjType &type); /* 计算基本列的flag */ static uint32_t calc_column_result_flag(const share::schema::ObColumnSchemaV2 &column_schema); - static int expr_is_order_consistent(const ObRawExpr *from, const ObRawExpr *to, bool &is_consistent); static int is_expr_comparable(const ObRawExpr *expr, bool &can_be); static int exprs_contain_subquery(const common::ObIArray &exprs, bool &cnt_subquery); static int function_alias(ObRawExprFactory &expr_factory, ObSysFunRawExpr *&expr); diff --git a/src/sql/rewrite/ob_transform_simplify_orderby.cpp b/src/sql/rewrite/ob_transform_simplify_orderby.cpp index 04599763f4..6abbd932ec 100644 --- a/src/sql/rewrite/ob_transform_simplify_orderby.cpp +++ b/src/sql/rewrite/ob_transform_simplify_orderby.cpp @@ -254,30 +254,24 @@ int ObTransformSimplifyOrderby::remove_order_by_duplicates(ObDMLStmt *stmt, } else { ObRawExpr *left_param = op_expr->get_param_expr(0); ObRawExpr *right_param = op_expr->get_param_expr(1); + bool is_consistent = false; if (OB_ISNULL(left_param) || OB_ISNULL(right_param)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("null pointer in condtion exprs", K(ret)); - } else { - bool is_consistent = false; - if (right_param == cur_item.expr_) { - //因为判断expr的类型的序是否可传递是有方向的,所以要情况调用,这里待确定的表达式位于等号的右端 - if (OB_FAIL(ObRawExprUtils::expr_is_order_consistent(left_param, right_param, is_consistent))) { - LOG_WARN("check expr is order consistent failed", K(ret), K(*left_param), K(*right_param)); - } else if (is_consistent) { - if (OB_FAIL(exist_item_by_expr(left_param, new_order_items, is_exist))) { - LOG_WARN("fail to find expr in items", K(ret)); - } - } - } else if (left_param == cur_item.expr_) { - //因为判断expr的类型的序是否可传递是有方向的,所以要情况调用,这里待确定的表达式位于等号的左端 - if (OB_FAIL(ObRawExprUtils::expr_is_order_consistent(right_param, left_param, is_consistent))) { - LOG_WARN("check expr is order consistent failed", K(ret), K(*left_param), K(*right_param)); - } else if (is_consistent) { - if (OB_FAIL(exist_item_by_expr(right_param, new_order_items, is_exist))) { - LOG_WARN("fail to find expr in items", K(ret)); - } - } - } else {/* do nothing */} + } else if (OB_FAIL(ObRelationalExprOperator::is_equal_transitive( + left_param->get_result_type(), + right_param->get_result_type(), is_consistent))) { + LOG_WARN("failed to check is equal transitive", K(ret), KPC(left_param), KPC(right_param)); + } else if (!is_consistent) { + // do nothing + } else if (right_param == cur_item.expr_) { + if (OB_FAIL(exist_item_by_expr(left_param, new_order_items, is_exist))) { + LOG_WARN("fail to find expr in items", K(ret)); + } + } else if (left_param == cur_item.expr_) { + if (OB_FAIL(exist_item_by_expr(right_param, new_order_items, is_exist))) { + LOG_WARN("fail to find expr in items", K(ret)); + } } } } else {/* do nothing */} diff --git a/src/sql/rewrite/ob_transform_utils.cpp b/src/sql/rewrite/ob_transform_utils.cpp index 6e405dd08b..3786d07a36 100644 --- a/src/sql/rewrite/ob_transform_utils.cpp +++ b/src/sql/rewrite/ob_transform_utils.cpp @@ -4863,7 +4863,7 @@ int ObTransformUtils::compute_basic_table_property(const ObDMLStmt *stmt, int ObTransformUtils::need_compute_fd_item_set(ObIArray &exprs) { bool need = true; - if (exprs.count() > 128) { + if (exprs.count() > 32) { need = false; } return need; diff --git a/unittest/sql/resolver/test_sql_bitset.cpp b/unittest/sql/resolver/test_sql_bitset.cpp index ec2c116f9f..5e40d654f0 100644 --- a/unittest/sql/resolver/test_sql_bitset.cpp +++ b/unittest/sql/resolver/test_sql_bitset.cpp @@ -165,6 +165,31 @@ TEST_F(TestSqlBitSet, do_mask) ASSERT_TRUE(bs2.has_member(63)); } +TEST_F(TestSqlBitSet, init_mask) +{ + ObSqlBitSet<16> bs; + int64_t mask_bits = 0; + for (int64_t i = 1; i < 128; ++i) { + mask_bits = i; + ASSERT_TRUE(OB_SUCCESS == bs.init_mask(mask_bits)); + ASSERT_EQ(mask_bits, bs.num_members()); + ASSERT_TRUE(OB_SUCCESS == bs.do_mask(0, mask_bits)); + ASSERT_EQ(mask_bits, bs.num_members()); + + mask_bits = i + 1; + ASSERT_TRUE(OB_SUCCESS == bs.init_mask(mask_bits)); + ASSERT_EQ(mask_bits, bs.num_members()); + ASSERT_TRUE(OB_SUCCESS == bs.do_mask(0, mask_bits)); + ASSERT_EQ(mask_bits, bs.num_members()); + + mask_bits = i; + ASSERT_TRUE(OB_SUCCESS == bs.init_mask(mask_bits)); + ASSERT_EQ(mask_bits, bs.num_members()); + ASSERT_TRUE(OB_SUCCESS == bs.do_mask(0, mask_bits)); + ASSERT_EQ(mask_bits, bs.num_members()); + } +} + TEST_F(TestSqlBitSet, set_operation) { ObSqlBitSet<16> bs;