diff --git a/src/sql/resolver/expr/ob_raw_expr_canonicalizer_impl.cpp b/src/sql/resolver/expr/ob_raw_expr_canonicalizer_impl.cpp index 23f6fed179..f6ba0749f5 100644 --- a/src/sql/resolver/expr/ob_raw_expr_canonicalizer_impl.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_canonicalizer_impl.cpp @@ -159,6 +159,7 @@ int ObRawExprCanonicalizerImpl::pull_and_factor(ObRawExpr *&expr) int64_t factor_num = INT64_MAX; // continue processing when one 'and'(ObOpRawExpr) exist at least bool do_handle = false; + bool expr_copied = false; ObOpRawExpr *m_expr = static_cast(expr); for (int64_t i = 0; OB_SUCC(ret) && i < m_expr->get_param_count(); ++i) { const ObRawExpr *and_expr = m_expr->get_param_expr(i); @@ -282,6 +283,32 @@ int ObRawExprCanonicalizerImpl::pull_and_factor(ObRawExpr *&expr) LOG_WARN("failed to add param expr", K(ret)); } // 2. remove from or + if (OB_SUCC(ret) && !expr_copied) { + // deep copy T_OP_OR and T_OP_AND to make expr unshared + ObRawExprCopier expr_copier(ctx_.expr_factory_); + ObOpRawExpr *new_or_expr = NULL; + ObArray new_candidate_factors; + if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_OP_OR, new_or_expr))) { + LOG_WARN("alloc ObOpRawExpr failed", K(ret)); + } else if (OB_ISNULL(new_or_expr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("new_or_expr is null"); + } + for (int64_t j = 0; OB_SUCC(ret) && j < m_expr->get_param_count(); ++j) { + ObRawExpr *new_or_param = m_expr->get_param_expr(j); + if (T_OP_AND == new_or_param->get_expr_type() && + OB_FAIL(expr_copier.copy_expr_node(new_or_param, new_or_param))) { + LOG_WARN("failed to copy expr node", K(ret)); + } else if (OB_FAIL(new_or_expr->add_param_expr(new_or_param))) { + LOG_WARN("failed to add param expr", K(ret)); + } + } + if (OB_SUCC(ret)) { + m_expr = new_or_expr; + expr = new_or_expr; + expr_copied = true; + } + } for (int64_t j = 0; OB_SUCC(ret) && j < idxs.count(); ++j) { ObOpRawExpr *and_expr = NULL; if (OB_ISNULL(m_expr->get_param_expr(j))) { diff --git a/src/sql/resolver/expr/ob_shared_expr_resolver.cpp b/src/sql/resolver/expr/ob_shared_expr_resolver.cpp index 6bbc32eee7..b0c7021a7d 100644 --- a/src/sql/resolver/expr/ob_shared_expr_resolver.cpp +++ b/src/sql/resolver/expr/ob_shared_expr_resolver.cpp @@ -162,6 +162,7 @@ int ObSharedExprResolver::get_shared_instance(ObRawExpr *expr, expr->is_query_ref_expr() || expr->is_exec_param_expr() || expr->is_pseudo_column_expr() || + expr->get_expr_type() == T_OP_ROW || expr->get_expr_type() == T_QUESTIONMARK) { shared_expr = expr; } else { diff --git a/src/sql/rewrite/ob_transform_simplify_expr.cpp b/src/sql/rewrite/ob_transform_simplify_expr.cpp index 4d56058806..05cee2d9ae 100644 --- a/src/sql/rewrite/ob_transform_simplify_expr.cpp +++ b/src/sql/rewrite/ob_transform_simplify_expr.cpp @@ -1590,6 +1590,12 @@ int ObTransformSimplifyExpr::do_convert_nvl_predicate(ObDMLStmt *stmt, if (OB_ISNULL(exp1) || OB_ISNULL(exp2)){ ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(exp1), K(exp2)); + } else if (nvl_expr->get_collation_level() != exp2->get_collation_level() && + OB_FAIL(ObTransformUtils::add_cast_for_replace(*ctx_->expr_factory_, + nvl_expr, + exp2, + ctx_->session_info_))) { + LOG_WARN("failed to add cast for replace", K(ret)); } else if (OB_FAIL(ObRawExprUtils::create_double_op_expr(*(ctx_->expr_factory_), ctx_->session_info_, parent_expr->get_expr_type(),