diff --git a/src/sql/optimizer/ob_join_order.cpp b/src/sql/optimizer/ob_join_order.cpp index 53c3b8e139..9059393d84 100644 --- a/src/sql/optimizer/ob_join_order.cpp +++ b/src/sql/optimizer/ob_join_order.cpp @@ -14263,7 +14263,8 @@ int ObJoinOrder::extract_pushdown_quals(const ObIArray &quals, ret = OB_NOT_SUPPORTED; LOG_USER_ERROR(OB_NOT_SUPPORTED, "join condition contains rownum and subquery"); } - } else if (T_OP_NE == qual->get_expr_type() && + } else if ((T_OP_NE == qual->get_expr_type() || + T_OP_NOT_IN == qual->get_expr_type()) && !force_inner_nl) { //do nothing } else if (OB_FAIL(pushdown_quals.push_back(qual))) { diff --git a/src/sql/optimizer/ob_optimizer_util.cpp b/src/sql/optimizer/ob_optimizer_util.cpp index 353d09cd62..54bea0e5fc 100644 --- a/src/sql/optimizer/ob_optimizer_util.cpp +++ b/src/sql/optimizer/ob_optimizer_util.cpp @@ -4590,6 +4590,12 @@ int ObOptimizerUtil::check_push_down_expr(const ObRelIds &table_ids, { int ret = OB_SUCCESS; all_contain = true; + bool contain_op_row = false; + if (OB_FAIL(ObRawExprUtils::check_contain_op_row_expr(&or_qual, contain_op_row))) { + LOG_WARN("fail to check contain op row", K(ret)); + } else if (contain_op_row) { + all_contain = false; + } for (int64_t i = 0; OB_SUCC(ret) && all_contain && i < or_qual.get_param_count(); ++i) { ObRawExpr *cur_expr = or_qual.get_param_expr(i); if (OB_ISNULL(cur_expr)) { @@ -4678,26 +4684,10 @@ int ObOptimizerUtil::generate_push_down_expr(const ObDMLStmt *stmt, } } } - if (OB_SUCC(ret)) { - //split expr may result T_OP_ROW shared - ObSEArray new_or_exprs; - ObRawExprCopier copier(expr_factory); - ReplaceExprByType replacer(T_OP_ROW); - if (OB_FAIL(copier.copy_on_replace(new_expr_params, - new_or_exprs, - &replacer))) { - LOG_WARN("failed to copy on replace start with exprs", K(ret)); - } else if (OB_UNLIKELY(new_expr_params.count() != new_or_exprs.count())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("get unexpected null", K(ret), K(new_expr_params.count()), K(new_or_exprs.count())); - } else if (OB_FAIL(new_expr_params.assign(new_or_exprs))) { - LOG_WARN("failed to assign assign results", K(ret)); - } else if (OB_FAIL(new_expr->get_param_exprs().assign(new_expr_params))) { - LOG_WARN("failed to assign param exprs", K(ret)); - } - } if (OB_FAIL(ret)) { /* do nothing */ + } else if (OB_FAIL(new_expr->get_param_exprs().assign(new_expr_params))) { + LOG_WARN("failed to assign param exprs", K(ret)); } else if (OB_FAIL(new_expr->formalize(session_info))) { LOG_WARN("failed to formalize or expr", K(ret)); } else if (OB_FAIL(new_expr->pull_relation_id())) { diff --git a/src/sql/resolver/expr/ob_raw_expr_copier.h b/src/sql/resolver/expr/ob_raw_expr_copier.h index 11cc1779a8..48d0a18d9a 100644 --- a/src/sql/resolver/expr/ob_raw_expr_copier.h +++ b/src/sql/resolver/expr/ob_raw_expr_copier.h @@ -219,43 +219,6 @@ int ObRawExprCopier::add_skipped_expr(const ObIArray &targets, bool include return ret; } -/** - * ReplaceExprByType is used to generate new expr when contain some special type node - * as following case, when we need to copy a medium expr: T_OP_ROW, need to deep copy parents - * expr:(c1,c2)!=(1,2) - * ReplaceExprByType(T_OP_ROW) - * old expr:(c1,c2)!=(1,2) new expr:(c1,c2)!=(1,2) - * T_OP_NE T_OP_NE(new) - * T_OP_ROW T_OP_ROW (new)T_OP_ROW T_OP_ROW(new) - * c1 c2 const(1) const(2) (old)c1 (old)c2 (old)const(1) const(2)(old) - */ -class ReplaceExprByType : public ObIRawExprReplacer -{ -public: - ReplaceExprByType(ObItemType expr_type) : expr_type_(expr_type) {} - virtual int generate_new_expr(ObRawExprFactory &expr_factory, - ObRawExpr *old_expr, - ObRawExpr *&new_expr) - { - int ret = OB_SUCCESS; - if (OB_ISNULL(old_expr)) { - ret = OB_ERR_UNEXPECTED; - SQL_RESV_LOG(WARN, "old expr is null", K(ret)); - } else if (old_expr->get_expr_type() == expr_type_) { - if (OB_FAIL(ObRawExprCopier::copy_expr_node(expr_factory, - old_expr, - new_expr))) { - SQL_RESV_LOG(WARN, "failed to copy calc urowid expr", K(ret)); - } else if (OB_ISNULL(new_expr)) { - ret = OB_ERR_UNEXPECTED; - SQL_RESV_LOG(WARN, "failed to build new calc rowid expr", K(ret)); - } - } - return ret; - } - ObItemType expr_type_; -}; - } } diff --git a/src/sql/resolver/expr/ob_raw_expr_util.cpp b/src/sql/resolver/expr/ob_raw_expr_util.cpp index eba0d97ec4..21d6cb8412 100644 --- a/src/sql/resolver/expr/ob_raw_expr_util.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_util.cpp @@ -9137,5 +9137,23 @@ int ObRawExprUtils::ora_cmp_integer(const ObConstRawExpr &const_expr, const int6 return ret; } +int ObRawExprUtils::check_contain_op_row_expr(const ObRawExpr *raw_expr, bool &contain) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(raw_expr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected NULL pointer", K(ret)); + } else if (raw_expr->get_expr_type() == T_OP_ROW && !raw_expr->is_const_expr()) { + contain = true; + } else { + for (int64_t i = 0; OB_SUCC(ret) && !contain && i < raw_expr->get_param_count(); i++) { + if (OB_FAIL(SMART_CALL(check_contain_op_row_expr(raw_expr->get_param_expr(i), contain)))) { + LOG_WARN("failed to replace_ref_column", KPC(raw_expr), K(i)); + } + } + } + return ret; +} + } } diff --git a/src/sql/resolver/expr/ob_raw_expr_util.h b/src/sql/resolver/expr/ob_raw_expr_util.h index 96f848bffd..2f9108f2b3 100644 --- a/src/sql/resolver/expr/ob_raw_expr_util.h +++ b/src/sql/resolver/expr/ob_raw_expr_util.h @@ -1195,6 +1195,7 @@ public: static int extract_local_vars_for_gencol(ObRawExpr *expr, const ObSQLMode sql_mode, ObColumnSchemaV2 &gen_col); + static int check_contain_op_row_expr(const ObRawExpr *raw_expr, bool &contain); private : static int create_real_cast_expr(ObRawExprFactory &expr_factory, diff --git a/src/sql/rewrite/ob_transform_predicate_move_around.cpp b/src/sql/rewrite/ob_transform_predicate_move_around.cpp index 3a4d713589..62a4f79d1c 100644 --- a/src/sql/rewrite/ob_transform_predicate_move_around.cpp +++ b/src/sql/rewrite/ob_transform_predicate_move_around.cpp @@ -2457,6 +2457,12 @@ int ObTransformPredicateMoveAround::check_having_expr(ObSelectStmt &stmt, ObSEArray generalized_columns; ObSEArray param_preds; all_contain = true; + bool contain_op_row = false; + if (OB_FAIL(ObRawExprUtils::check_contain_op_row_expr(&or_qual, contain_op_row))) { + LOG_WARN("fail to check contain op row", K(ret)); + } else if (contain_op_row) { + all_contain = false; + } for (int64_t i = 0; OB_SUCC(ret) && all_contain && i < or_qual.get_param_count(); ++i) { ObRawExpr *cur_expr = or_qual.get_param_expr(i); generalized_columns.reuse(); @@ -2523,22 +2529,6 @@ int ObTransformPredicateMoveAround::inner_split_or_having_expr(ObSelectStmt &stm LOG_WARN("failed to push back expr", K(ret)); } } - if (OB_SUCC(ret)) { - //split expr may result T_OP_ROW shared - ObSEArray new_or_exprs; - ObRawExprCopier copier(*expr_factory); - ReplaceExprByType replacer(T_OP_ROW); - if (OB_FAIL(copier.copy_on_replace(or_exprs, - new_or_exprs, - &replacer))) { - LOG_WARN("failed to copy on replace start with exprs", K(ret)); - } else if (OB_UNLIKELY(or_exprs.count() != new_or_exprs.count())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("get unexpected null", K(ret), K(or_exprs.count()), K(new_or_exprs.count())); - } else if (OB_FAIL(or_exprs.assign(new_or_exprs))) { - LOG_WARN("failed to assign assign results", K(ret)); - } - } if (OB_SUCC(ret)) { if (OB_FAIL(ObRawExprUtils::build_or_exprs(*expr_factory, or_exprs, new_expr))) { LOG_WARN("failed to build or expr", K(ret));