/** * Copyright (c) 2021 OceanBase * OceanBase CE is licensed under Mulan PubL v2. * You can use this software according to the terms and conditions of the Mulan PubL v2. * You may obtain a copy of Mulan PubL v2 at: * http://license.coscl.org.cn/MulanPubL-2.0 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PubL v2 for more details. */ #define USING_LOG_PREFIX SQL_RESV #include "sql/resolver/expr/ob_raw_expr_util.h" #include "share/ob_define.h" #include "share/ob_errno.h" #include "lib/allocator/ob_malloc.h" #include "lib/allocator/page_arena.h" #include "lib/string/ob_string.h" #include "lib/string/ob_sql_string.h" #include "lib/json/ob_json.h" #include "lib/json/ob_json_print_utils.h" #include "sql/resolver/dml/ob_select_stmt.h" #include "sql/resolver/expr/ob_raw_expr.h" #include "sql/resolver/expr/ob_raw_expr_resolver_impl.h" #include "sql/resolver/ob_resolver_utils.h" #include "sql/parser/ob_parser_utils.h" #include "sql/parser/ob_parser.h" #include "sql/parser/ob_sql_parser.h" #include "sql/session/ob_sql_session_info.h" #include "sql/engine/expr/ob_expr_to_type.h" #include "sql/engine/expr/ob_expr_type_to_str.h" #include "sql/engine/expr/ob_expr_column_conv.h" #include "sql/engine/expr/ob_datum_cast.h" #include "sql/engine/expr/ob_expr_cast.h" #include "common/ob_smart_call.h" #include "sql/optimizer/ob_optimizer_util.h" namespace oceanbase { using namespace common; using namespace share; using namespace share::schema; namespace sql { #define RESOLVE_ORALCE_IMLICIT_CAST_WARN_OR_ERR(warn_code, err_code) \ if ((session_info->get_sql_mode() & SMO_ERROR_ON_RESOLVE_CAST) > 0) { \ ret = err_code; \ } else { \ LOG_USER_WARN(warn_code); \ } inline int ObRawExprUtils::resolve_op_expr_add_implicit_cast(ObRawExprFactory& expr_factory, const ObSQLSessionInfo* session_info, ObRawExpr* src_expr, const ObExprResType& dst_type, ObSysFunRawExpr*& func_expr) { int ret = OB_SUCCESS; if (dst_type.is_varying_len_char_type() && !ob_is_rowid_tc(src_expr->get_result_type().get_type())) { ObItemType func_type = T_MAX; const char* func_name = NULL; if (OB_ISNULL(src_expr)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), KP(src_expr)); } else if (src_expr->get_result_type().is_raw()) { func_type = T_FUN_SYS_RAWTOHEX; func_name = N_RAWTOHEX; } else if (dst_type.is_nvarchar2()) { func_type = T_FUN_SYS_TO_NCHAR; func_name = N_TO_NCHAR; } else if (dst_type.is_varchar()) { func_type = T_FUN_SYS_TO_CHAR; func_name = N_TO_CHAR; } if (OB_SUCC(ret)) { if (OB_FAIL(expr_factory.create_raw_expr(func_type, func_expr))) { LOG_WARN("create cast expr failed", K(ret)); } else if (OB_FAIL(func_expr->add_param_expr(src_expr))) { LOG_WARN("add real param expr failed", K(ret)); } else { func_expr->set_func_name(ObString::make_string(func_name)); if (OB_FAIL(func_expr->formalize(session_info))) { LOG_WARN("formalize current expr failed", K(ret)); } LOG_DEBUG("succ to create to char expr", K(dst_type)); } } } else { OZ(ObRawExprUtils::create_cast_expr(expr_factory, src_expr, dst_type, func_expr, session_info)); CK(OB_NOT_NULL(func_expr)); } return ret; } int ObRawExprUtils::resolve_op_expr_implicit_cast(ObRawExprFactory& expr_factory, const ObSQLSessionInfo* session_info, ObItemType op_type, ObRawExpr*& sub_expr1, ObRawExpr*& sub_expr2) { int ret = OB_SUCCESS; if (OB_ISNULL(sub_expr1) || OB_ISNULL(sub_expr2)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get null expr", K(ret), K(sub_expr1), K(sub_expr2)); } else { ObSysFunRawExpr* new_expr = NULL; ObSysFunRawExpr* new_expr2 = NULL; ObObjType r_type1 = ObMaxType; ObObjType r_type2 = ObMaxType; ObObjType r_type3 = ObMaxType; r_type1 = sub_expr1->get_result_type().get_type(); r_type2 = sub_expr2->get_result_type().get_type(); // formalize to get expr's type if (OB_SUCC(ret) && !ob_is_valid_obj_o_type(r_type1)) { if (OB_FAIL(sub_expr1->formalize(session_info))) { LOG_WARN("expr fail to formalize"); } else if (!ob_is_valid_obj_o_type(r_type1 = sub_expr1->get_result_type().get_type())) { RESOLVE_ORALCE_IMLICIT_CAST_WARN_OR_ERR(OB_OBJ_TYPE_ERROR, OB_OBJ_TYPE_ERROR); LOG_WARN("invalid oracle type after formalize type1", K(r_type1), K(*sub_expr1)); } } if (OB_SUCC(ret) && !ob_is_valid_obj_o_type(r_type2)) { if (OB_FAIL(sub_expr2->formalize(session_info))) { LOG_WARN("expr fail to formalize"); } else if (!ob_is_valid_obj_o_type(r_type2 = sub_expr2->get_result_type().get_type())) { RESOLVE_ORALCE_IMLICIT_CAST_WARN_OR_ERR(OB_OBJ_TYPE_ERROR, OB_OBJ_TYPE_ERROR); LOG_WARN("invalid oracle type after formalize type1", K(r_type2), K(*sub_expr2)); } } r_type1 = ObLobType == r_type1 ? ObLongTextType : r_type1; r_type2 = ObLobType == r_type2 ? ObLongTextType : r_type2; if (OB_SUCC(ret) && share::is_oracle_mode()) { // compare lob type date in oracle mode not allowed. if (OB_UNLIKELY(ObLongTextType == r_type1 || ObLongTextType == r_type2) && IS_COMPARISON_OP(op_type)) { ret = OB_ERR_INVALID_TYPE_FOR_OP; LOG_WARN("can't calculate with lob type in oracle mode", K(ret), K(r_type1), K(r_type2), K(op_type)); } } if (OB_SUCC(ret)) { ObObjOType type1 = ob_obj_type_to_oracle_type(r_type1); ObObjOType type2 = ob_obj_type_to_oracle_type(r_type2); if (type1 >= ObOMaxType || type2 >= ObOMaxType) { LOG_WARN("INVALID ORACLE TYPE", K(type1), K(type2), K(*sub_expr1), K(*sub_expr2)); RESOLVE_ORALCE_IMLICIT_CAST_WARN_OR_ERR(OB_OBJ_TYPE_ERROR, OB_ERR_INVALID_TYPE_FOR_OP); } else if (ObONullType == type1 || ObONullType == type2) { LOG_DEBUG("No need to cast with null", K(type1), K(type2)); } else { ImplicitCastDirection dir = ImplicitCastDirection::IC_NOT_SUPPORT; ObObjType middle_type = ObMaxType; ObObjTypeClass tc1 = OBJ_O_TYPE_TO_CLASS[type1]; ObObjTypeClass tc2 = OBJ_O_TYPE_TO_CLASS[type2]; switch (op_type) { case T_OP_CNN: case T_OP_LIKE: { /* for non-string data type: select c1||c2 from tab; => cast(c1 as varchar)||cast(c2 as varchar) */ bool cast_left = true; bool cast_right = true; bool has_nstring = ob_is_nstring_type(r_type1) || ob_is_nstring_type(r_type2); if (ob_is_string_or_lob_type(r_type1) && ob_is_nstring_type(r_type1) == has_nstring) { cast_left = false; } if (ob_is_string_or_lob_type(r_type2) && ob_is_nstring_type(r_type2) == has_nstring) { cast_right = false; } if (T_OP_LIKE == op_type) { if (ob_is_rowid_tc(r_type1) && ob_is_string_tc(r_type2)) { cast_left = true; cast_right = false; } else if (ob_is_string_tc(r_type1) && ob_is_rowid_tc(r_type2)) { cast_right = true; cast_left = false; } } if (cast_left && cast_right) { dir = ImplicitCastDirection::IC_TO_MIDDLE_TYPE; middle_type = has_nstring ? ObNVarchar2Type : ObVarcharType; } else if (cast_left) { dir = ImplicitCastDirection::IC_A_TO_B; r_type2 = has_nstring ? ObNVarchar2Type : ObVarcharType; } else if (cast_right) { dir = ImplicitCastDirection::IC_B_TO_A; r_type1 = has_nstring ? ObNVarchar2Type : ObVarcharType; } else { dir = ImplicitCastDirection::IC_NO_CAST; } break; } case T_OP_ADD: { if (ob_is_oracle_datetime_tc(r_type1)) { if (ob_is_numeric_type(r_type2)) { dir = ImplicitCastDirection::IC_NO_CAST; } else if (ob_is_string_tc(r_type2)) { r_type3 = ObNumberType; dir = ImplicitCastDirection::IC_B_TO_C; } } else if (ob_is_oracle_datetime_tc(r_type2)) { if (ob_is_numeric_type(r_type1)) { dir = ImplicitCastDirection::IC_NO_CAST; } else if (ob_is_string_tc(r_type1)) { r_type3 = ObNumberType; dir = ImplicitCastDirection::IC_A_TO_C; } } if (ob_is_raw_tc(r_type1)) { if (ob_is_string_tc(r_type2)) { dir = ImplicitCastDirection::IC_NO_CAST; } } else if (ob_is_raw_tc(r_type2)) { if (ob_is_string_tc(r_type1)) { dir = ImplicitCastDirection::IC_NO_CAST; } } if (ImplicitCastDirection::IC_NOT_SUPPORT != dir) { break; } } case T_OP_MINUS: { if (ob_is_oracle_datetime_tc(r_type1)) { if (ob_is_numeric_type(r_type2)) { dir = ImplicitCastDirection::IC_NO_CAST; } else if (ob_is_string_tc(r_type2)) { r_type3 = ObNumberType; dir = ImplicitCastDirection::IC_B_TO_C; } else if (ob_is_oracle_datetime_tc(r_type2)) { dir = ImplicitCastDirection::IC_NO_CAST; } } else if (ob_is_oracle_datetime_tc(r_type2)) { dir = ImplicitCastDirection::IC_NO_CAST; } if (ob_is_raw_tc(r_type1)) { if (ob_is_string_tc(r_type2)) { dir = ImplicitCastDirection::IC_NO_CAST; } } else if (ob_is_raw_tc(r_type2)) { if (ob_is_string_tc(r_type1)) { dir = ImplicitCastDirection::IC_NO_CAST; } } if (ImplicitCastDirection::IC_NOT_SUPPORT != dir) { break; } } case T_OP_MUL: case T_OP_DIV: case T_OP_MOD: { if (ob_is_raw_tc(r_type1)) { if (ob_is_string_tc(r_type2)) { dir = ImplicitCastDirection::IC_NO_CAST; } } else if (ob_is_raw_tc(r_type2)) { if (ob_is_string_tc(r_type1)) { dir = ImplicitCastDirection::IC_NO_CAST; } } if (ImplicitCastDirection::IC_NOT_SUPPORT != dir) { break; } } // todo timestamp with tz/ltz... default: if (OB_UNLIKELY(ObLongTextType == r_type1 || ObLongTextType == r_type2)) { /* lob type return warning */ } else { middle_type = ObNumberType; dir = OB_OBJ_IMPLICIT_CAST_DIRECTION_FOR_ORACLE[type1][type2]; if ((ImplicitCastDirection::IC_B_TO_C == dir && ob_is_nchar(r_type1)) || (ImplicitCastDirection::IC_A_TO_C == dir && ob_is_nchar(r_type2))) { // nchar and varchar2, convert varchar to nvarchar2 r_type3 = ObNVarchar2Type; } } break; } // when cast raw to char implicitly, it is cast to varchar actually. if (ImplicitCastDirection::IC_A_TO_B == dir && ob_is_raw(r_type1) && ObCharType == r_type2) { r_type3 = ObVarcharType; dir = ImplicitCastDirection::IC_A_TO_C; } if (ob_is_interval_tc(r_type1) || ob_is_interval_tc(r_type2)) { dir = ImplicitCastDirection::IC_NO_CAST; } LOG_DEBUG( "Molly ORACLE IMPLICIT CAST DIR", K(dir), K(type1), K(type2), K(r_type3), K(*sub_expr1), K(*sub_expr2)); ObExprResType dest_type; switch (dir) { case ImplicitCastDirection::IC_NO_CAST: { // int is number(38) in oracle, when number div number, the result can be decimal. // So we add cast int as number b4 do div if (tc1 == ObIntTC && tc2 == ObIntTC && op_type == T_OP_DIV) { ObAccuracy acc = ObAccuracy::DDL_DEFAULT_ACCURACY2[1][ObNumberType]; dest_type.set_precision(acc.get_precision()); dest_type.set_scale(acc.get_scale()); dest_type.set_collation_level(CS_LEVEL_NUMERIC); dest_type.set_type(ObNumberType); if (OB_FAIL( resolve_op_expr_add_implicit_cast(expr_factory, session_info, sub_expr1, dest_type, new_expr))) { LOG_WARN("create cast expr for implicit failed", K(ret)); } else if (OB_FAIL(resolve_op_expr_add_implicit_cast( expr_factory, session_info, sub_expr2, dest_type, new_expr2))) { LOG_WARN("create cast expr for implicit failed", K(ret)); } else if (OB_ISNULL(new_expr) || OB_ISNULL(new_expr2)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpect null expr", K(ret)); } else if (OB_FAIL(new_expr->add_flag(IS_INNER_ADDED_EXPR))) { LOG_WARN("failed to add flag", K(ret)); } else if (OB_FAIL(new_expr2->add_flag(IS_INNER_ADDED_EXPR))) { LOG_WARN("failed to add flag", K(ret)); } else { sub_expr1 = new_expr; sub_expr2 = new_expr2; } } break; } case ImplicitCastDirection::IC_A_TO_B: { ObAccuracy acc = (ObNumberType == r_type2 ? ObAccuracy::DDL_DEFAULT_ACCURACY2[1][r_type2] : ObAccuracy::MAX_ACCURACY2[1][r_type2]); dest_type.set_precision(acc.get_precision()); dest_type.set_scale(acc.get_scale()); dest_type.set_type(r_type2); if (OB_FAIL( resolve_op_expr_add_implicit_cast(expr_factory, session_info, sub_expr1, dest_type, new_expr))) { LOG_WARN("create cast expr for implicit failed", K(ret)); } else if (OB_ISNULL(new_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpect null expr", K(ret)); } else if (OB_FAIL(new_expr->add_flag(IS_INNER_ADDED_EXPR))) { LOG_WARN("failed to add flag", K(ret)); } else { sub_expr1 = new_expr; } break; } case ImplicitCastDirection::IC_B_TO_A: { ObAccuracy acc = (ObNumberType == r_type1 ? ObAccuracy::DDL_DEFAULT_ACCURACY2[1][r_type1] : ObAccuracy::MAX_ACCURACY2[1][r_type1]); dest_type.set_precision(acc.get_precision()); dest_type.set_scale(acc.get_scale()); // dest_type.set_collation_level(CS_LEVEL_NUMERIC); dest_type.set_type(r_type1); if (OB_FAIL( resolve_op_expr_add_implicit_cast(expr_factory, session_info, sub_expr2, dest_type, new_expr))) { LOG_WARN("create cast expr for implicit failed", K(ret)); } else if (OB_ISNULL(new_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpect null expr", K(ret)); } else { sub_expr2 = new_expr; } break; } case ImplicitCastDirection::IC_A_TO_C: { ObAccuracy acc = (ObNumberType == r_type3 ? ObAccuracy::DDL_DEFAULT_ACCURACY2[1][r_type3] : ObAccuracy::MAX_ACCURACY2[1][r_type3]); dest_type.set_precision(acc.get_precision()); dest_type.set_scale(acc.get_scale()); dest_type.set_type(r_type3); if (OB_FAIL( resolve_op_expr_add_implicit_cast(expr_factory, session_info, sub_expr1, dest_type, new_expr))) { LOG_WARN("create cast expr for implicit failed", K(ret)); } else if (OB_ISNULL(new_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpect null expr", K(ret)); } else if (OB_FAIL(new_expr->add_flag(IS_INNER_ADDED_EXPR))) { LOG_WARN("failed to add flag", K(ret)); } else { sub_expr1 = new_expr; } break; } case ImplicitCastDirection::IC_B_TO_C: { ObAccuracy acc = (ObNumberType == r_type3 ? ObAccuracy::DDL_DEFAULT_ACCURACY2[1][r_type3] : ObAccuracy::MAX_ACCURACY2[1][r_type3]); dest_type.set_precision(acc.get_precision()); dest_type.set_scale(acc.get_scale()); dest_type.set_type(r_type3); if (OB_FAIL( resolve_op_expr_add_implicit_cast(expr_factory, session_info, sub_expr2, dest_type, new_expr))) { LOG_WARN("create cast expr for implicit failed", K(ret)); } else if (OB_ISNULL(new_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpect null expr", K(ret)); } else if (OB_FAIL(new_expr->add_flag(IS_INNER_ADDED_EXPR))) { LOG_WARN("failed to add flag", K(ret)); } else { sub_expr2 = new_expr; } break; } case ImplicitCastDirection::IC_TO_MIDDLE_TYPE: { ObAccuracy acc = (ObNumberType == middle_type ? ObAccuracy::DDL_DEFAULT_ACCURACY2[1][middle_type] : ObAccuracy::MAX_ACCURACY2[1][middle_type]); dest_type.set_precision(acc.get_precision()); dest_type.set_scale(acc.get_scale()); dest_type.set_collation_level(CS_LEVEL_NUMERIC); dest_type.set_type(middle_type); ObObjTypeClass middle_tc = OBJ_O_TYPE_TO_CLASS[middle_type]; // optimization: only need to cast string type to number type if (middle_type == ObNumberType) { if (ObStringTC == tc1 && (ObIntTC == tc2 || ObFloatTC == tc2 || ObDoubleTC == tc2 || ObNumberTC == tc2)) { if (OB_FAIL( ObRawExprUtils::create_cast_expr(expr_factory, sub_expr1, dest_type, new_expr, session_info))) { LOG_WARN("create cast expr for implicit failed", K(ret)); } else if (OB_ISNULL(new_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpect null expr", K(ret)); } else if (OB_FAIL(new_expr->add_flag(IS_INNER_ADDED_EXPR))) { LOG_WARN("failed to add flag", K(ret)); } else { sub_expr1 = new_expr; } } else if (ObStringTC == tc2 && (ObIntTC == tc1 || ObFloatTC == tc1 || ObDoubleTC == tc1 || ObNumberTC == tc1)) { if (OB_FAIL(ObRawExprUtils::create_cast_expr( expr_factory, sub_expr2, dest_type, new_expr2, session_info))) { LOG_WARN("create cast expr for implicit failed", K(ret)); } else if (OB_ISNULL(new_expr2)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpect null expr", K(ret)); } else if (OB_FAIL(new_expr2->add_flag(IS_INNER_ADDED_EXPR))) { LOG_WARN("failed to add flag", K(ret)); } else { sub_expr2 = new_expr2; } } else { LOG_WARN("create cast expr for implicit failed unexpected TO_MIDDLE_TYPE", K(tc1), K(tc2)); } } else { if (middle_tc != tc1) { if (OB_FAIL(resolve_op_expr_add_implicit_cast( expr_factory, session_info, sub_expr1, dest_type, new_expr))) { LOG_WARN("create cast expr for implicit failed", K(ret)); } else if (OB_ISNULL(new_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpect null expr", K(ret)); } else if (OB_FAIL(new_expr->add_flag(IS_INNER_ADDED_EXPR))) { LOG_WARN("failed to add flag", K(ret)); } else { sub_expr1 = new_expr; } } if (middle_tc != tc2) { if (OB_FAIL(resolve_op_expr_add_implicit_cast( expr_factory, session_info, sub_expr2, dest_type, new_expr2))) { LOG_WARN("create cast expr for implicit failed", K(ret)); } else if (OB_ISNULL(new_expr2)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpect null expr", K(ret)); } else if (OB_FAIL(new_expr2->add_flag(IS_INNER_ADDED_EXPR))) { LOG_WARN("failed to add flag", K(ret)); } else { sub_expr2 = new_expr2; } } } break; } case ImplicitCastDirection::IC_NOT_SUPPORT: { // ObString type1_str = ObString(ob_obj_type_str(r_type1)); // ObString type2_str = ObString(ob_obj_type_str(r_type2)); // return warning or error when can't do implicite datatype convert bool is_error = (session_info != NULL && ((session_info->get_sql_mode() & SMO_ERROR_ON_RESOLVE_CAST) > 0)) || (sub_expr1->get_result_type().is_blob() || sub_expr2->get_result_type().is_blob() || sub_expr1->get_result_type().is_blob_locator() || sub_expr2->get_result_type().is_blob_locator()); if (is_error) { ret = OB_ERR_INVALID_TYPE_FOR_OP; LOG_USER_ERROR(OB_ERR_INVALID_TYPE_FOR_OP, ob_obj_type_str(r_type1), ob_obj_type_str(r_type2)); } else { LOG_USER_WARN(OB_ERR_INVALID_TYPE_FOR_OP, ob_obj_type_str(r_type1), ob_obj_type_str(r_type2)); } LOG_WARN("expr get oracle implicit cast direction failed", K(is_error)); break; } } } } } return ret; } int ObRawExprUtils::resolve_op_expr_for_oracle_implicit_cast( ObRawExprFactory& expr_factory, const ObSQLSessionInfo* session_info, ObOpRawExpr*& b_expr) { int ret = OB_SUCCESS; ObRawExpr* sub_expr1 = NULL; ObRawExpr* sub_expr2 = NULL; sub_expr1 = b_expr->get_param_expr(0); sub_expr2 = b_expr->get_param_expr(1); if (OB_ISNULL(sub_expr1) || OB_ISNULL(sub_expr2)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get null expr", K(ret), K(sub_expr1), K(sub_expr2)); } else if (T_OP_ROW == sub_expr1->get_expr_type() || T_OP_ROW == sub_expr2->get_expr_type()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get T_OP_ROW expr", K(ret), K(*sub_expr1), K(*sub_expr2)); } else { if (!sub_expr1->is_query_ref_expr() && sub_expr2->is_query_ref_expr()) { // t1.c1 =any (select c1 from t2) ObQueryRefRawExpr* query_ref_expr = static_cast(sub_expr2); ObSelectStmt* query_stmt = query_ref_expr->get_ref_stmt(); ObRawExpr* select_expr = NULL; if (OB_ISNULL(query_stmt)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret), K(query_stmt)); } else if (OB_UNLIKELY(1 != query_stmt->get_select_item_size())) { ret = OB_ERR_INVALID_COLUMN_NUM; LOG_USER_ERROR(OB_ERR_INVALID_COLUMN_NUM, 1L); LOG_WARN("query_ref_expr should have 1 output column", K(query_ref_expr->get_output_column())); } else if (OB_ISNULL(select_expr = query_stmt->get_select_item(0).expr_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret), K(select_expr)); } else if (OB_FAIL(resolve_op_expr_implicit_cast( expr_factory, session_info, b_expr->get_expr_type(), sub_expr1, select_expr))) { LOG_WARN("failed to resolve_op_expr_implicit_cast", K(ret)); } else if (OB_ISNULL(select_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpect null expr", K(ret)); } else { query_stmt->get_select_item(0).expr_ = select_expr; ObIArray& column_types = query_ref_expr->get_column_types(); column_types.reset(); if (OB_FAIL(column_types.push_back(select_expr->get_result_type()))) { LOG_WARN("add column type failed", K(ret)); } } } else if (sub_expr1->is_query_ref_expr() && sub_expr2->is_query_ref_expr()) { // (select c1 from t2 where t2.c1=1) =any (select c1 from t2) ObQueryRefRawExpr* query_ref_expr1 = static_cast(sub_expr1); ObQueryRefRawExpr* query_ref_expr2 = static_cast(sub_expr2); ObSelectStmt* query_stmt1 = query_ref_expr1->get_ref_stmt(); ObSelectStmt* query_stmt2 = query_ref_expr2->get_ref_stmt(); ObRawExpr* select_expr1 = NULL; ObRawExpr* select_expr2 = NULL; if (OB_ISNULL(query_stmt1) || OB_ISNULL(query_stmt2)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret), K(query_stmt1), K(query_stmt2)); } else if (query_stmt1->get_select_item_size() != query_stmt2->get_select_item_size()) { ret = OB_ERR_INVALID_COLUMN_NUM; LOG_WARN("query expr should same output column", K(query_ref_expr1->get_output_column()), K(query_ref_expr2->get_output_column())); } else { ObIArray& column_types1 = query_ref_expr1->get_column_types(); column_types1.reset(); ObIArray& column_types2 = query_ref_expr2->get_column_types(); column_types2.reset(); for (int64_t i = 0; OB_SUCC(ret) && i < query_stmt1->get_select_item_size(); ++i) { if (OB_ISNULL(select_expr1 = query_stmt1->get_select_item(i).expr_) || OB_ISNULL(select_expr2 = query_stmt2->get_select_item(i).expr_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret), K(select_expr1), K(select_expr2)); } else if (OB_FAIL(resolve_op_expr_implicit_cast( expr_factory, session_info, b_expr->get_expr_type(), select_expr1, select_expr2))) { LOG_WARN("failed to resolve_op_expr_implicit_cast", K(ret)); } else if (OB_ISNULL(select_expr1) || OB_ISNULL(select_expr2)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpect null expr", K(ret)); } else if (OB_FAIL(column_types1.push_back(select_expr1->get_result_type()))) { LOG_WARN("add column type failed", K(ret)); } else if (OB_FAIL(column_types2.push_back(select_expr2->get_result_type()))) { LOG_WARN("add column type failed", K(ret)); } else { query_stmt1->get_select_item(i).expr_ = select_expr1; query_stmt2->get_select_item(i).expr_ = select_expr2; } } } } else { if (OB_FAIL(resolve_op_expr_implicit_cast( expr_factory, session_info, b_expr->get_expr_type(), sub_expr1, sub_expr2))) { LOG_WARN("failed to resolve_op_expr_implicit_cast", K(ret)); } else if (OB_FAIL(b_expr->replace_param_expr(0, sub_expr1))) { LOG_WARN("failed to replace_param_expr", K(ret)); } else if (OB_FAIL(b_expr->replace_param_expr(1, sub_expr2))) { LOG_WARN("failed to replace_param_expr", K(ret)); } } } return ret; } int ObRawExprUtils::resolve_op_exprs_for_oracle_implicit_cast( ObRawExprFactory& expr_factory, const ObSQLSessionInfo* session_info, ObIArray& op_exprs) { int ret = OB_SUCCESS; if (session_info == NULL) { LOG_WARN("can't get compatibility mode from session_info", K(session_info)); } else { ObOpRawExpr* b_expr = NULL; for (int64_t i = 0; OB_SUCC(ret) && i < op_exprs.count(); i++) { b_expr = op_exprs.at(i); if (OB_ISNULL(b_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get null expr", K(ret)); } else if (b_expr->get_param_count() != 2) { // TODO Molly case when LOG_WARN("IMPLICIT UNEXPECTED BEXPR", K(*b_expr)); } else if (OB_FAIL(resolve_op_expr_for_oracle_implicit_cast(expr_factory, session_info, b_expr))) { LOG_WARN("IMPLICIT UNEXPECTED BEXPR", K(*b_expr)); } } } return ret; } int ObRawExprUtils::function_alias(ObRawExprFactory& expr_factory, ObSysFunRawExpr*& expr) { int ret = OB_SUCCESS; int64_t decimal = 10; int64_t binary = 2; int64_t octal = 8; if (OB_ISNULL(expr)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(expr)); } else if (0 == expr->get_func_name().case_compare("bin")) { // bin(N) is equivalent to CONV(N,10,2) ObConstRawExpr* from_base = NULL; ObConstRawExpr* to_base = NULL; if (OB_FAIL(ObRawExprUtils::build_const_int_expr(expr_factory, ObIntType, decimal, from_base))) { LOG_WARN("failed to create expr", K(ret)); } else if (OB_FAIL(ObRawExprUtils::build_const_int_expr(expr_factory, ObIntType, binary, to_base))) { LOG_WARN("failed to create expr", K(ret)); } else if (OB_UNLIKELY(1 != expr->get_param_count())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid param count", K(expr->get_param_count())); } else if (OB_FAIL(expr->add_param_expr(from_base))) { LOG_WARN("fail to add param expr", K(from_base)); } else if (OB_FAIL(expr->add_param_expr(to_base))) { LOG_WARN("fail to add param expr", K(to_base)); } else { expr->set_func_name("conv"); } } else if (0 == expr->get_func_name().case_compare("oct")) { // oct(N) is equivalent to CONV(N,10,8) ObConstRawExpr* from_base = NULL; ObConstRawExpr* to_base = NULL; if (OB_FAIL(ObRawExprUtils::build_const_int_expr(expr_factory, ObIntType, decimal, from_base))) { LOG_WARN("failed to create expr", K(ret)); } else if (OB_FAIL(ObRawExprUtils::build_const_int_expr(expr_factory, ObIntType, octal, to_base))) { LOG_WARN("failed to create expr", K(ret)); } else if (OB_UNLIKELY(1 != expr->get_param_count())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid param count", K(expr->get_param_count())); } else if (OB_FAIL(expr->add_param_expr(from_base))) { LOG_WARN("fail to add param expr", K(from_base), K(ret)); } else if (OB_FAIL(expr->add_param_expr(to_base))) { LOG_WARN("fail to add param expr", K(to_base), K(ret)); } else { expr->set_func_name("conv"); } } else if (0 == expr->get_func_name().case_compare("lcase")) { // lcase is synonym for lower expr->set_func_name("lower"); } else if (0 == expr->get_func_name().case_compare("ucase")) { // ucase is synonym for upper expr->set_func_name("upper"); } else if (0 == expr->get_func_name().case_compare("power")) { // don't alias "power" to "pow" in oracle mode, because oracle has no // "pow" function. if (!share::is_oracle_mode()) { expr->set_func_name("pow"); } } else if (0 == expr->get_func_name().case_compare("ws")) { // ws is synonym for word_segment expr->set_func_name("word_segment"); } else { } return ret; } int ObRawExprUtils::make_raw_expr_from_str(const char* expr_str, const int64_t buf_len, ObExprResolveContext& resolve_ctx, ObRawExpr*& expr, ObIArray& columns, ObIArray& sys_vars, ObIArray* sub_query_info, ObIArray& aggr_exprs, ObIArray& win_exprs) { int ret = OB_SUCCESS; ObSqlString sql_str; ParseResult parse_result; ObParser parser(resolve_ctx.expr_factory_.get_allocator(), SMO_DEFAULT); if (OB_ISNULL(expr_str) || OB_ISNULL(sub_query_info)) { ret = OB_INVALID_ARGUMENT; _LOG_WARN("expr_str is %p, sub_query_info = %p", expr_str, sub_query_info); } else if (OB_FAIL(sql_str.append_fmt("SELECT %.*s", static_cast(buf_len), expr_str))) { LOG_WARN("fail to concat string", K(expr_str), K(ret)); } else if (OB_FAIL(parser.parse(sql_str.string(), parse_result))) { _OB_LOG(WARN, "parse: %p, %p, %p, msg=[%s], start_col_=[%d], end_col_[%d], " "line_[%d], yycolumn[%d], yylineno_[%d]", parse_result.yyscan_info_, parse_result.result_tree_, parse_result.malloc_pool_, parse_result.error_msg_, parse_result.start_col_, parse_result.end_col_, parse_result.line_, parse_result.yycolumn_, parse_result.yylineno_); } else { if (OB_UNLIKELY(OB_LOGGER.get_log_level() >= OB_LOG_LEVEL_DEBUG)) { LOG_DEBUG("", "parser result", SJ(ObParserResultPrintWrapper(*parse_result.result_tree_))); } ParseNode* stmt_node = NULL; ParseNode* select_node = NULL; ParseNode* select_expr_list = NULL; ParseNode* select_expr = NULL; ParseNode* parsed_expr = NULL; stmt_node = parse_result.result_tree_; if (NULL == stmt_node) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("internal arg is not correct", KP(stmt_node)); } else if (T_STMT_LIST != stmt_node->type_) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("internal arg is not correct", K(stmt_node->type_)); } if (OB_SUCC(ret)) { select_node = stmt_node->children_[0]; if (NULL == select_node) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("internal arg is not correct", KP(select_node)); } else if (T_SELECT != select_node->type_) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("internal arg is not correct", K(select_node->type_)); } } if (OB_SUCC(ret)) { select_expr_list = select_node->children_[PARSE_SELECT_SELECT]; if (NULL == select_expr_list) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("internal arg is not correct", KP(select_expr_list)); } else if (T_PROJECT_LIST != select_expr_list->type_) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("internal arg is not correct", K(select_expr_list->type_)); } } if (OB_SUCC(ret)) { select_expr = select_expr_list->children_[0]; if (NULL == select_expr) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("internal arg is not correct", KP(select_expr)); } else if (T_PROJECT_STRING != select_expr->type_) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("internal arg is not correct", K(select_expr->type_)); } } if (OB_SUCC(ret)) { parsed_expr = select_expr->children_[0]; if (OB_ISNULL(parsed_expr)) { LOG_ERROR("internal arg is not correct", KP(parsed_expr)); } } if (OB_SUCC(ret)) { ObArray op_exprs; ObSEArray user_var_exprs; ObRawExprResolverImpl expr_resolver(resolve_ctx); // generate raw expr if (OB_FAIL(expr_resolver.resolve(parsed_expr, expr, columns, sys_vars, *sub_query_info, aggr_exprs, win_exprs, op_exprs, user_var_exprs))) { _LOG_WARN("failed to resolve expr tree, err=%d", ret); } } // destroy syntax tree parser.free_result(parse_result); } return ret; } int ObRawExprUtils::make_raw_expr_from_str(const ObString& expr_str, ObExprResolveContext& resolve_ctx, ObRawExpr*& expr, ObIArray& column, ObIArray& sys_vars, ObIArray* sub_query_info, ObIArray& aggr_exprs, ObIArray& win_exprs) { int ret = OB_SUCCESS; if (OB_ISNULL(sub_query_info)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(sub_query_info)); } else if (OB_FAIL(make_raw_expr_from_str(expr_str.ptr(), expr_str.length(), resolve_ctx, expr, column, sys_vars, sub_query_info, aggr_exprs, win_exprs))) { LOG_WARN("fail to make_raw_expr_from_str", K(ret)); } return ret; } int ObRawExprUtils::parse_default_expr_from_str( const ObString& expr_str, ObCollationType expr_str_cs_type, ObIAllocator& allocator, const ParseNode*& node) { int ret = OB_SUCCESS; ObSqlString sql_str; ParseResult parse_result; ObSQLMode sql_mode = SMO_DEFAULT; if (share::is_oracle_mode()) { sql_mode = DEFAULT_ORACLE_MODE | SMO_ORACLE; } ObSQLParser parser(allocator, sql_mode); MEMSET(&parse_result, 0, sizeof(ParseResult)); parse_result.malloc_pool_ = &allocator; parse_result.pl_parse_info_.is_pl_parse_ = true; parse_result.pl_parse_info_.is_pl_parse_expr_ = true; parse_result.sql_mode_ = sql_mode; parse_result.charset_info_ = ObCharset::get_charset(expr_str_cs_type); parse_result.is_not_utf8_connection_ = ObCharset::is_valid_collation(expr_str_cs_type) ? (ObCharset::charset_type_by_coll(expr_str_cs_type) != CHARSET_UTF8MB4) : false; if (OB_FAIL(sql_str.append_fmt("DO %.*s", expr_str.length(), expr_str.ptr()))) { LOG_WARN("failed to concat expr str", K(expr_str), K(ret)); } else if (OB_FAIL(parser.parse(sql_str.string().ptr(), sql_str.string().length(), parse_result))) { _OB_LOG(WARN, "parse: %p, %p, %p, msg=[%s], start_col_=[%d], end_col_[%d], " "line_[%d], yycolumn[%d], yylineno_[%d]", parse_result.yyscan_info_, parse_result.result_tree_, parse_result.malloc_pool_, parse_result.error_msg_, parse_result.start_col_, parse_result.end_col_, parse_result.line_, parse_result.yycolumn_, parse_result.yylineno_); } else { if (OB_UNLIKELY(OB_LOGGER.get_log_level() >= OB_LOG_LEVEL_DEBUG)) { LOG_DEBUG("", "parser result", SJ(ObParserResultPrintWrapper(*parse_result.result_tree_))); } ParseNode* expr_node = NULL; if (OB_ISNULL(expr_node = parse_result.result_tree_->children_[0])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("failed to parse default expr node", K(ret), K(expr_str)); } else if (OB_UNLIKELY(T_DEFAULT != expr_node->type_) || OB_UNLIKELY(1 != expr_node->num_child_) || OB_ISNULL(expr_node->children_) || OB_ISNULL(expr_node->children_[0])) { ret = OB_ERR_UNEXPECTED; LOG_WARN( "expr node type is illegal", K(ret), K(expr_node->type_), K(expr_node->num_child_), K(expr_node->children_)); } else { node = expr_node->children_[0]; } } return ret; } int ObRawExprUtils::parse_expr_node_from_str(const ObString& expr_str, ObIAllocator& allocator, const ParseNode*& node) { int ret = OB_SUCCESS; ObSqlString sql_str; ParseResult parse_result; ObSQLMode sql_mode = SMO_DEFAULT; if (share::is_oracle_mode()) { sql_mode = DEFAULT_ORACLE_MODE | SMO_ORACLE; } ObParser parser(allocator, sql_mode); if (OB_FAIL(sql_str.append_fmt("SELECT %.*s FROM DUAL", expr_str.length(), expr_str.ptr()))) { LOG_WARN("fail to concat string", K(expr_str), K(ret)); } else if (OB_FAIL(parser.parse(sql_str.string(), parse_result))) { _OB_LOG(WARN, "parse: %p, %p, %p, msg=[%s], start_col_=[%d], end_col_[%d], " "line_[%d], yycolumn[%d], yylineno_[%d]", parse_result.yyscan_info_, parse_result.result_tree_, parse_result.malloc_pool_, parse_result.error_msg_, parse_result.start_col_, parse_result.end_col_, parse_result.line_, parse_result.yycolumn_, parse_result.yylineno_); } else { if (OB_UNLIKELY(OB_LOGGER.get_log_level() >= OB_LOG_LEVEL_DEBUG)) { LOG_DEBUG("", "parser result", SJ(ObParserResultPrintWrapper(*parse_result.result_tree_))); } ParseNode* stmt_node = NULL; ParseNode* select_node = NULL; ParseNode* select_expr_list = NULL; ParseNode* select_expr = NULL; stmt_node = parse_result.result_tree_; if (NULL == stmt_node) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("internal arg is not correct", KP(stmt_node)); } else if (T_STMT_LIST != stmt_node->type_) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("internal arg is not correct", K(stmt_node->type_)); } if (OB_SUCC(ret)) { select_node = stmt_node->children_[0]; if (NULL == select_node) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("internal arg is not correct", KP(select_node)); } else if (T_SELECT != select_node->type_) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("internal arg is not correct", K(select_node->type_)); } } if (OB_SUCC(ret)) { select_expr_list = select_node->children_[PARSE_SELECT_SELECT]; if (NULL == select_expr_list) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("internal arg is not correct", KP(select_expr_list)); } else if (T_PROJECT_LIST != select_expr_list->type_) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("internal arg is not correct", K(select_expr_list->type_)); } } if (OB_SUCC(ret)) { select_expr = select_expr_list->children_[0]; if (NULL == select_expr) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("internal arg is not correct", KP(select_expr)); } else if (T_PROJECT_STRING != select_expr->type_) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("internal arg is not correct", K(select_expr->type_)); } } if (OB_SUCC(ret)) { node = select_expr->children_[0]; } } return ret; } int ObRawExprUtils::parse_bool_expr_node_from_str( const common::ObString& expr_str, common::ObIAllocator& allocator, const ParseNode*& node) { int ret = OB_SUCCESS; ObSqlString sql_str; ParseResult parse_result; ObSQLMode sql_mode = SMO_DEFAULT; if (share::is_oracle_mode()) { sql_mode = DEFAULT_ORACLE_MODE | SMO_ORACLE; } ObParser parser(allocator, sql_mode); if (OB_FAIL(sql_str.append_fmt("SELECT 1 FROM DUAL WHERE %.*s", expr_str.length(), expr_str.ptr()))) { LOG_WARN("fail to concat string", K(expr_str), K(ret)); } else if (OB_FAIL(parser.parse(sql_str.string(), parse_result))) { _OB_LOG(WARN, "parse: %p, %p, %p, msg=[%s], start_col_=[%d], end_col_[%d], " "line_[%d], yycolumn[%d], yylineno_[%d]", parse_result.yyscan_info_, parse_result.result_tree_, parse_result.malloc_pool_, parse_result.error_msg_, parse_result.start_col_, parse_result.end_col_, parse_result.line_, parse_result.yycolumn_, parse_result.yylineno_); } else { if (OB_UNLIKELY(OB_LOGGER.get_log_level() >= OB_LOG_LEVEL_DEBUG)) { LOG_DEBUG("", "parser result", SJ(ObParserResultPrintWrapper(*parse_result.result_tree_))); } ParseNode* stmt_node = NULL; ParseNode* select_node = NULL; ParseNode* where_node = NULL; ParseNode* expr_node = NULL; stmt_node = parse_result.result_tree_; if (NULL == stmt_node) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("internal arg is not correct", KP(stmt_node)); } else if (T_STMT_LIST != stmt_node->type_) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("internal arg is not correct", K(stmt_node->type_)); } if (OB_SUCC(ret)) { select_node = stmt_node->children_[0]; if (NULL == select_node) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("internal arg is not correct", KP(select_node)); } else if (T_SELECT != select_node->type_) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("internal arg is not correct", K(select_node->type_)); } } if (OB_SUCC(ret)) { where_node = select_node->children_[PARSE_SELECT_WHERE]; if (NULL == where_node) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("internal arg is not correct", KP(where_node)); } else if (T_WHERE_CLAUSE != where_node->type_) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("internal arg is not correct", K(where_node->type_)); } } if (OB_SUCC(ret)) { expr_node = where_node->children_[0]; if (NULL == expr_node) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("internal arg is not correct", KP(expr_node)); } } if (OB_SUCC(ret)) { node = expr_node; } } return ret; } int ObRawExprUtils::build_generated_column_expr(const ObString& expr_str, ObRawExprFactory& expr_factory, const ObSQLSessionInfo& session_info, ObRawExpr*& expr, ObIArray& columns, const ObSchemaChecker* schema_checker) { int ret = OB_SUCCESS; const ParseNode* node = NULL; if (OB_FAIL(parse_expr_node_from_str(expr_str, expr_factory.get_allocator(), node))) { LOG_WARN("parse expr node from string failed", K(ret), K(expr_str)); } else if (OB_ISNULL(node)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("node is null"); } else if (OB_FAIL(build_generated_column_expr(expr_factory, session_info, *node, expr, columns, schema_checker))) { LOG_WARN("build generated column expr failed", K(ret)); } return ret; } int ObRawExprUtils::build_generated_column_expr(const ObString& expr_str, ObRawExprFactory& expr_factory, const ObSQLSessionInfo& session_info, const ObTableSchema& table_schema, ObRawExpr*& expr, const ObSchemaChecker* schema_checker) { int ret = OB_SUCCESS; const ParseNode* node = NULL; ObSEArray columns; const ObColumnSchemaV2* col_schema = NULL; if (OB_FAIL(parse_expr_node_from_str(expr_str, expr_factory.get_allocator(), node))) { LOG_WARN("parse expr node from string failed", K(ret)); } else if (OB_ISNULL(node)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("node is null"); } else if (OB_FAIL(build_generated_column_expr(expr_factory, session_info, *node, expr, columns, schema_checker))) { LOG_WARN("build generated column expr failed", K(ret), K(expr_str)); } for (int64_t i = 0; OB_SUCC(ret) && i < columns.count(); i++) { const ObQualifiedName& q_name = columns.at(i); if (OB_UNLIKELY(!q_name.database_name_.empty())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid generated column name", K(q_name)); } else if (!q_name.tbl_name_.empty() && !ObCharset::case_insensitive_equal(q_name.tbl_name_, table_schema.get_table_name_str())) { ret = OB_ERR_BAD_TABLE; LOG_USER_ERROR(OB_ERR_BAD_TABLE, q_name.tbl_name_.length(), q_name.tbl_name_.ptr()); } else if (OB_ISNULL(col_schema = table_schema.get_column_schema(q_name.col_name_))) { ret = OB_ERR_KEY_COLUMN_DOES_NOT_EXITS; LOG_USER_ERROR(OB_ERR_KEY_COLUMN_DOES_NOT_EXITS, q_name.col_name_.length(), q_name.col_name_.ptr()); } else if (OB_UNLIKELY(col_schema->is_generated_column())) { ret = OB_ERR_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN; LOG_USER_ERROR(OB_ERR_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN, "Generated column in column expression"); } else if (OB_FAIL(ObRawExprUtils::init_column_expr(*col_schema, *q_name.ref_expr_))) { LOG_WARN("init column expr failed", K(ret), K(q_name)); } else { q_name.ref_expr_->set_ref_id(table_schema.get_table_id(), col_schema->get_column_id()); } } if (OB_SUCC(ret)) { if (OB_FAIL(expr->formalize(&session_info))) { LOG_WARN("formalize expr failed", K(ret), KPC(expr)); } } return ret; } int ObRawExprUtils::build_check_constraint_expr(ObRawExprFactory& expr_factory, const ObSQLSessionInfo& session_info, const ParseNode& node, ObRawExpr*& expr, common::ObIArray& columns) { int ret = OB_SUCCESS; ObArray sys_vars; ObArray aggr_exprs; ObArray win_exprs; ObArray sub_query_info; ObArray op_exprs; if (OB_FAIL(build_raw_expr(expr_factory, session_info, node, expr, columns, sys_vars, aggr_exprs, win_exprs, sub_query_info, op_exprs))) { LOG_WARN("fail to get collation_connection", K(ret)); } else if (OB_UNLIKELY(expr->has_flag(CNT_SUB_QUERY))) { ret = OB_ERR_INVALID_SUBQUERY_USE; LOG_WARN("subquery not allowed here", K(ret)); } else if (OB_UNLIKELY(expr->has_flag(CNT_AGG))) { ret = OB_ERR_GROUP_FUNC_NOT_ALLOWED; LOG_WARN("group function is not allowed here", K(ret)); } else if (OB_UNLIKELY(expr->has_flag(CNT_ROWNUM) || expr->has_flag(CNT_PSEUDO_COLUMN))) { ret = OB_ERR_CBY_PSEUDO_COLUMN_NOT_ALLOWED; LOG_WARN("Specified pseudo column or operator not allowed here", K(ret), K(expr->has_flag(CNT_ROWNUM)), K(expr->has_flag(CNT_PSEUDO_COLUMN))); } else if (OB_UNLIKELY(expr->has_flag(CNT_WINDOW_FUNC))) { ret = OB_ERR_INVALID_WINDOW_FUNC_USE; } else if (OB_UNLIKELY(sys_vars.count() > 0 || expr->has_flag(CNT_CUR_TIME) || expr->has_flag(CNT_STATE_FUNC))) { ret = OB_ERR_DATE_OR_SYS_VAR_CANNOT_IN_CHECK_CST; LOG_WARN("date or system variable wrongly specified in CHECK constraint", K(ret), K(expr->has_flag(CNT_CUR_TIME)), K(expr->has_flag(CNT_STATE_FUNC))); } else { /*do nothing*/ } return ret; } int ObRawExprUtils::build_generated_column_expr(ObRawExprFactory& expr_factory, const ObSQLSessionInfo& session_info, const ParseNode& node, ObRawExpr*& expr, ObIArray& columns, const ObSchemaChecker* schema_checker) { int ret = OB_SUCCESS; ObArray sys_vars; ObArray aggr_exprs; ObArray win_exprs; ObArray sub_query_info; ObArray op_exprs; if (OB_FAIL(build_raw_expr(expr_factory, session_info, const_cast(schema_checker), T_NONE_SCOPE, NULL, NULL, NULL, node, expr, columns, sys_vars, aggr_exprs, win_exprs, sub_query_info, op_exprs, false))) { LOG_WARN("fail to get collation_connection", K(ret)); } else if (OB_UNLIKELY(sys_vars.count() > 0)) { // todo:mysql ERROR 3102 (HY000): Expression of generated column 'column' contains a disallowed function. // mysql error code: ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED // format: Expression of generated column '%s' contains a disallowed function ret = OB_NOT_SUPPORTED; LOG_USER_ERROR(OB_NOT_SUPPORTED, "use variables in generated column"); } else if (OB_UNLIKELY(sub_query_info.count() > 0)) { ret = OB_NOT_SUPPORTED; LOG_USER_ERROR(OB_NOT_SUPPORTED, "use subquery in generated column"); } else if (OB_UNLIKELY(aggr_exprs.count() > 0)) { ret = OB_ERR_INVALID_GROUP_FUNC_USE; LOG_USER_ERROR(OB_ERR_INVALID_GROUP_FUNC_USE); } else if (OB_UNLIKELY(win_exprs.count() > 0)) { ret = OB_NOT_SUPPORTED; LOG_USER_ERROR(OB_NOT_SUPPORTED, "use window function in generated column"); } else if (lib::is_oracle_mode()) { // generated column contain only two types of access obj:sysfunc expression and column expression // only column expression will be handled in the upper function call, // so sysfunc expression should be filtered in this function and can't return to the upper function call ObSEArray, 2> ref_sys_exprs; ObSEArray real_columns; for (int64_t i = 0; OB_SUCC(ret) && i < columns.count(); i++) { const ObQualifiedName& q_name = columns.at(i); if (q_name.is_sys_func()) { ObRawExpr* sys_func = q_name.access_idents_.at(0).sys_func_expr_; CK(OB_NOT_NULL(sys_func)); for (int64_t i = 0; OB_SUCC(ret) && i < ref_sys_exprs.count(); ++i) { OZ(ObRawExprUtils::replace_ref_column(sys_func, ref_sys_exprs.at(i).first, ref_sys_exprs.at(i).second)); } OZ(q_name.access_idents_.at(0).sys_func_expr_->check_param_num()); OZ(ObRawExprUtils::replace_ref_column(expr, q_name.ref_expr_, sys_func)); OZ(ref_sys_exprs.push_back(std::pair(q_name.ref_expr_, sys_func))); } else { OZ(real_columns.push_back(q_name), q_name, i); } } if (OB_SUCC(ret) && real_columns.count() != columns.count()) { columns.reuse(); OZ(columns.assign(real_columns), real_columns); } } return ret; } int ObRawExprUtils::build_raw_expr(ObRawExprFactory& expr_factory, const ObSQLSessionInfo& session_info, const ParseNode& node, ObRawExpr*& expr, ObIArray& columns, ObIArray& sys_vars, ObIArray& aggr_exprs, ObIArray& win_exprs, ObIArray& sub_query_info, common::ObIArray& op_exprs, bool is_prepare_protocol /*= false*/) { int ret = OB_SUCCESS; if (OB_FAIL(build_raw_expr(expr_factory, session_info, NULL, T_NONE_SCOPE, NULL, NULL, NULL, node, expr, columns, sys_vars, aggr_exprs, win_exprs, sub_query_info, op_exprs, is_prepare_protocol))) { LOG_WARN("failed to build raw expr", K(ret)); } return ret; } int ObRawExprUtils::build_raw_expr(ObRawExprFactory& expr_factory, const ObSQLSessionInfo& session_info, ObSchemaChecker* schema_checker, ObStmtScope current_scope, ObStmt* stmt, const ParamStore* param_list, common::ObIArray>* external_param_info, const ParseNode& node, ObRawExpr*& expr, ObIArray& columns, ObIArray& sys_vars, ObIArray& aggr_exprs, ObIArray& win_exprs, ObIArray& sub_query_info, ObIArray& op_exprs, bool is_prepare_protocol /*= false*/) { int ret = OB_SUCCESS; ObCollationType collation_connection = CS_TYPE_INVALID; ObCharsetType character_set_connection = CHARSET_INVALID; if (OB_FAIL(session_info.get_collation_connection(collation_connection))) { LOG_WARN("fail to get collation_connection", K(ret)); } else if (OB_FAIL(session_info.get_character_set_connection(character_set_connection))) { LOG_WARN("fail to get character_set_connection", K(ret)); } else { ObExprResolveContext ctx(expr_factory, session_info.get_timezone_info(), OB_NAME_CASE_INVALID); ctx.dest_collation_ = collation_connection; ctx.connection_charset_ = character_set_connection; ctx.param_list_ = param_list; ctx.is_extract_param_type_ = !is_prepare_protocol; // when prepare do not extract ctx.external_param_info_ = external_param_info; ctx.current_scope_ = current_scope; ctx.stmt_ = stmt; ctx.schema_checker_ = schema_checker; ctx.session_info_ = &session_info; ObSEArray user_var_exprs; ObRawExprResolverImpl expr_resolver(ctx); if (OB_FAIL(session_info.get_name_case_mode(ctx.case_mode_))) { LOG_WARN("fail to get name case mode", K(ret)); } else if (OB_FAIL(expr_resolver.resolve( &node, expr, columns, sys_vars, sub_query_info, aggr_exprs, win_exprs, op_exprs, user_var_exprs))) { LOG_WARN("resolve expr failed", K(ret)); } else { /*do nothing*/ } } return ret; } int ObRawExprUtils::build_generated_column_expr(const ObString& expr_str, ObRawExprFactory& expr_factory, const ObSQLSessionInfo& session_info, uint64_t table_id, const ObTableSchema& table_schema, const ObColumnSchemaV2& gen_col_schema, ObRawExpr*& expr, const ObSchemaChecker* schema_checker) { int ret = OB_SUCCESS; ObArray columns; const ObColumnSchemaV2* col_schema = NULL; if (OB_FAIL(build_generated_column_expr(expr_str, expr_factory, session_info, expr, columns, schema_checker))) { LOG_WARN("build generated column expr failed", K(ret)); } for (int64_t i = 0; OB_SUCC(ret) && i < columns.count(); ++i) { const ObQualifiedName& q_name = columns.at(i); if (OB_UNLIKELY(!q_name.database_name_.empty()) || OB_UNLIKELY(!q_name.tbl_name_.empty())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid generated column name", K(q_name)); } else if (OB_ISNULL(col_schema = table_schema.get_column_schema(q_name.col_name_))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("column schema is null"); } else if (OB_FAIL(init_column_expr(*col_schema, *q_name.ref_expr_))) { LOG_WARN("init column expr failed", K(ret)); } else { q_name.ref_expr_->set_ref_id(table_id, col_schema->get_column_id()); } } if (OB_SUCC(ret)) { if (OB_FAIL(expr->formalize(&session_info))) { LOG_WARN("formalize expr failed", K(ret)); } } if (OB_SUCC(ret) && !gen_col_schema.is_hidden()) { // only generated column defined by user need to do cast. ObExprResType expected_type; expected_type.set_meta(gen_col_schema.get_meta_type()); expected_type.set_accuracy(gen_col_schema.get_accuracy()); expected_type.set_result_flag(calc_column_result_flag(gen_col_schema)); if (ObRawExprUtils::need_column_conv(expected_type, *expr)) { if (OB_FAIL(build_column_conv_expr(expr_factory, &gen_col_schema, expr, &session_info))) { LOG_WARN("create cast expr failed", K(ret)); } } } return ret; } // compare two raw expressions bool ObRawExprUtils::is_same_raw_expr(const ObRawExpr* src, const ObRawExpr* dst) { bool is_same = false; if ((NULL == src && NULL != dst) || (NULL != src && NULL == dst)) { is_same = false; } else if (NULL == src && NULL == dst) { is_same = true; } else { if (!src->same_as(*dst)) { is_same = false; } else { is_same = true; } } return is_same; } int ObRawExprUtils::replace_all_ref_column( ObRawExpr*& raw_expr, const common::ObIArray& exprs, int64_t& offset) { int ret = OB_SUCCESS; if (OB_ISNULL(raw_expr)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(raw_expr)); } else if (offset >= exprs.count()) { LOG_WARN("beyond the index", K(offset), K(exprs.count())); } else if (T_REF_COLUMN == raw_expr->get_expr_type()) { LOG_DEBUG("replace leaf node", K(*raw_expr), K(*exprs.at(offset)), K(offset)); raw_expr = exprs.at(offset); ++offset; } else { int64_t N = raw_expr->get_param_count(); for (int64_t i = 0; OB_SUCC(ret) && i < N && offset < exprs.count(); ++i) { ObRawExpr*& child_expr = raw_expr->get_param_expr(i); if (OB_FAIL(replace_all_ref_column(child_expr, exprs, offset))) { LOG_WARN("replace reference column failed", K(ret)); } } // end for } return ret; } // if %expr_factory is not NULL, will deep copy %to expr. default behavior is shallow copy int ObRawExprUtils::replace_ref_column( ObRawExpr*& raw_expr, ObRawExpr* from, ObRawExpr* to, ObRawExprFactory* expr_factory) { int ret = OB_SUCCESS; if (OB_ISNULL(raw_expr) || OB_ISNULL(from) || OB_ISNULL(to)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(raw_expr), K(from), K(to)); } else if (raw_expr == to) { // do nothing // in case: parent(child) = to (from) // replace as: parenet(child) = to (to) } else if (raw_expr == from) { if (NULL != expr_factory) { ObRawExpr* new_to = NULL; if (OB_FAIL(copy_expr(*expr_factory, to, new_to, COPY_REF_DEFAULT))) { LOG_WARN("copy expr failed", K(ret), K(*to)); } else if (OB_ISNULL(new_to)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("copied expr is NULL", K(ret), KP(new_to)); } else { raw_expr = new_to; } } else { raw_expr = to; LOG_DEBUG("replace leaf node", K(*from), K(*to), K(from), K(to)); } } else if (raw_expr->is_query_ref_expr()) { ObSelectStmt* ref_stmt = static_cast(raw_expr)->get_ref_stmt(); ObSEArray relation_exprs; if (OB_ISNULL(ref_stmt)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret), K(ref_stmt)); } else if (OB_FAIL(ref_stmt->get_relation_exprs(relation_exprs))) { LOG_WARN("failed to get relation exprs", K(ret)); } else if (OB_FAIL(SMART_CALL(replace_ref_column(relation_exprs, from, to)))) { LOG_WARN("replace reference column failed", K(ret)); } } else { int64_t N = raw_expr->get_param_count(); for (int64_t i = 0; OB_SUCC(ret) && i < N; ++i) { ObRawExpr*& child_expr = raw_expr->get_param_expr(i); if (OB_FAIL(SMART_CALL(replace_ref_column(child_expr, from, to, expr_factory)))) { LOG_WARN("replace reference column failed", K(ret)); } } // end for } return ret; } int ObRawExprUtils::replace_ref_column(ObIArray& exprs, ObRawExpr* from, ObRawExpr* to) { int ret = OB_SUCCESS; bool is_stack_overflow = false; if (OB_FAIL(check_stack_overflow(is_stack_overflow))) { LOG_WARN("check stack overflow failed", K(ret)); } else if (is_stack_overflow) { ret = OB_SIZE_OVERFLOW; LOG_WARN("too deep recursive", K(ret)); } else if (OB_ISNULL(from) || OB_ISNULL(to)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(from), K(to), K(ret)); } else { ObRawExpr* tmp_raw_expr = NULL; for (int64_t i = 0; OB_SUCC(ret) && i < exprs.count(); ++i) { ObRawExpr*& raw_expr = tmp_raw_expr; if (OB_FAIL(exprs.at(i, raw_expr))) { LOG_WARN("failed to get raw expr", K(i), K(ret)); } else if (OB_FAIL(SMART_CALL(replace_ref_column(raw_expr, from, to)))) { LOG_WARN("failed to replace_ref_column", K(from), K(to), K(ret)); } else { /*do nothing*/ } } } return ret; } bool ObRawExprUtils::all_column_exprs(const common::ObIArray& exprs) { bool all_column = true; for (int64_t i = 0; all_column && i < exprs.count(); ++i) { if (OB_ISNULL(exprs.at(i))) { all_column = false; } else if (!exprs.at(i)->is_column_ref_expr()) { all_column = false; } else { } } return all_column; } int ObRawExprUtils::extract_column_exprs(const ObRawExpr* raw_expr, ObIArray& column_exprs) { int ret = OB_SUCCESS; if (NULL == raw_expr) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid raw expr", K(ret), K(raw_expr)); } else { if (T_REF_COLUMN == raw_expr->get_expr_type()) { ret = add_var_to_array_no_dup(column_exprs, const_cast(raw_expr)); } else { int64_t N = raw_expr->get_param_count(); for (int64_t i = 0; OB_SUCC(ret) && i < N; ++i) { ret = extract_column_exprs(raw_expr->get_param_expr(i), column_exprs); } } } return ret; } int ObRawExprUtils::extract_column_exprs(const ObIArray& exprs, ObIArray& column_exprs) { int ret = OB_SUCCESS; for (int64_t i = 0; OB_SUCC(ret) && i < exprs.count(); ++i) { if (OB_ISNULL(exprs.at(i))) { ret = OB_INVALID_ARGUMENT; LOG_WARN("Expr is NULL", K(ret), K(i)); } else if (OB_FAIL(extract_column_exprs(exprs.at(i), column_exprs))) { LOG_WARN("Failed to extract column exprs", K(ret)); } else { } // do nothing } return ret; } int ObRawExprUtils::extract_column_ids(const ObIArray& exprs, common::ObIArray& column_ids) { int ret = OB_SUCCESS; for (int64_t i = 0; OB_SUCC(ret) && i < exprs.count(); i++) { if (OB_ISNULL(exprs.at(i))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret)); } else if (OB_FAIL(extract_column_ids(exprs.at(i), column_ids))) { LOG_WARN("failed to extract column ids", K(ret)); } else { /*do nothing*/ } } return ret; } int ObRawExprUtils::extract_column_ids(const ObRawExpr* raw_expr, common::ObIArray& column_ids) { int ret = OB_SUCCESS; if (NULL == raw_expr) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid raw expr", K(ret), K(raw_expr)); } else { if (T_REF_COLUMN == raw_expr->get_expr_type()) { ret = add_var_to_array_no_dup(column_ids, static_cast(raw_expr)->get_column_id()); } else { int64_t N = raw_expr->get_param_count(); for (int64_t i = 0; OB_SUCC(ret) && i < N; ++i) { ret = SMART_CALL(extract_column_ids(raw_expr->get_param_expr(i), column_ids)); } } } return ret; } int ObRawExprUtils::extract_table_ids(const ObRawExpr* raw_expr, common::ObIArray& table_ids) { int ret = OB_SUCCESS; if (NULL == raw_expr) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid raw expr", K(ret), K(raw_expr)); } else { if (T_REF_COLUMN == raw_expr->get_expr_type()) { ret = add_var_to_array_no_dup(table_ids, static_cast(raw_expr)->get_table_id()); } else { int64_t N = raw_expr->get_param_count(); for (int64_t i = 0; OB_SUCC(ret) && i < N; ++i) { ret = extract_table_ids(raw_expr->get_param_expr(i), table_ids); } } } return ret; } int ObRawExprUtils::cnt_current_level_aggr_expr(const ObRawExpr* expr, int32_t cur_level, bool& cnt_aggr) { int ret = OB_SUCCESS; if (OB_ISNULL(expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr is null"); } else if (expr->has_flag(IS_AGG) && expr->get_expr_level() == cur_level) { cnt_aggr = true; } else if (expr->has_flag(IS_SUB_QUERY)) { const ObQueryRefRawExpr* query_ref = static_cast(expr); const ObSelectStmt* subquery = NULL; if ((subquery = query_ref->get_ref_stmt()) != NULL) { if (OB_FAIL(cnt_current_level_aggr_expr(subquery, cur_level, cnt_aggr))) { LOG_WARN("get generalized column in subquery failed", K(ret)); } } else { ret = OB_ERR_UNEXPECTED; LOG_WARN("Invalid query ref expr", K(*expr), K(ret)); } } else if ((expr->has_flag(CNT_AGG) || expr->has_flag(CNT_SUB_QUERY)) && !expr->is_set_op_expr()) { for (int64_t i = 0; OB_SUCC(ret) && !cnt_aggr && i < expr->get_param_count(); ++i) { if (OB_FAIL(cnt_current_level_aggr_expr(expr->get_param_expr(i), cur_level, cnt_aggr))) { LOG_WARN("cnt current level aggr expr failed", K(ret)); } } } return ret; } int ObRawExprUtils::cnt_current_level_aggr_expr(const ObDMLStmt* stmt, int32_t column_level, bool& cnt_aggr) { int ret = OB_SUCCESS; ObArray relation_exprs; ObArray child_stmts; cnt_aggr = false; if (OB_ISNULL(stmt)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("stmt is null"); } else if (OB_FAIL(stmt->get_relation_exprs(relation_exprs))) { LOG_WARN("get stmt relation exprs failed", K(ret)); } else if (OB_FAIL(stmt->get_from_subquery_stmts(child_stmts))) { LOG_WARN("get child stmt failed", K(ret)); } for (int64_t i = 0; OB_SUCC(ret) && !cnt_aggr && i < relation_exprs.count(); ++i) { if (OB_FAIL(cnt_current_level_aggr_expr(relation_exprs.at(i), column_level, cnt_aggr))) { LOG_WARN("get generalized column in expr tree failed", K(ret)); } } for (int64_t i = 0; OB_SUCC(ret) && !cnt_aggr && i < child_stmts.count(); ++i) { if (OB_FAIL(cnt_current_level_aggr_expr(child_stmts.at(i), column_level, cnt_aggr))) { LOG_WARN("get generalized column in stmt failed", K(ret)); } } return ret; } int ObRawExprUtils::try_add_cast_expr_above(ObRawExprFactory* expr_factory, const ObSQLSessionInfo* session, ObRawExpr& src_expr, const ObExprResType& dst_type, ObRawExpr*& new_expr) { int ret = OB_SUCCESS; ObCastMode cm = CM_NONE; OZ(ObSQLUtils::get_default_cast_mode(false, /* explicit_cast */ 0, /* result_flag */ session, cm)); OZ(try_add_cast_expr_above(expr_factory, session, src_expr, dst_type, cm, new_expr)); return ret; } int ObRawExprUtils::try_add_cast_expr_above(ObRawExprFactory* expr_factory, const ObSQLSessionInfo* session, ObRawExpr& expr, const ObExprResType& dst_type, const ObCastMode& cm, ObRawExpr*& new_expr) { int ret = OB_SUCCESS; new_expr = &expr; bool need_cast = false; const ObExprResType& src_type = expr.get_result_type(); CK(OB_NOT_NULL(session) && OB_NOT_NULL(expr_factory)); OZ(ObRawExprUtils::check_need_cast_expr(src_type, dst_type, need_cast)); if (OB_SUCC(ret) && need_cast) { if (T_FUN_SYS_CAST == expr.get_expr_type() && expr.has_flag(IS_OP_OPERAND_IMPLICIT_CAST)) { ret = OB_ERR_UNEXPECTED; #ifdef DEBUG LOG_ERROR("try to add implicit cast again, check if type deduction is correct", K(ret), K(expr), K(dst_type), K(session->get_current_query_string())); #else LOG_WARN("try to add implicit cast again, check if type deduction is correct", K(ret), K(expr), K(dst_type), K(session->get_current_query_string())); #endif } else { // setup zerofill cm // eg: select concat(cast(c_zf as char(10)), cast(col_no_zf as char(10))) from t1; ObCastMode cm_zf = cm; if (expr.get_result_type().has_result_flag(OB_MYSQL_ZEROFILL_FLAG)) { cm_zf |= CM_ZERO_FILL; } ObSysFunRawExpr* cast_expr = NULL; OZ(ObRawExprUtils::create_cast_expr(*expr_factory, &expr, dst_type, cast_expr, session, false, cm_zf)); CK(OB_NOT_NULL(new_expr = dynamic_cast(cast_expr))); } LOG_DEBUG("in try_add_cast", K(ret), K(dst_type), K(cm)); } return ret; } int ObRawExprUtils::create_cast_expr(ObRawExprFactory& expr_factory, ObRawExpr* src_expr, const ObExprResType& dst_type, ObSysFunRawExpr*& func_expr, const ObSQLSessionInfo* session, bool use_def_cm, ObCastMode cm) { int ret = OB_SUCCESS; CK(OB_NOT_NULL(src_expr)); CK(OB_NOT_NULL(session)); if (OB_SUCC(ret) && use_def_cm) { OZ(ObSQLUtils::get_default_cast_mode(false, /* explicit_cast */ 0, /* result_flag */ session, cm)); } if (OB_SUCC(ret)) { if (session->use_static_typing_engine()) { const ObExprResType& src_type = src_expr->get_result_type(); bool need_extra_cast_for_src_type = false; bool need_extra_cast_for_dst_type = false; need_extra_cast(src_type, dst_type, need_extra_cast_for_src_type, need_extra_cast_for_dst_type); // extra cast expr: cast non-utf8 to utf8 ObSysFunRawExpr* extra_cast = NULL; if (need_extra_cast_for_src_type) { ObExprResType src_type_utf8; OZ(setup_extra_cast_utf8_type(src_type, src_type_utf8)); OZ(create_real_cast_expr(expr_factory, src_expr, src_type_utf8, extra_cast, session)); OZ(create_real_cast_expr(expr_factory, extra_cast, dst_type, func_expr, session)); } else if (need_extra_cast_for_dst_type) { ObExprResType dst_type_utf8; OZ(setup_extra_cast_utf8_type(dst_type, dst_type_utf8)); OZ(create_real_cast_expr(expr_factory, src_expr, dst_type_utf8, extra_cast, session)); OZ(create_real_cast_expr(expr_factory, extra_cast, dst_type, func_expr, session)); } else { OZ(create_real_cast_expr(expr_factory, src_expr, dst_type, func_expr, session)); } if (NULL != extra_cast) { OX(extra_cast->set_extra(cm)); OZ(extra_cast->add_flag(IS_INNER_ADDED_EXPR)); } CK(OB_NOT_NULL(func_expr)); OX(func_expr->set_extra(cm)); OZ(func_expr->add_flag(IS_INNER_ADDED_EXPR)); } else { OZ(create_real_cast_expr(expr_factory, src_expr, dst_type, func_expr, session)); OZ(func_expr->add_flag(IS_INNER_ADDED_EXPR)); } OZ(func_expr->formalize(session)); } return ret; } void ObRawExprUtils::need_extra_cast(const ObExprResType& src_type, const ObExprResType& dst_type, bool& need_extra_cast_for_src_type, bool& need_extra_cast_for_dst_type) { need_extra_cast_for_src_type = false; need_extra_cast_for_dst_type = false; const ObCharsetType& src_cs = ObCharset::charset_type_by_coll(src_type.get_collation_type()); const ObCharsetType& dst_cs = ObCharset::charset_type_by_coll(dst_type.get_collation_type()); bool nonstr_to_str = !src_type.is_string_type() && dst_type.is_string_type(); bool str_to_nonstr = src_type.is_string_type() && !dst_type.is_string_type(); if (src_type.is_null() || dst_type.is_null()) { // do nothing } else if (str_to_nonstr) { if (CHARSET_BINARY != src_cs && ObCharset::get_default_charset() != src_cs) { need_extra_cast_for_src_type = true; } } else if (nonstr_to_str) { if (CHARSET_BINARY != dst_cs && ObCharset::get_default_charset() != dst_cs) { need_extra_cast_for_dst_type = true; } } } int ObRawExprUtils::setup_extra_cast_utf8_type(const ObExprResType& type, ObExprResType& utf8_type) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!type.is_string_type())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("in type must be string type", K(ret), K(type)); } else { utf8_type = type; utf8_type.set_collation_type(ObCharset::get_system_collation()); if (ObNVarchar2Type == type.get_type()) { utf8_type.set_type(ObVarcharType); } else if (ObNCharType == type.get_type()) { utf8_type.set_type(ObCharType); } } return ret; } int ObRawExprUtils::erase_inner_added_exprs(ObRawExpr* src_expr, ObRawExpr*& out_expr) { int ret = OB_SUCCESS; CK(OB_NOT_NULL(src_expr)); OX(out_expr = src_expr); if (OB_SUCC(ret) && src_expr->has_flag(IS_INNER_ADDED_EXPR)) { switch (src_expr->get_expr_type()) { case T_OP_BOOL: case T_FUN_SYS_REMOVE_CONST: { CK(1 == src_expr->get_param_count()); OZ(erase_inner_added_exprs(src_expr->get_param_expr(0), out_expr)); break; } case T_FUN_SYS_CAST: { CK(2 == src_expr->get_param_count()); OZ(erase_inner_added_exprs(src_expr->get_param_expr(0), out_expr)); break; } default: { break; } } } return ret; } int ObRawExprUtils::erase_operand_implicit_cast(ObRawExpr* src, ObRawExpr*& out) { int ret = OB_SUCCESS; CK(OB_NOT_NULL(src)); if (OB_SUCC(ret)) { if (src->has_flag(IS_OP_OPERAND_IMPLICIT_CAST)) { OZ(erase_operand_implicit_cast(src->get_param_expr(0), out)); } else { for (int64_t i = 0; i < src->get_param_count() && OB_SUCC(ret); i++) { OZ(erase_operand_implicit_cast(src->get_param_expr(i), src->get_param_expr(i))); } if (OB_SUCC(ret)) { out = src; } } } return ret; } int ObRawExprUtils::create_to_type_expr(ObRawExprFactory& expr_factory, ObRawExpr* src_expr, const ObObjType& dst_type, ObSysFunRawExpr*& to_type, ObSQLSessionInfo* session_info) { int ret = OB_SUCCESS; ObExprOperator* op = NULL; if (OB_FAIL(expr_factory.create_raw_expr(T_FUN_SYS_TO_TYPE, to_type))) { LOG_WARN("create to_type expr failed", K(ret)); } else if (OB_ISNULL(to_type)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("to_type is null"); } else if (OB_FAIL(to_type->add_param_expr(src_expr))) { LOG_WARN("add param expr failed", K(ret)); } else if (OB_ISNULL(op = to_type->get_op())) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_ERROR("allocate expr operator failed"); } else { to_type->set_func_name(N_TO_TYPE); ObExprToType* to_type_op = static_cast(op); to_type_op->set_expect_type(dst_type); if (OB_FAIL(to_type->formalize(session_info))) { LOG_WARN("formalize to_type expr failed", K(ret)); } } return ret; } int ObRawExprUtils::create_substr_expr(ObRawExprFactory& expr_factory, ObSQLSessionInfo* session_info, ObRawExpr* first_expr, ObRawExpr* second_expr, ObRawExpr* third_expr, ObSysFunRawExpr*& out_expr) { int ret = OB_SUCCESS; if (OB_FAIL(expr_factory.create_raw_expr(T_FUN_SYS_SUBSTR, out_expr))) { LOG_WARN("create to_type expr failed", K(ret)); } else if (OB_ISNULL(out_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("to_type is null"); } else { if (NULL == third_expr) { if (OB_FAIL(out_expr->set_param_exprs(first_expr, second_expr))) { LOG_WARN("add param expr failed", K(ret)); } } else { if (OB_FAIL(out_expr->set_param_exprs(first_expr, second_expr, third_expr))) { LOG_WARN("add param expr failed", K(ret)); } } } if (OB_SUCC(ret) && OB_FAIL(out_expr->formalize(session_info))) { LOG_WARN("formalize to_type expr failed", K(ret)); } return ret; } int ObRawExprUtils::create_type_to_str_expr(ObRawExprFactory& expr_factory, ObRawExpr* src_expr, ObSysFunRawExpr*& out_expr, ObSQLSessionInfo* session_info, bool is_type_to_str) { int ret = OB_SUCCESS; ObExprOperator* op = NULL; ObObjType data_type = ObNullType; if (OB_ISNULL(src_expr) || OB_ISNULL(session_info)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("src_expr or session_info is NULL", KP(src_expr), KP(session_info), K(ret)); } else if (OB_UNLIKELY(!src_expr->is_terminal_expr() && !src_expr->is_sys_func_expr() && !src_expr->is_udf_expr())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("src_expr should be terminal expr or func expr", KPC(src_expr), K(ret)); } else if (FALSE_IT(data_type = src_expr->get_data_type())) { } else if (OB_UNLIKELY(!ob_is_enumset_tc(data_type))) { LOG_WARN("data_type of src_expr is invalid", K(data_type), KPC(src_expr), K(ret)); } else { ObItemType item_type = (true == is_type_to_str) ? (ObEnumType == data_type ? T_FUN_ENUM_TO_STR : T_FUN_SET_TO_STR) : (ObEnumType == data_type ? T_FUN_ENUM_TO_INNER_TYPE : T_FUN_SET_TO_INNER_TYPE); const char* func_name = (true == is_type_to_str) ? (ObEnumType == data_type ? N_ENUM_TO_STR : N_SET_TO_STR) : (ObEnumType == data_type ? N_ENUM_TO_INNER_TYPE : N_SET_TO_INNER_TYPE); if (OB_FAIL(expr_factory.create_raw_expr(item_type, out_expr))) { LOG_WARN("create out_expr expr failed", K(ret)); } else if (OB_ISNULL(out_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("created out_expr is null", K(ret)); } else if (OB_ISNULL(op = out_expr->get_op())) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_ERROR("allocate expr operator failed", K(ret)); } else { out_expr->set_func_name(ObString::make_string(func_name)); } ObConstRawExpr* col_accuracy_expr = NULL; if (OB_SUCC(ret)) { ObString str_col_accuracy; if (OB_FAIL(build_const_string_expr( expr_factory, ObVarcharType, str_col_accuracy, src_expr->get_collation_type(), col_accuracy_expr))) { LOG_WARN("fail to build type expr", K(ret)); } else if (OB_ISNULL(col_accuracy_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("col_accuracy_expr is NULL", K(ret)); } else { col_accuracy_expr->set_collation_type(src_expr->get_collation_type()); col_accuracy_expr->set_accuracy(src_expr->get_accuracy()); } } if (OB_SUCC(ret)) { ObExprTypeToStr* type_to_str = static_cast(op); const ObIArray& enum_set_values = src_expr->get_enum_set_values(); if (OB_ISNULL(type_to_str)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("failed to cast ObExprOperator* to ObExprTypeToStr*", K(ret)); } else if (OB_UNLIKELY(enum_set_values.count() < 1)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("enum_set_values is empty", K(ret)); } else if (OB_FAIL(out_expr->add_param_expr(col_accuracy_expr))) { LOG_WARN("failed to add param expr", K(ret)); } else if (OB_FAIL(out_expr->add_param_expr(src_expr))) { LOG_WARN("failed to add param expr", K(ret)); } else if (OB_FAIL(type_to_str->shallow_copy_str_values(enum_set_values))) { LOG_WARN("failed to shallow_copy_str_values", K(ret)); } else if (OB_FAIL(out_expr->formalize(session_info))) { LOG_WARN("formalize to_type expr failed", K(ret)); } else { } } } return ret; } int ObRawExprUtils::create_type_to_str_expr(ObRawExprFactory& expr_factory, ObRawExpr* src_expr, int32_t expr_level, ObSysFunRawExpr*& out_expr, ObSQLSessionInfo* session_info, bool is_type_to_str) { int ret = OB_SUCCESS; if (OB_FAIL(create_type_to_str_expr(expr_factory, src_expr, out_expr, session_info, is_type_to_str))) { LOG_WARN("failed to create type_to_str_expr", K(ret)); } else if (OB_ISNULL(out_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("null expr", K(ret)); } else if (OB_FAIL(out_expr->pull_relation_id_and_levels(expr_level))) { LOG_WARN("failed to pull_relation_id_and_levels", K(ret)); } return ret; } // init_expr are initial expressions before parameterization; // src_expr output expression after parameterization. int ObRawExprUtils::create_exec_param_expr(ObStmt* stmt, ObRawExprFactory& expr_factory, ObRawExpr*& src_expr, ObSQLSessionInfo* session_info, std::pair& init_expr) { UNUSED(session_info); int ret = OB_SUCCESS; if (OB_ISNULL(stmt)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", KP(stmt)); } else { init_expr.first = stmt->get_question_marks_count(); init_expr.second = src_expr; stmt->increase_question_marks_count(); if (OB_FAIL(create_param_expr(expr_factory, init_expr.first, src_expr, true))) { LOG_WARN("create param expr failed", K(ret)); } else if (OB_FAIL(stmt->get_exec_param_ref_exprs().push_back(src_expr))) { LOG_WARN("store param expr failed", K(ret)); } } return ret; } int ObRawExprUtils::create_param_expr( ObRawExprFactory& expr_factory, int64_t param_idx, ObRawExpr*& expr, bool is_exec_param) { int ret = OB_SUCCESS; ObConstRawExpr* c_expr = NULL; if (OB_ISNULL(expr)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("expr is null"); } else if (OB_FAIL(expr_factory.create_raw_expr(T_QUESTIONMARK, c_expr))) { LOG_WARN("create const raw expr failed", K(ret)); } else if (OB_ISNULL(c_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("const raw expr is null", K(ret)); } else { ObObjParam val; val.set_unknown(param_idx); val.set_param_meta(); c_expr->set_value(val); c_expr->set_result_type(expr->get_result_type()); if (is_exec_param) { c_expr->add_flag(IS_EXEC_PARAM); } if (ob_is_enumset_tc(expr->get_result_type().get_type())) { if (OB_FAIL(c_expr->set_enum_set_values(expr->get_enum_set_values()))) { LOG_WARN("failed to set enum_set_values", K(*expr), K(ret)); } } if (OB_SUCC(ret)) { if (OB_FAIL(c_expr->extract_info())) { LOG_WARN("extract const raw expr info failed", K(ret)); } else { expr = c_expr; } } } return ret; } int ObRawExprUtils::copy_exprs(ObRawExprFactory& expr_factory, const ObIArray& origin, ObIArray& dest, const uint64_t copy_types, bool use_new_allocator) { int ret = OB_SUCCESS; for (int64_t i = 0; OB_SUCC(ret) && i < origin.count(); i++) { ObGroupbyExpr dest_item; if (OB_FAIL(ObRawExprUtils::copy_exprs( expr_factory, origin.at(i).groupby_exprs_, dest_item.groupby_exprs_, copy_types, use_new_allocator))) { LOG_WARN("failed to copy exprs.", K(ret)); } else if (OB_FAIL(dest.push_back(dest_item))) { LOG_WARN("failed to push back into dest.", K(ret)); } else { /*do nothing.*/ } } return ret; } int ObRawExprUtils::copy_expr(ObRawExprFactory& expr_factory, const ObRawExpr* origin, ObRawExpr*& dest, const uint64_t copy_types, bool use_new_allocator) { int ret = OB_SUCCESS; bool need_copy = true; bool copy_share_expr = (COPY_REF_SHARED == copy_types) || use_new_allocator; if (NULL == origin) { need_copy = false; dest = NULL; } else if (copy_share_expr) { // current expr should be copied no matter it is shared or not } else if (origin->is_column_ref_expr() || origin->is_query_ref_expr() || origin->is_aggr_expr() || origin->is_win_func_expr() || origin->is_set_op_expr() || is_pseudo_column_like_expr(*origin) || origin->has_flag(IS_SHARED_REF) || origin->has_flag(IS_PARAM)) { // a shared expr is not copied in default mode dest = const_cast(origin); need_copy = false; } if (OB_SUCC(ret) && need_copy) { // deep copy here ObRawExpr::ExprClass expr_class = origin->get_expr_class(); switch (expr_class) { case ObRawExpr::EXPR_QUERY_REF: { // this is not deep copy, should change !!! ObQueryRefRawExpr* dest_query_ref = NULL; const ObQueryRefRawExpr* origin_query_ref = static_cast(origin); if (OB_FAIL(expr_factory.create_raw_expr(origin->get_expr_type(), dest_query_ref)) || OB_ISNULL(dest_query_ref)) { LOG_WARN("failed to allocate raw expr", K(dest_query_ref), K(ret)); } else if (OB_FAIL(dest_query_ref->assign(*origin_query_ref))) { LOG_WARN("failed to assign query ref", K(ret)); } else { dest = dest_query_ref; } break; } case ObRawExpr::EXPR_COLUMN_REF: { ObColumnRefRawExpr* dest_column_ref = NULL; const ObColumnRefRawExpr* origin_column_ref = static_cast(origin); if (OB_FAIL(expr_factory.create_raw_expr(T_REF_COLUMN, dest_column_ref)) || OB_ISNULL(dest_column_ref)) { LOG_WARN("failed to allocate raw expr", K(dest_column_ref), K(ret)); } else if (OB_FAIL(dest_column_ref->deep_copy(expr_factory, *origin_column_ref, use_new_allocator))) { LOG_WARN("failed to deep copy column ref", K(ret)); } else { dest = dest_column_ref; } break; } case ObRawExpr::EXPR_AGGR: { ObAggFunRawExpr* dest_agg = NULL; const ObAggFunRawExpr* origin_agg = static_cast(origin); if (OB_FAIL(expr_factory.create_raw_expr(origin->get_expr_type(), dest_agg)) || OB_ISNULL(dest_agg)) { LOG_WARN("failed to allocate raw expr", K(dest_agg), K(ret)); } else if (OB_FAIL(dest_agg->deep_copy(expr_factory, *origin_agg, COPY_REF_DEFAULT, use_new_allocator))) { LOG_WARN("failed to deep copy agg expr", K(ret)); } else { dest = dest_agg; } break; } case ObRawExpr::EXPR_CONST: { ObConstRawExpr* dest_const = NULL; const ObConstRawExpr* origin_const = static_cast(origin); if (OB_FAIL(expr_factory.create_raw_expr(origin->get_expr_type(), dest_const)) || OB_ISNULL(dest_const)) { LOG_WARN("failed to allocate raw expr", K(dest_const), K(ret)); } else if (OB_FAIL(dest_const->deep_copy(expr_factory, *origin_const, COPY_REF_DEFAULT, use_new_allocator))) { LOG_WARN("failed to deep copy const expr", K(ret)); } else { dest = dest_const; } break; } case ObRawExpr::EXPR_OPERATOR: { const ObOpRawExpr* origin_op = static_cast(origin); if (origin->is_obj_access_expr()) { const ObObjAccessRawExpr* origin_oa = static_cast(origin); ObObjAccessRawExpr* dest_oa = NULL; if (OB_FAIL(expr_factory.create_raw_expr(origin->get_expr_type(), dest_oa))) { LOG_WARN("failed to allocate raw expr", K(ret)); } else if (OB_ISNULL(dest_oa)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr is NULL", K(dest_oa), K(ret)); } else if (OB_FAIL(dest_oa->deep_copy(expr_factory, *origin_oa, COPY_REF_DEFAULT, use_new_allocator))) { LOG_WARN("failed to assign", K(*dest_oa), K(ret)); } else { dest = dest_oa; } } else if (origin->is_assoc_index_expr()) { ret = OB_NOT_SUPPORTED; } else if (T_SP_CPARAM == origin->get_expr_type()) { ret = OB_NOT_SUPPORTED; LOG_USER_ERROR(OB_NOT_SUPPORTED, "call procedure"); } else if (T_FUN_PL_INTEGER_CHECKER == origin->get_expr_type()) { ret = OB_NOT_SUPPORTED; } else { ObOpRawExpr* dest_op = NULL; if (OB_FAIL(expr_factory.create_raw_expr(origin->get_expr_type(), dest_op)) || OB_ISNULL(dest_op)) { LOG_WARN("failed to allocate raw expr", K(dest_op), K(ret)); } else if (OB_FAIL(dest_op->deep_copy(expr_factory, *origin_op, COPY_REF_DEFAULT, use_new_allocator))) { LOG_WARN("failed to deep copy op expr", K(ret)); } else { dest = dest_op; } } break; } case ObRawExpr::EXPR_CASE_OPERATOR: { ObCaseOpRawExpr* dest_case = NULL; const ObCaseOpRawExpr* origin_case = static_cast(origin); if (OB_FAIL(expr_factory.create_raw_expr(origin->get_expr_type(), dest_case)) || OB_ISNULL(dest_case)) { LOG_WARN("failed to allocate raw expr", K(dest_case), K(ret)); } else if (OB_FAIL(dest_case->deep_copy(expr_factory, *origin_case, COPY_REF_DEFAULT, use_new_allocator))) { LOG_WARN("failed to deep copy case expr", K(ret)); } else { dest = dest_case; } break; } case ObRawExpr::EXPR_SYS_FUNC: { if (T_FUN_SYS_SEQ_NEXTVAL == origin->get_expr_type()) { ObSequenceRawExpr* dest_seq = NULL; const ObSequenceRawExpr* origin_seq = static_cast(origin); if (OB_FAIL(expr_factory.create_raw_expr(origin->get_expr_type(), dest_seq))) { LOG_WARN("failed to allocate raw expr", K(dest_seq), K(ret)); } else if (OB_ISNULL(dest_seq)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr is NULL", K(dest_seq), K(ret)); } else if (OB_FAIL(dest_seq->deep_copy(expr_factory, *origin_seq, COPY_REF_DEFAULT, use_new_allocator))) { LOG_WARN("failed to deep copy sys func expr", K(ret)); } else { dest = dest_seq; } } else if (T_FUN_NORMAL_UDF == origin->get_expr_type()) { ObNormalDllUdfRawExpr* dest_nudf = NULL; const ObNormalDllUdfRawExpr* origin_nudf = static_cast(origin); if (OB_FAIL(expr_factory.create_raw_expr(origin->get_expr_type(), dest_nudf))) { LOG_WARN("failed to allocate raw expr", K(dest_nudf), K(ret)); } else if (OB_ISNULL(dest_nudf)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr is NULL", K(dest_nudf), K(ret)); } else if (OB_FAIL(dest_nudf->deep_copy(expr_factory, *origin_nudf, COPY_REF_DEFAULT, use_new_allocator))) { LOG_WARN("failed to deep copy sys func expr", K(ret)); } else { dest = dest_nudf; } } else if (T_FUN_PL_COLLECTION_CONSTRUCT == origin->get_expr_type()) { ret = OB_NOT_SUPPORTED; } else if (T_FUN_PL_OBJECT_CONSTRUCT == origin->get_expr_type()) { ret = OB_NOT_SUPPORTED; } else if (T_FUN_PL_GET_CURSOR_ATTR == origin->get_expr_type()) { ret = OB_NOT_SUPPORTED; } else if (T_FUN_PL_SQLCODE_SQLERRM == origin->get_expr_type()) { ObPLSQLCodeSQLErrmRawExpr* dest_scse = NULL; const ObPLSQLCodeSQLErrmRawExpr* origin_scse = static_cast(origin); if (OB_FAIL(expr_factory.create_raw_expr(origin->get_expr_type(), dest_scse))) { LOG_WARN("failed to allocate raw expr", K(dest_scse), K(ret)); } else if (OB_ISNULL(dest_scse)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr is NULL", K(dest_scse), K(ret)); } else if (OB_FAIL(dest_scse->deep_copy(expr_factory, *origin_scse, COPY_REF_DEFAULT, use_new_allocator))) { LOG_WARN("failed to deep copy sys func expr", K(ret)); } else { dest = dest_scse; } } else { ObSysFunRawExpr* dest_sys = NULL; const ObSysFunRawExpr* origin_sys = static_cast(origin); if (OB_FAIL(expr_factory.create_raw_expr(origin->get_expr_type(), dest_sys))) { LOG_WARN("failed to allocate raw expr", K(dest_sys), K(ret)); } else if (OB_ISNULL(dest_sys)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr is NULL", K(dest_sys), K(ret)); } else if (OB_FAIL(dest_sys->deep_copy(expr_factory, *origin_sys, COPY_REF_DEFAULT, use_new_allocator))) { LOG_WARN("failed to deep copy sys func expr", K(ret)); } else { dest = dest_sys; } } break; } case ObRawExpr::EXPR_UDF: { ret = OB_NOT_SUPPORTED; break; } case ObRawExpr::EXPR_ALIAS_REF: { ObAliasRefRawExpr* dest_alias = NULL; const ObAliasRefRawExpr* origin_alias = static_cast(origin); if (OB_FAIL(expr_factory.create_raw_expr(origin->get_expr_type(), dest_alias)) || OB_ISNULL(dest_alias)) { LOG_WARN("failed to allocate raw expr", K(dest_alias), K(ret)); } else if (OB_FAIL(dest_alias->deep_copy(expr_factory, *origin_alias, COPY_REF_DEFAULT, use_new_allocator))) { LOG_WARN("failed to copy alias", K(ret)); } else { dest = dest_alias; } break; } case ObRawExpr::EXPR_PSEUDO_COLUMN: { ObPseudoColumnRawExpr* dest_pseudo_column = NULL; const ObPseudoColumnRawExpr* origin_pseudo_column = static_cast(origin); if (OB_FAIL(expr_factory.create_raw_expr(origin->get_expr_type(), dest_pseudo_column)) || OB_ISNULL(dest_pseudo_column)) { LOG_WARN("failed to alocate raw expr", K(ret)); } else if (OB_FAIL(dest_pseudo_column->deep_copy( expr_factory, *origin_pseudo_column, COPY_REF_DEFAULT, use_new_allocator))) { LOG_WARN("failed to assign pseudo column", K(ret)); } else { dest = dest_pseudo_column; } break; } case ObRawExpr::EXPR_WINDOW: { ObWinFunRawExpr* dest_win_fun = NULL; const ObWinFunRawExpr* origin_win_fun = static_cast(origin); if (OB_FAIL(expr_factory.create_raw_expr(origin->get_expr_type(), dest_win_fun)) || OB_ISNULL(dest_win_fun)) { LOG_WARN("failed to allocate raw expr", K(dest_win_fun), K(ret)); } else if (OB_FAIL( dest_win_fun->deep_copy(expr_factory, *origin_win_fun, COPY_REF_DEFAULT, use_new_allocator))) { LOG_WARN("failed to deep copy window function", K(ret)); } else { dest = dest_win_fun; } break; } case ObRawExpr::EXPR_DOMAIN_INDEX: { ret = OB_NOT_SUPPORTED; LOG_WARN("not supported deep copy of domain index expr", K(ret)); break; } case ObRawExpr::EXPR_VAR: { ObVarRawExpr* dest_var_expr = NULL; const ObVarRawExpr* origin_var_expr = static_cast(origin); if (OB_FAIL(expr_factory.create_raw_expr(origin->get_expr_type(), dest_var_expr)) || OB_ISNULL(dest_var_expr)) { LOG_WARN("failed to allocate raw expr", K(dest_var_expr), K(ret)); } else if (OB_FAIL( dest_var_expr->deep_copy(expr_factory, *origin_var_expr, COPY_REF_DEFAULT, use_new_allocator))) { LOG_WARN("failed to deep copy var raw expr", K(ret)); } else { dest = dest_var_expr; } break; } case ObRawExpr::EXPR_SET_OP: { ObSetOpRawExpr* dest_set_op_expr = NULL; const ObSetOpRawExpr* origin_set_op_expr = static_cast(origin); if (OB_FAIL(expr_factory.create_raw_expr(origin->get_expr_type(), dest_set_op_expr)) || OB_ISNULL(dest_set_op_expr)) { LOG_WARN("failed to allocate raw expr", K(dest_set_op_expr), K(ret)); } else if (OB_FAIL(dest_set_op_expr->deep_copy( expr_factory, *origin_set_op_expr, COPY_REF_DEFAULT, use_new_allocator))) { LOG_WARN("failed to deep copy set op raw expr", K(ret)); } else { dest = dest_set_op_expr; } break; } case ObRawExpr::EXPR_INVALID_CLASS: default: // should not reach here break; } } return ret; } bool ObRawExprUtils::need_column_conv(const ObExprResType& expected_type, const ObRawExpr& expr) { int bret = true; if (expected_type.get_type() == expr.get_data_type()) { bool type_matched = false; if (expected_type.is_integer_type() || expected_type.is_temporal_type()) { type_matched = true; } else if (expected_type.get_collation_type() == expr.get_collation_type() && expected_type.get_accuracy().get_accuracy() == expr.get_accuracy().get_accuracy()) { type_matched = true; } if (type_matched) { if (expected_type.has_result_flag(OB_MYSQL_NOT_NULL_FLAG) && expr.get_result_type().has_result_flag(OB_MYSQL_NOT_NULL_FLAG)) { bret = false; } else if (!expected_type.has_result_flag(OB_MYSQL_NOT_NULL_FLAG)) { bret = false; } else { /*do nothing*/ } } } return bret; } bool ObRawExprUtils::need_column_conv(const ColumnItem& column, ObRawExpr& expr) { int bret = true; if (column.get_expr() != NULL && column.get_expr()->is_fulltext_column()) { // generated column of fulltext idnex is a inner hidden column, don't need to do column convert. bret = false; } else if (column.get_column_type() != NULL) { const ObExprResType& column_type = *column.get_column_type(); if (column_type.get_type() == expr.get_data_type() && column_type.get_collation_type() == expr.get_collation_type() && column_type.get_accuracy().get_accuracy() == expr.get_accuracy().get_accuracy()) { if (column.is_not_null() && expr.get_result_type().has_result_flag(OB_MYSQL_NOT_NULL_FLAG)) { bret = false; } else if (!column.is_not_null()) { bret = false; } else { /*do nothing*/ } } else { /*do nothing*/ } } else { /*do nothing*/ } return bret; } int ObRawExprUtils::build_column_conv_expr(ObRawExprFactory& expr_factory, const share::schema::ObColumnSchemaV2* column_schema, ObRawExpr*& expr, const ObSQLSessionInfo* session_info) { int ret = OB_SUCCESS; CK(OB_NOT_NULL(session_info)); CK(OB_NOT_NULL(column_schema)); if (OB_SUCC(ret)) { if (column_schema->is_fulltext_column()) { } else if (OB_FAIL(build_column_conv_expr(session_info, expr_factory, column_schema->get_data_type(), column_schema->get_collation_type(), column_schema->get_accuracy().get_accuracy(), column_schema->is_nullable(), NULL, NULL, expr))) { LOG_WARN("failed to build column convert expr", K(ret)); } } return ret; } int ObRawExprUtils::build_column_conv_expr(ObRawExprFactory& expr_factory, common::ObIAllocator& allocator, const ObColumnRefRawExpr& col_ref, ObRawExpr*& expr, const ObSQLSessionInfo* session_info) { int ret = OB_SUCCESS; ObString column_conv_info; const ObString& database_name = col_ref.get_database_name(); const ObString& table_name = col_ref.get_table_name(); const ObString& column_name = col_ref.get_column_name(); int64_t buff_len = database_name.length() + table_name.length() + column_name.length() + 20; char* temp_str_buf = static_cast(allocator.alloc(buff_len)); if (OB_UNLIKELY(OB_ISNULL(temp_str_buf))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to alloc memory", K(ret)); } else if (snprintf(temp_str_buf, buff_len, "\"%.*s\".\"%.*s\".\"%.*s\"", database_name.length(), database_name.ptr(), table_name.length(), table_name.ptr(), column_name.length(), column_name.ptr()) < 0) { ret = OB_SIZE_OVERFLOW; LOG_WARN("failed to generate buffer for temp_str_buf", K(ret)); } else { column_conv_info = ObString(buff_len, static_cast(strlen(temp_str_buf)), temp_str_buf); } CK(session_info); if (OB_SUCC(ret)) { if (col_ref.is_fulltext_column()) { } else if (OB_FAIL(build_column_conv_expr(session_info, expr_factory, col_ref.get_data_type(), col_ref.get_collation_type(), col_ref.get_accuracy().get_accuracy(), !col_ref.is_not_null(), &column_conv_info, &col_ref.get_enum_set_values(), expr))) { LOG_WARN("fail to build column convert expr", K(ret)); } } return ret; } int ObRawExprUtils::build_column_conv_expr(const ObSQLSessionInfo* session_info, ObRawExprFactory& expr_factory, const ObObjType& type, const ObCollationType& collation, const int64_t& accuracy, const bool& is_nullable, const common::ObString* column_conv_info, const ObIArray* type_infos, ObRawExpr*& expr) { int ret = OB_SUCCESS; ObObjType dest_type = ObLobType == type ? ObLongTextType : type; ObSysFunRawExpr* f_expr = NULL; ObConstRawExpr* is_nullable_expr = NULL; ObConstRawExpr* type_expr = NULL; ObConstRawExpr* collation_expr = NULL; ObConstRawExpr* accuracy_expr = NULL; ObConstRawExpr* column_info_expr = NULL; uint64_t def_cast_mode = 0; CK(OB_NOT_NULL(session_info)); CK(OB_NOT_NULL(expr)); ObString column_info; if (OB_NOT_NULL(column_conv_info)) { column_info = *column_conv_info; } if (OB_FAIL(ret)) { // do nothing ... } else if (OB_FAIL(expr_factory.create_raw_expr(T_FUN_COLUMN_CONV, f_expr))) { LOG_WARN("fail to create T_FUN_COLUMN_CONV raw expr", K(ret)); } else if (OB_FAIL(build_const_int_expr(expr_factory, ObInt32Type, static_cast(dest_type), type_expr))) { LOG_WARN("fail to build const int expr", K(ret)); } else if (OB_FAIL( build_const_int_expr(expr_factory, ObInt32Type, static_cast(collation), collation_expr))) { LOG_WARN("fail to build type expr", K(ret)); } else if (OB_FAIL(build_const_int_expr(expr_factory, ObIntType, accuracy, accuracy_expr))) { LOG_WARN("fail to build int expr", K(ret), K(accuracy)); } else if (OB_FAIL(build_const_int_expr(expr_factory, ObTinyIntType, is_nullable, is_nullable_expr))) { LOG_WARN("fail to build bool expr", K(ret)); } else if (OB_FAIL(build_const_string_expr( expr_factory, ObCharType, column_info, CS_TYPE_UTF8MB4_GENERAL_CI, column_info_expr))) { LOG_WARN("fail to build column info expr", K(ret)); } else if (OB_FAIL(f_expr->add_param_expr(type_expr))) { LOG_WARN("fail to add param expr", K(ret)); } else if (OB_FAIL(f_expr->add_param_expr(collation_expr))) { LOG_WARN("fail to add param expr", K(ret)); } else if (OB_FAIL(f_expr->add_param_expr(accuracy_expr))) { LOG_WARN("fail to add param expr", K(ret)); } else if (OB_FAIL(f_expr->add_param_expr(is_nullable_expr))) { LOG_WARN("fail to add param expr", K(ret)); } else if (OB_FAIL(f_expr->add_param_expr(expr))) { LOG_WARN("fail to add param expr", K(ret)); } else if (GET_MIN_CLUSTER_VERSION() >= CLUSTER_VERSION_2273 && OB_FAIL(f_expr->add_param_expr(column_info_expr))) { LOG_WARN("fail to add param expr", K(ret)); } else if (ObSQLUtils::get_default_cast_mode(false, /* explicit_cast */ 0, /* result_flag */ session_info, def_cast_mode)) { LOG_WARN("fail to get_default_cast_mode", K(ret)); } else { if (ob_is_enumset_tc(dest_type) && OB_NOT_NULL(type_infos)) { ObExprColumnConv* column_conv = NULL; ObExprOperator* op = NULL; if (OB_ISNULL(op = f_expr->get_op())) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_ERROR("allocate expr operator failed", K(ret)); } else if (OB_ISNULL(column_conv = static_cast(op))) { LOG_WARN("fail to cast ObExprOperator* to ObExprColumnConv*", K(ret)); } else if (OB_FAIL(column_conv->shallow_copy_str_values(*type_infos))) { LOG_WARN("fail to shallow_copy_str_values", K(ret)); } else if (f_expr->set_enum_set_values(*type_infos)) { LOG_WARN("fail to set_enum_set_values", K(ret)); } else { /*success*/ } } if (OB_SUCC(ret)) { f_expr->set_extra(def_cast_mode); f_expr->set_func_name(ObString::make_string(N_COLUMN_CONV)); f_expr->set_data_type(dest_type); f_expr->set_expr_type(T_FUN_COLUMN_CONV); if (expr->is_for_generated_column()) { f_expr->set_for_generated_column(); } expr = f_expr; if (OB_FAIL(expr->formalize(session_info))) { LOG_WARN("fail to extract info", K(ret)); } } } return ret; } // invoker should remember to add to stmt's expr_store to free the memory // stmt->store_expr(expr) int ObRawExprUtils::build_const_int_expr( ObRawExprFactory& expr_factory, ObObjType type, int64_t int_value, ObConstRawExpr*& expr) { int ret = OB_SUCCESS; ObConstRawExpr* c_expr = NULL; if (OB_FAIL(expr_factory.create_raw_expr(static_cast(type), c_expr))) { LOG_WARN("fail to create const raw c_expr", K(ret)); } else { ObObj obj; obj.set_int(type, int_value); c_expr->set_value(obj); expr = c_expr; } return ret; } int ObRawExprUtils::build_const_number_expr( ObRawExprFactory& expr_factory, ObObjType type, const number::ObNumber value, ObConstRawExpr*& expr) { int ret = OB_SUCCESS; ObConstRawExpr* c_expr = NULL; if (OB_FAIL(expr_factory.create_raw_expr(static_cast(type), c_expr))) { LOG_WARN("fail to create const raw c_expr", K(ret)); } else { ObObj obj; obj.set_number(type, value); c_expr->set_value(obj); expr = c_expr; } return ret; } int ObRawExprUtils::build_var_int_expr(ObRawExprFactory& expr_factory, ObConstRawExpr*& expr) { int ret = OB_SUCCESS; ObConstRawExpr* c_expr = NULL; if (OB_FAIL(expr_factory.create_raw_expr(T_VAR_INT, c_expr))) { LOG_WARN("fail to create const raw c_expr", K(ret)); } else { ObObj obj; obj.set_int(0); c_expr->set_value(obj); expr = c_expr; } return ret; } int ObRawExprUtils::build_const_string_expr(ObRawExprFactory& expr_factory, ObObjType type, const ObString& string_value, ObCollationType cs_type, ObConstRawExpr*& expr) { int ret = OB_SUCCESS; ObConstRawExpr* c_expr = NULL; if (OB_FAIL(expr_factory.create_raw_expr(static_cast(type), c_expr))) { LOG_WARN("fail to create const raw c_expr", K(ret)); } else { ObObj obj; obj.set_string(type, string_value); obj.set_collation_type(cs_type); c_expr->set_value(obj); expr = c_expr; } return ret; } int ObRawExprUtils::build_variable_expr( ObRawExprFactory& expr_factory, const ObExprResType& result_type, ObVarRawExpr*& expr) { int ret = OB_SUCCESS; ObVarRawExpr* c_expr = NULL; if (OB_FAIL(expr_factory.create_raw_expr(T_EXEC_VAR, c_expr))) { LOG_WARN("fail to create const raw c_expr", K(ret)); } else { c_expr->set_result_type(result_type); expr = c_expr; } return ret; } int ObRawExprUtils::build_null_expr(ObRawExprFactory& expr_factory, ObRawExpr*& expr) { int ret = OB_SUCCESS; ObConstRawExpr* c_expr = NULL; if (OB_FAIL(expr_factory.create_raw_expr(T_NULL, c_expr))) { LOG_WARN("create const expr failed", K(ret)); } else { ObObj obj; obj.set_null(); c_expr->set_value(obj); expr = c_expr; } return ret; } int ObRawExprUtils::build_trim_expr(const ObColumnSchemaV2* column_schema, ObRawExprFactory& expr_factory, ObSQLSessionInfo* session_info, ObRawExpr*& expr) { int ret = OB_SUCCESS; ObSysFunRawExpr* trim_expr = NULL; int64_t trim_type = 2; ObConstRawExpr* type_expr = NULL; ObConstRawExpr* pattem_expr = NULL; ObString padding_char(1, &OB_PADDING_CHAR); ObCollationType padding_char_cs_type = CS_TYPE_INVALID; if (NULL == column_schema || NULL == expr) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(column_schema), K(expr)); } else { bool is_cs_nonascii = ObCharset::is_cs_nonascii(column_schema->get_collation_type()); padding_char_cs_type = is_cs_nonascii ? ObCharset::get_default_collation(CHARSET_UTF8MB4) : column_schema->get_collation_type(); } if (OB_FAIL(ret)) { } else if (OB_FAIL(expr_factory.create_raw_expr(T_FUN_INNER_TRIM, trim_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(trim_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to store expr", K(ret)); } else if (OB_FAIL(build_const_int_expr(expr_factory, ObIntType, trim_type, type_expr))) { LOG_WARN("fail to build type expr", K(ret)); } else if (trim_expr->add_param_expr(type_expr)) { LOG_WARN("fail to add param expr", K(ret), K(*type_expr)); } else if (OB_FAIL( build_const_string_expr(expr_factory, ObCharType, padding_char, padding_char_cs_type, pattem_expr))) { LOG_WARN("fail to build pattem expr", K(ret)); } else if (FALSE_IT(static_cast(pattem_expr)->get_value().set_collation_level(CS_LEVEL_IMPLICIT))) { LOG_WARN("fail to set collation type", K(ret)); } else if (trim_expr->add_param_expr(pattem_expr)) { LOG_WARN("fail to add param expr", K(ret)); } else if (trim_expr->add_param_expr(expr)) { LOG_WARN("fail to add param expr", K(ret), K(*expr)); } else { trim_expr->set_data_type(ObCharType); trim_expr->set_func_name(ObString::make_string(N_INNER_TRIM)); if (expr->is_for_generated_column()) { trim_expr->set_for_generated_column(); } expr = trim_expr; if (OB_FAIL(expr->formalize(session_info))) { LOG_WARN("fail to extract info", K(ret)); } } return ret; } int ObRawExprUtils::build_pad_expr(ObRawExprFactory& expr_factory, bool is_char, const ObColumnSchemaV2* column_schema, ObRawExpr*& expr, sql::ObSQLSessionInfo* session_info) { int ret = OB_SUCCESS; ObSysFunRawExpr* pad_expr = NULL; ObConstRawExpr* pading_word_expr = NULL; ObConstRawExpr* length_expr = NULL; ObString padding_char(1, &OB_PADDING_CHAR); ObString padding_binary(1, &OB_PADDING_BINARY); ObObjType padding_expr_type = ObMaxType; ObCollationType padding_expr_collation = CS_TYPE_INVALID; if (NULL == column_schema) { ret = OB_INVALID_ARGUMENT; LOG_WARN("inalid argument", K(column_schema)); } else if (OB_FAIL(expr_factory.create_raw_expr(T_FUN_PAD, pad_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(pad_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("pad expr is null", K(ret)); } else if (FALSE_IT(padding_expr_type = ob_is_nstring_type(column_schema->get_data_type()) ? ObNVarchar2Type : ObVarcharType)) { } else if (FALSE_IT(padding_expr_collation = ob_is_nstring_type(column_schema->get_data_type()) ? CS_TYPE_UTF8MB4_BIN : column_schema->get_collation_type())) { } else if (is_char && OB_FAIL(build_const_string_expr( expr_factory, padding_expr_type, padding_char, padding_expr_collation, pading_word_expr))) { LOG_WARN("fail to build pading word expr", K(ret)); } else if (!is_char && OB_FAIL(build_const_string_expr( expr_factory, padding_expr_type, padding_binary, padding_expr_collation, pading_word_expr))) { LOG_WARN("fail to build pading word expr", K(ret)); } else if (OB_FAIL(build_const_int_expr(expr_factory, ObIntType, column_schema->get_data_length(), length_expr))) { LOG_WARN("fail to build length expr", K(ret)); } else if (OB_FAIL(pad_expr->add_param_expr(expr))) { LOG_WARN("fail to add param expr", K(ret)); } else if (OB_FAIL(pad_expr->add_param_expr(pading_word_expr))) { LOG_WARN("fail to add param expr", K(ret)); } else if (OB_FAIL(pad_expr->add_param_expr(length_expr))) { LOG_WARN("fail to add param expr", K(ret)); } else { ObAccuracy padding_accuracy = pading_word_expr->get_accuracy(); padding_accuracy.set_length_semantics(column_schema->get_accuracy().get_length_semantics()); pading_word_expr->set_accuracy(padding_accuracy); pad_expr->set_data_type(padding_expr_type); pad_expr->set_func_name(ObString::make_string(N_PAD)); if (expr->is_for_generated_column()) { pad_expr->set_for_generated_column(); } expr = pad_expr; if (OB_FAIL(expr->formalize(session_info))) { LOG_WARN("fail to extract info", K(ret)); } LOG_DEBUG("build pad expr", KPC(pading_word_expr), KPC(pad_expr)); } return ret; } int ObRawExprUtils::build_nvl_expr(ObRawExprFactory& expr_factory, const ColumnItem* column_item, ObRawExpr*& expr) { int ret = OB_SUCCESS; ObSysFunRawExpr* nvl_func_expr = NULL; ObSysFunRawExpr* now_func_expr = NULL; if (NULL == column_item || NULL == expr) { ret = OB_INVALID_ARGUMENT; LOG_WARN("fail bo build length expr", K(column_item), K(expr)); } else if (OB_FAIL(expr_factory.create_raw_expr(T_FUN_SYS_TIMESTAMP_NVL, nvl_func_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_FAIL(expr_factory.create_raw_expr(T_FUN_SYS_CUR_TIMESTAMP, now_func_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(nvl_func_expr) || OB_ISNULL(now_func_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("func expr is null", K(nvl_func_expr), K(now_func_expr)); } else { nvl_func_expr->set_expr_type(T_FUN_SYS_TIMESTAMP_NVL); nvl_func_expr->set_func_name(ObString::make_string(N_TIMESTAMP_NVL)); nvl_func_expr->set_data_type(ObTimestampType); nvl_func_expr->set_accuracy(column_item->get_column_type()->get_accuracy()); now_func_expr->set_expr_type(T_FUN_SYS_CUR_TIMESTAMP); now_func_expr->set_data_type(ObDateTimeType); now_func_expr->set_accuracy(column_item->get_column_type()->get_accuracy()); // the accuracy of column now_func_expr->set_func_name(ObString::make_string(N_CUR_TIMESTAMP)); } if (OB_SUCC(ret)) { if (OB_FAIL(nvl_func_expr->add_param_expr(expr))) { LOG_WARN("fail to add param expr", K(ret)); } else if (OB_FAIL(nvl_func_expr->add_param_expr(now_func_expr))) { LOG_WARN("fail to add param expr", K(ret)); } else { expr = nvl_func_expr; } } return ret; } int ObRawExprUtils::build_lnnvl_expr(ObRawExprFactory& expr_factory, ObRawExpr* param_expr, ObRawExpr*& expr) { int ret = OB_SUCCESS; ObSysFunRawExpr* lnnvl_expr = NULL; expr = NULL; if (OB_ISNULL(param_expr)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(param_expr), K(ret)); } else if (OB_FAIL(expr_factory.create_raw_expr(T_FUN_SYS_LNNVL, lnnvl_expr))) { LOG_WARN("failed to create raw expr", K(ret)); } else if (OB_ISNULL(lnnvl_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("null expr", K(ret)); } else { lnnvl_expr->set_func_name(ObString::make_string(N_LNNVL)); lnnvl_expr->set_data_type(ObTinyIntType); if (OB_FAIL(lnnvl_expr->add_param_expr(param_expr))) { LOG_WARN("failed to add param expr", K(ret)); } else { expr = lnnvl_expr; } } return ret; } int ObRawExprUtils::build_equal_last_insert_id_expr( ObRawExprFactory& expr_factory, ObRawExpr*& expr, ObSQLSessionInfo* session) { int ret = OB_SUCCESS; ObOpRawExpr* equal_expr = NULL; ObSysFunRawExpr* last_insert_id = NULL; if (OB_ISNULL(expr) || OB_UNLIKELY(!expr->is_op_expr())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(expr)); } else if (OB_FAIL(expr_factory.create_raw_expr(T_OP_EQ, equal_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_FAIL(expr_factory.create_raw_expr(T_FUN_SYS_LAST_INSERT_ID, last_insert_id))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(equal_expr) || OB_ISNULL(last_insert_id)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr is null", K(equal_expr), K(last_insert_id)); } else { last_insert_id->set_func_name(ObString::make_string(N_LAST_INSERT_ID)); last_insert_id->set_data_type(ObIntType); if (OB_FAIL(equal_expr->add_param_expr(expr->get_param_expr(0)))) { LOG_WARN("fail to add param expr", K(ret)); } else if (OB_FAIL(equal_expr->add_param_expr(last_insert_id))) { LOG_WARN("fail to add param expr", K(ret)); } else if (OB_FAIL(equal_expr->formalize(session))) { LOG_WARN("fail to formalize expr", K(*equal_expr), K(ret)); } else { expr = equal_expr; } } return ret; } int ObRawExprUtils::build_get_user_var(ObRawExprFactory& expr_factory, const ObString& var_name, ObRawExpr*& expr, const ObSQLSessionInfo* session_info /* = NULL */, ObQueryCtx* query_ctx /* = NULL */, ObIArray* user_var_exprs /* = NULL*/) { int ret = OB_SUCCESS; ObSysFunRawExpr* f_expr = NULL; ObUserVarIdentRawExpr* var_expr = NULL; ObIArray* all_vars = (NULL == query_ctx ? NULL : &query_ctx->all_user_variable_); bool query_has_udf = (NULL == query_ctx ? false : query_ctx->has_udf_); if (OB_FAIL(expr_factory.create_raw_expr(T_OP_GET_USER_VAR, f_expr))) { LOG_WARN("create ObOpRawExpr failed", K(ret)); } else { ObString str = var_name; ObCharset::casedn(CS_TYPE_UTF8MB4_GENERAL_CI, str); ObObj val; val.set_varchar(str); val.set_collation_type(ObCharset::get_system_collation()); val.set_collation_level(CS_LEVEL_IMPLICIT); if (NULL != all_vars) { for (int64_t i = 0; OB_SUCC(ret) && i < all_vars->count(); ++i) { if (OB_ISNULL(all_vars->at(i))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get null user var ident expr", K(ret)); } else if (all_vars->at(i)->is_same_variable(val)) { var_expr = all_vars->at(i); } } } if (OB_SUCC(ret) && NULL == var_expr) { if (OB_FAIL(expr_factory.create_raw_expr(T_USER_VARIABLE_IDENTIFIER, var_expr))) { LOG_WARN("fail to create user var ident expr", K(ret)); } else if (NULL != all_vars && OB_FAIL(all_vars->push_back(var_expr))) { LOG_WARN("failed to push back var expr", K(ret)); } else { var_expr->set_value(val); } } if (OB_SUCC(ret)) { var_expr->set_query_has_udf(query_has_udf); if (OB_FAIL(f_expr->set_param_expr(var_expr))) { LOG_WARN("failed to add param expr", K(ret)); } else if (NULL != user_var_exprs && OB_FAIL(add_var_to_array_no_dup(*user_var_exprs, var_expr))) { LOG_WARN("failed to add var to array no dup", K(ret)); } else { expr = f_expr; } } } if (OB_SUCC(ret) && NULL != session_info) { if (OB_FAIL(expr->formalize(session_info))) { LOG_WARN("failed to formalize", K(ret)); } } return ret; } int ObRawExprUtils::build_get_sys_var(ObRawExprFactory& expr_factory, const ObString& var_name, ObSetVar::SetScopeType var_scope, ObRawExpr*& expr, const ObSQLSessionInfo* session_info) { int ret = OB_SUCCESS; ObConstRawExpr* name_expr = NULL; ObConstRawExpr* scope_expr = NULL; ObSysFunRawExpr* get_sys_var_expr = NULL; if (OB_FAIL(expr_factory.create_raw_expr(T_VARCHAR, name_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_FAIL(expr_factory.create_raw_expr(T_INT, scope_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_FAIL(expr_factory.create_raw_expr(T_OP_GET_SYS_VAR, get_sys_var_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(name_expr) || OB_ISNULL(scope_expr) || OB_ISNULL(get_sys_var_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr is null", K(name_expr), K(scope_expr), K(get_sys_var_expr)); } else { ObObj name_obj; name_obj.set_varchar(var_name); name_obj.set_collation_level(CS_LEVEL_SYSCONST); name_obj.set_collation_type(ObCharset::get_system_collation()); name_expr->set_value(name_obj); ObObj scope_obj; scope_obj.set_int(static_cast(var_scope)); scope_expr->set_expr_type(static_cast(scope_obj.get_type())); scope_expr->set_value(scope_obj); expr = get_sys_var_expr; get_sys_var_expr->set_expr_type(T_OP_GET_SYS_VAR); get_sys_var_expr->set_func_name(ObString::make_string(N_GET_SYS_VAR)); ret = get_sys_var_expr->set_param_exprs(name_expr, scope_expr); } if (OB_SUCC(ret) && NULL != session_info) { if (OB_FAIL(expr->formalize(session_info))) { LOG_WARN("failed to formalize", K(ret)); } } return ret; } int ObRawExprUtils::build_calc_part_id_expr(ObRawExprFactory& expr_factory, const ObSQLSessionInfo& session, uint64_t ref_table_id, ObPartitionLevel part_level, ObRawExpr* part_expr, ObRawExpr* subpart_expr, ObRawExpr*& expr) { int ret = OB_SUCCESS; expr = NULL; ObSysFunRawExpr* calc_expr = NULL; if (OB_FAIL(expr_factory.create_raw_expr(T_FUN_SYS, calc_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(calc_expr)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("fail to create raw expr", K(calc_expr), K(ret)); } else { if (schema::PARTITION_LEVEL_TWO == part_level) { if (OB_ISNULL(part_expr) || OB_ISNULL(subpart_expr)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("subpart_expr is null", K(subpart_expr), K(ret)); } else if (OB_FAIL(calc_expr->add_param_expr(part_expr)) || OB_FAIL(calc_expr->add_param_expr(subpart_expr))) { LOG_WARN("fail to add param expr", K(ret), K(*part_expr), K(*subpart_expr)); } } else if (schema::PARTITION_LEVEL_ONE == part_level) { if (OB_ISNULL(part_expr)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("part_expr is null", K(part_level), K(part_expr), K(ret)); } else if (OB_FAIL(calc_expr->add_param_expr(part_expr))) { LOG_WARN("fail to add param expr", K(ret), K(*part_expr)); } } if (OB_SUCC(ret)) { ObString func_name; if (OB_FAIL(ob_write_string(expr_factory.get_allocator(), ObString("calc_partition_id"), func_name))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("Malloc function name failed", K(ret)); } else { calc_expr->set_func_name(func_name); calc_expr->set_extra(ref_table_id); } if (OB_SUCC(ret)) { if (OB_FAIL(calc_expr->formalize(&session))) { LOG_WARN("fail to formalize expr", K(ret), K(calc_expr)); } else { expr = calc_expr; } } } } return ret; } int ObRawExprUtils::build_get_package_var(ObRawExprFactory& expr_factory, uint64_t package_id, int64_t var_idx, ObExprResType* result_type, ObRawExpr*& expr, const ObSQLSessionInfo* session_info) { int ret = OB_SUCCESS; ObSysFunRawExpr* f_expr = NULL; ObConstRawExpr* c_expr1 = NULL; ObConstRawExpr* c_expr2 = NULL; ObConstRawExpr* c_expr3 = NULL; OZ(expr_factory.create_raw_expr(T_OP_GET_PACKAGE_VAR, f_expr)); OZ(build_const_int_expr(expr_factory, ObUInt64Type, package_id, c_expr1)); OZ(f_expr->add_param_expr(c_expr1)); OZ(build_const_int_expr(expr_factory, ObIntType, var_idx, c_expr2)); OZ(f_expr->add_param_expr(c_expr2)); OZ(build_const_int_expr(expr_factory, ObIntType, reinterpret_cast(result_type), c_expr3)); OZ(f_expr->add_param_expr(c_expr3)); OX(f_expr->set_func_name(ObString::make_string(N_GET_PACKAGE_VAR))); OX(expr = f_expr); CK(OB_NOT_NULL(session_info)); OZ(expr->formalize(session_info)); return ret; } int ObRawExprUtils::build_get_subprogram_var(ObRawExprFactory& expr_factory, uint64_t package_id, uint64_t routine_id, int64_t var_idx, ObExprResType* result_type, ObRawExpr*& expr, const ObSQLSessionInfo* session_info) { int ret = OB_SUCCESS; ObSysFunRawExpr* f_expr = NULL; ObConstRawExpr* c_expr1 = NULL; ObConstRawExpr* c_expr2 = NULL; ObConstRawExpr* c_expr3 = NULL; ObConstRawExpr* c_expr4 = NULL; OZ(expr_factory.create_raw_expr(T_OP_GET_SUBPROGRAM_VAR, f_expr)); OZ(build_const_int_expr(expr_factory, ObUInt64Type, package_id, c_expr1)); OZ(f_expr->add_param_expr(c_expr1)); OZ(build_const_int_expr(expr_factory, ObUInt64Type, routine_id, c_expr2)); OZ(f_expr->add_param_expr(c_expr2)); OZ(build_const_int_expr(expr_factory, ObIntType, var_idx, c_expr3)); OZ(f_expr->add_param_expr(c_expr3)); OZ(build_const_int_expr(expr_factory, ObIntType, reinterpret_cast(result_type), c_expr4)); OZ(f_expr->add_param_expr(c_expr4)); OX(f_expr->set_func_name(ObString::make_string(N_GET_SUBPROGRAM_VAR))); OX(expr = f_expr); CK(OB_NOT_NULL(session_info)); OZ(expr->formalize(session_info)); return ret; } int ObRawExprUtils::create_equal_expr(ObRawExprFactory& expr_factory, ObSQLSessionInfo* session_info, const ObRawExpr* val_ref, const ObRawExpr* col_ref, ObRawExpr*& expr) { int ret = OB_SUCCESS; ObOpRawExpr* equal_expr = NULL; if (OB_FAIL(expr_factory.create_raw_expr(T_OP_EQ, equal_expr))) { LOG_WARN("create equal expr failed", K(ret)); } else if (OB_ISNULL(expr = equal_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("equal expr is null"); } else if (OB_FAIL(equal_expr->set_param_exprs(const_cast(col_ref), const_cast(val_ref)))) { LOG_WARN("set param expr failed", K(ret)); } else if (OB_FAIL(equal_expr->formalize(session_info))) { LOG_WARN("formalize equal expr failed", K(ret)); } else { } return ret; } int ObRawExprUtils::create_double_op_expr(ObRawExprFactory& expr_factory, const ObSQLSessionInfo* session_info, ObItemType expr_type, ObRawExpr*& add_expr, const ObRawExpr* left_expr, const ObRawExpr* right_expr) { int ret = OB_SUCCESS; ObOpRawExpr* op_expr = NULL; if (OB_FAIL(expr_factory.create_raw_expr(expr_type, op_expr))) { LOG_WARN("create add op expr failed", K(ret)); } else if (OB_ISNULL(add_expr = op_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("add expr is null"); } else if (OB_FAIL(op_expr->set_param_exprs(const_cast(left_expr), const_cast(right_expr)))) { LOG_WARN("set param exprs failed", K(ret)); } else if (OB_FAIL(op_expr->formalize(session_info))) { LOG_WARN("formalize add operator failed", K(ret)); } return ret; } int ObRawExprUtils::make_set_op_expr(ObRawExprFactory& expr_factory, int64_t idx, ObItemType set_op_type, const ObExprResType& res_type, ObSQLSessionInfo* session_info, ObRawExpr*& out_expr) { int ret = OB_SUCCESS; ObSetOpRawExpr* set_expr = NULL; if (OB_UNLIKELY(set_op_type <= T_OP_SET) || OB_UNLIKELY(set_op_type > T_OP_EXCEPT)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unknow set operator type", K(set_op_type)); } else if (OB_FAIL(expr_factory.create_raw_expr(set_op_type, set_expr))) { LOG_WARN("create set op raw expr failed", K(ret)); } else if (OB_ISNULL(out_expr = set_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("out expr is null"); } else if (OB_FAIL(set_expr->add_flag(IS_SET_OP))) { LOG_WARN("failed to add flag IS_SET_OP", K(ret)); } else { set_expr->set_result_type(res_type); set_expr->set_idx(idx); if (session_info != NULL && OB_FAIL(set_expr->formalize(session_info))) { LOG_WARN("formalize set expr failed", K(ret)); } } return ret; } int ObRawExprUtils::merge_variables(const ObIArray& src_vars, ObIArray& dst_vars) { int ret = OB_SUCCESS; int64_t N = src_vars.count(); for (int64_t i = 0; OB_SUCC(ret) && i < N; ++i) { const ObVarInfo& var = src_vars.at(i); bool found = false; int64_t M = dst_vars.count(); for (int64_t j = 0; j < M; ++j) { if (var == dst_vars.at(j)) { found = true; break; } } // end for if (!found) { ret = dst_vars.push_back(var); } } // end for return ret; } int ObRawExprUtils::get_array_param_index(const ObRawExpr* expr, int64_t& param_index) { int ret = OB_SUCCESS; if (OB_ISNULL(expr)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(expr)); } else if (expr->is_const_expr()) { if (expr->get_result_type().get_param().is_ext()) { const ObConstRawExpr* c_expr = static_cast(expr); if (OB_FAIL(c_expr->get_value().get_unknown(param_index))) { LOG_WARN("get param index failed", K(ret), K(c_expr->get_value())); } } } else { for (int64_t i = 0; OB_SUCC(ret) && OB_INVALID_INDEX == param_index && i < expr->get_param_count(); ++i) { if (OB_FAIL(get_array_param_index(expr->get_param_expr(i), param_index))) { LOG_WARN("get array param index failed", K(ret), KPC(expr)); } } } return ret; } int ObRawExprUtils::get_item_count(const ObRawExpr* expr, int64_t& count) { int ret = OB_SUCCESS; if (OB_ISNULL(expr)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(expr)); } else if (expr->is_column_ref_expr()) { const ObColumnRefRawExpr* col_ref = static_cast(expr); if (col_ref->is_generated_column()) { ret = get_item_count(col_ref->get_dependant_expr(), count); } else { ++count; } } else { for (int64_t i = 0; OB_SUCC(ret) && i < expr->get_param_count(); i++) { if (OB_ISNULL(expr->get_param_expr(i))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get invalie expr", K(i), K(ret)); } else if (OB_FAIL(get_item_count(expr->get_param_expr(i), count))) { LOG_WARN("fail to get item count", K(ret)); } } if (OB_SUCC(ret)) { count++; } } return ret; } int ObRawExprUtils::build_column_expr( ObRawExprFactory& expr_factory, const ObColumnSchemaV2& column_schema, ObColumnRefRawExpr*& column_expr) { int ret = OB_SUCCESS; ObString database_name; ObString table_name; ObString column_name; if (OB_FAIL(expr_factory.create_raw_expr(T_REF_COLUMN, column_expr))) { LOG_WARN("create column expr failed", K(ret)); } else if (OB_ISNULL(column_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("column_expr is null"); } else if (OB_FAIL(init_column_expr(column_schema, *column_expr))) { LOG_WARN("init column expr failed", K(ret)); } return ret; } int ObRawExprUtils::build_alias_column_expr( ObRawExprFactory& expr_factory, ObRawExpr* ref_expr, int32_t alias_level, ObAliasRefRawExpr*& alias_expr) { int ret = OB_SUCCESS; if (OB_FAIL(expr_factory.create_raw_expr(T_REF_ALIAS_COLUMN, alias_expr))) { LOG_WARN("create alias column expr failed", K(ret)); } else if (OB_ISNULL(alias_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("alias column expr is null", K(ret)); } else { alias_expr->set_expr_level(alias_level); alias_expr->set_ref_expr(ref_expr); } return ret; } int ObRawExprUtils::build_query_output_ref( ObRawExprFactory& expr_factory, ObQueryRefRawExpr* query_ref, int64_t project_index, ObAliasRefRawExpr*& alias_expr) { int ret = OB_SUCCESS; ObSelectStmt* sel_stmt = NULL; ObRawExpr* real_ref_expr = NULL; if (OB_ISNULL(query_ref) || OB_ISNULL(sel_stmt = query_ref->get_ref_stmt())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("query ref expr is invalid", K(ret), K(query_ref), K(sel_stmt)); } else if (project_index < 0 || project_index >= query_ref->get_ref_stmt()->get_select_item_size() || OB_ISNULL(real_ref_expr = sel_stmt->get_select_item(project_index).expr_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("project index is invalid", K(ret), K(project_index), K(real_ref_expr)); } else if (OB_FAIL(expr_factory.create_raw_expr(T_REF_ALIAS_COLUMN, alias_expr))) { LOG_WARN("create alias column expr failed", K(ret)); } else if (OB_ISNULL(alias_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("alias column expr is null", K(ret)); } else { alias_expr->set_expr_level(query_ref->get_expr_level()); alias_expr->set_query_output(query_ref, project_index); alias_expr->set_result_type(real_ref_expr->get_result_type()); } return ret; } bool ObRawExprUtils::is_same_column_ref(const ObRawExpr* column_ref1, const ObRawExpr* column_ref2) { // need to compare real node in alias ref. const ObRawExpr* left_real_ref = column_ref1; const ObRawExpr* right_real_ref = column_ref2; while (left_real_ref != NULL && T_REF_ALIAS_COLUMN == left_real_ref->get_expr_type()) { left_real_ref = static_cast(left_real_ref)->get_ref_expr(); } while (right_real_ref != NULL && T_REF_ALIAS_COLUMN == right_real_ref->get_expr_type()) { right_real_ref = static_cast(right_real_ref)->get_ref_expr(); } bool bret = (left_real_ref == right_real_ref); return bret; } int32_t ObRawExprUtils::get_generalized_column_level(const ObRawExpr& generalized_column) { int32_t column_level = -1; if (generalized_column.is_column_ref_expr()) { column_level = static_cast(generalized_column).get_expr_level(); } else if (generalized_column.is_query_ref_expr()) { column_level = static_cast(generalized_column).get_expr_level(); } else if (generalized_column.is_aggr_expr()) { column_level = static_cast(generalized_column).get_expr_level(); } else if (generalized_column.is_set_op_expr()) { column_level = static_cast(generalized_column).get_expr_level(); } return column_level; } int ObRawExprUtils::init_column_expr(const ObColumnSchemaV2& column_schema, ObColumnRefRawExpr& column_expr) { int ret = OB_SUCCESS; const ObAccuracy& accuracy = column_schema.get_accuracy(); column_expr.set_ref_id(column_schema.get_table_id(), column_schema.get_column_id()); column_expr.set_data_type(column_schema.get_data_type()); column_expr.set_result_flag(calc_column_result_flag(column_schema)); column_expr.get_column_name().assign_ptr( column_schema.get_column_name_str().ptr(), column_schema.get_column_name_str().length()); column_expr.set_column_flags(column_schema.get_column_flags()); column_expr.set_hidden_column(column_schema.is_hidden()); if (ob_is_string_type(column_schema.get_data_type()) || ob_is_enumset_tc(column_schema.get_data_type())) { column_expr.set_collation_type(column_schema.get_collation_type()); column_expr.set_collation_level(CS_LEVEL_IMPLICIT); } else { column_expr.set_collation_type(CS_TYPE_BINARY); column_expr.set_collation_level(CS_LEVEL_NUMERIC); } if (OB_SUCC(ret)) { column_expr.set_accuracy(accuracy); if (OB_FAIL(column_expr.extract_info())) { LOG_WARN("extract column expr info failed", K(ret)); } } if (OB_SUCC(ret) && column_schema.is_enum_or_set()) { if (OB_FAIL(column_expr.set_enum_set_values(column_schema.get_extended_type_info()))) { LOG_WARN("failed to set enum set values", K(ret)); } } 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::exprs_contain_subquery(const ObIArray& exprs, bool& cnt_subquery) { int ret = OB_SUCCESS; cnt_subquery = false; for (int64_t i = 0; OB_SUCC(ret) && !cnt_subquery && i < exprs.count(); ++i) { if (OB_ISNULL(exprs.at(i))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr is null", K(i)); } else if (exprs.at(i)->has_flag(CNT_SUB_QUERY)) { cnt_subquery = true; } } return ret; } uint32_t ObRawExprUtils::calc_column_result_flag(const ObColumnSchemaV2& column_schema) { uint32_t flag = 0; if (column_schema.is_autoincrement()) { flag |= OB_MYSQL_AUTO_INCREMENT_FLAG; } if (!column_schema.is_nullable()) { flag |= OB_MYSQL_NOT_NULL_FLAG; } if (column_schema.is_rowkey_column()) { flag |= OB_MYSQL_PRI_KEY_FLAG; flag |= OB_MYSQL_PART_KEY_FLAG; } if (column_schema.is_index_column()) { flag |= OB_MYSQL_PART_KEY_FLAG; if (column_schema.get_index_position() == 1) { flag |= OB_MYSQL_MULTIPLE_KEY_FLAG; } } if (column_schema.is_zero_fill()) { flag |= OB_MYSQL_ZEROFILL_FLAG; } return flag; } int ObRawExprUtils::extract_int_value(const ObRawExpr* expr, int64_t& val) { int ret = OB_SUCCESS; int64_t count = 0; if (OB_ISNULL(expr) || !expr->is_const_expr()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("const expr should not be null", K(ret), K(expr)); } else { const ObConstRawExpr* const_expr = static_cast(expr); if (OB_ISNULL(const_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("const expr should not be null", K(ret)); } else { const ObObj& result = const_expr->get_value(); if (OB_FAIL(result.get_int(count))) { LOG_WARN("failed to get int", K(ret)); } else { val = count; } } } return ret; } int ObRawExprUtils::need_wrap_to_string( ObObjType param_type, ObObjType calc_type, const bool is_same_type_need, bool& need_wrap) { int ret = OB_SUCCESS; need_wrap = false; if (!ob_is_enumset_tc(param_type)) { // only need to convert when parameter is enum type. } else if (param_type == calc_type && (!is_same_type_need)) { need_wrap = false; } else { switch (calc_type) { case ObNullType: case ObTinyIntType: case ObSmallIntType: case ObMediumIntType: case ObInt32Type: case ObIntType: case ObUTinyIntType: case ObUSmallIntType: case ObUMediumIntType: case ObUInt32Type: case ObUInt64Type: case ObFloatType: case ObDoubleType: case ObUFloatType: case ObUDoubleType: case ObNumberType: case ObUNumberType: case ObNumberFloatType: case ObBitType: case ObYearType: { need_wrap = false; break; } case ObDateTimeType: case ObTimestampType: case ObDateType: case ObTimeType: case ObVarcharType: case ObCharType: case ObTinyTextType: case ObTextType: case ObMediumTextType: case ObLongTextType: case ObEnumType: case ObSetType: case ObTimestampTZType: case ObTimestampLTZType: case ObTimestampNanoType: case ObRawType: case ObIntervalDSType: case ObIntervalYMType: case ObNVarchar2Type: case ObNCharType: { need_wrap = true; break; } default: { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid calc_type", K(param_type), K(calc_type), K(ret)); } } } LOG_DEBUG("finish need_wrap_to_string", K(need_wrap), K(param_type), K(calc_type), K(ret), K(lbt())); return ret; } int ObRawExprUtils::extract_param_idxs(const ObRawExpr* expr, ObIArray& param_idxs) { int ret = OB_SUCCESS; if (OB_ISNULL(expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr is null"); } else if (expr->get_expr_type() == T_QUESTIONMARK) { const ObConstRawExpr* const_expr = static_cast(expr); const ObObj& val = const_expr->get_value(); int64_t param_idx = OB_INVALID_INDEX; if (OB_FAIL(val.get_unknown(param_idx))) { LOG_WARN("get unknown of value failed", K(ret)); } else if (OB_FAIL(param_idxs.push_back(param_idx))) { LOG_WARN("store param idx failed", K(ret)); } } else if (expr->has_flag(CNT_PARAM)) { for (int64_t i = 0; OB_SUCC(ret) && i < expr->get_param_count(); ++i) { if (OB_FAIL(extract_param_idxs(expr->get_param_expr(i), param_idxs))) { LOG_WARN("extract param idxs failed", K(ret)); } } } return ret; } int ObRawExprUtils::find_alias_expr(ObRawExpr* expr, ObAliasRefRawExpr*& alias_expr) { int ret = OB_SUCCESS; if (OB_ISNULL(expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr is null", K(ret)); } else if (expr->is_alias_ref_expr()) { alias_expr = static_cast(expr); } else if (expr->has_flag(CNT_ALIAS)) { for (int64_t i = 0; OB_SUCC(ret) && i < expr->get_param_count(); ++i) { if (OB_FAIL(SMART_CALL(find_alias_expr(expr->get_param_expr(i), alias_expr)))) { LOG_WARN("failed to find alias expr", K(ret)); } } } return ret; } bool ObRawExprUtils::contain_id(const ObIArray& ids, const uint64_t target) { bool found = false; for (int64_t i = 0; !found && i < ids.count(); ++i) { if (ids.at(i) == target) { found = true; } } return found; } int ObRawExprUtils::clear_exprs_flag(const ObIArray& exprs, ObExprInfoFlag flag) { int ret = OB_SUCCESS; ARRAY_FOREACH(exprs, i) { ObRawExpr* raw_expr = exprs.at(i); if (OB_ISNULL(raw_expr)) { LOG_WARN("get output expr fail", K(i), K(exprs)); ret = OB_ERR_UNEXPECTED; } else if (OB_FAIL(raw_expr->clear_flag(flag))) { LOG_WARN("fail to clear flag", K(ret)); } else { } } return ret; } bool ObRawExprUtils::has_prefix_str_expr( const ObRawExpr& expr, const ObColumnRefRawExpr& orig_column_expr, const ObRawExpr*& substr_expr) { bool bret = false; const ObRawExpr* tmp = &expr; if (T_FUN_COLUMN_CONV == expr.get_expr_type()) { tmp = expr.get_param_expr(4); } if (T_FUN_SYS_SUBSTR == tmp->get_expr_type()) { const ObRawExpr* param_expr1 = tmp->get_param_expr(0); if (param_expr1 != NULL && param_expr1->is_column_ref_expr() && param_expr1->get_result_type().is_string_or_lob_locator_type() && param_expr1->same_as(orig_column_expr)) { if (3 == tmp->get_param_count()) { const ObRawExpr* param_expr2 = tmp->get_param_expr(1); if (param_expr2 != NULL && param_expr2->is_const_expr()) { const ObConstRawExpr* const_expr = static_cast(param_expr2); if (const_expr->get_value().is_int() && const_expr->get_value().get_int() == 1) { bret = true; substr_expr = tmp; } } } } } return bret; } int ObRawExprUtils::build_like_expr(ObRawExprFactory& expr_factory, ObSQLSessionInfo* session_info, ObRawExpr* text_expr, ObRawExpr* pattern_expr, ObRawExpr* escape_expr, ObOpRawExpr*& like_expr) { int ret = OB_SUCCESS; if (OB_FAIL(expr_factory.create_raw_expr(T_OP_LIKE, like_expr))) { LOG_WARN("create like expr failed", K(ret)); } else if (OB_FAIL(like_expr->add_param_expr(text_expr))) { LOG_WARN("add text expr to like expr failed", K(ret)); } else if (OB_FAIL(like_expr->add_param_expr(pattern_expr))) { LOG_WARN("add pattern expr to like expr failed", K(ret)); } else if (OB_FAIL(like_expr->add_param_expr(escape_expr))) { LOG_WARN("add escape expr to like expr failed", K(ret)); } else if (OB_FAIL(like_expr->formalize(session_info))) { LOG_WARN("formalize like expr failed", K(ret)); } return ret; } int ObRawExprUtils::replace_level_column(ObRawExpr*& raw_expr, ObRawExpr* to, bool& replaced) { int ret = OB_SUCCESS; if (OB_ISNULL(raw_expr) || OB_ISNULL(to)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(raw_expr), K(to)); } else if (raw_expr->get_expr_type() == T_LEVEL) { raw_expr = to; replaced = true; LOG_DEBUG("replace leaf node", K(*to), K(to)); } else { int64_t N = raw_expr->get_param_count(); for (int64_t i = 0; OB_SUCC(ret) && i < N; ++i) { ObRawExpr*& child_expr = raw_expr->get_param_expr(i); if (OB_FAIL(replace_level_column(child_expr, to, replaced))) { LOG_WARN("replace reference column failed", K(ret)); } } // end for } return ret; } int ObRawExprUtils::build_const_bool_expr(ObRawExprFactory* expr_factory, ObRawExpr*& expr, bool b_value) { int ret = OB_SUCCESS; ObConstRawExpr* bool_expr = NULL; if (OB_ISNULL(expr_factory)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr_factory is null", K(ret)); } else if (OB_FAIL(expr_factory->create_raw_expr(T_BOOL, bool_expr))) { LOG_WARN("build const bool expr failed", K(ret)); } else if (OB_ISNULL(bool_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("bool expr is null", K(ret)); } else { ObObj val; val.set_bool(b_value); bool_expr->set_value(val); expr = bool_expr; } return ret; } int ObRawExprUtils::check_composite_cast(ObRawExpr*& expr, ObSchemaChecker& schema_checker) { int ret = OB_SUCCESS; if (OB_ISNULL(expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr is NULL", K(ret)); } else if (T_FUN_SYS_CAST == expr->get_expr_type()) { CK(OB_NOT_NULL(expr->get_param_expr(0)), OB_NOT_NULL(expr->get_param_expr(1))); CK(expr->get_param_expr(1)->is_const_expr()); } else { for (int64_t i = 0; OB_SUCC(ret) && i < expr->get_param_count(); ++i) { OZ(SMART_CALL(check_composite_cast(expr->get_param_expr(i), schema_checker))); } } return ret; } /* int ObRawExprUtils::add_expr_to_set(ObRawExprUniqueSet &expr_set, ObRawExpr *expr) { int ret = expr_set.exist_refactored(expr); if (OB_HASH_EXIST == ret) { ret = OB_SUCCESS; // do nothing } else if (OB_HASH_NOT_EXIST == ret) { OZ(expr_set.set_refactored(expr)); } else { LOG_WARN("fail to search raw expr", K(ret)); } return ret; } int ObRawExprUtils::add_exprs_to_set(ObRawExprUniqueSet &expr_set, const ObIArray &exprs) { int ret = OB_SUCCESS; for (int64_t i = 0; OB_SUCC(ret) && i < exprs.count(); i++) { OZ(add_expr_to_set(expr_set, exprs.at(i))); } return ret; } */ int ObRawExprUtils::flatten_raw_exprs( const ObIArray& raw_exprs, ObRawExprUniqueSet& flattened_exprs, std::function filter) { int ret = OB_SUCCESS; for (int64_t i = 0; OB_SUCC(ret) && i < raw_exprs.count(); i++) { if (OB_FAIL(flatten_raw_expr(raw_exprs.at(i), flattened_exprs, filter))) { LOG_WARN("fail to flatten raw expr", K(ret)); } } return ret; } int ObRawExprUtils::flatten_raw_exprs( const ObRawExprUniqueSet& raw_exprs, ObRawExprUniqueSet& flattened_exprs, std::function filter) { return flatten_raw_exprs(raw_exprs.get_expr_array(), flattened_exprs, filter); } int ObRawExprUtils::flatten_raw_expr( ObRawExpr* raw_expr, ObRawExprUniqueSet& flattened_exprs, std::function filter) { int ret = OB_SUCCESS; bool is_stack_overflow = false; if (OB_FAIL(check_stack_overflow(is_stack_overflow))) { LOG_WARN("check stack overflow failed", K(ret)); } else if (is_stack_overflow) { ret = OB_SIZE_OVERFLOW; LOG_WARN("too deep recursive", K(ret)); } else if (OB_ISNULL(raw_expr) || !filter(raw_expr)) { // do nothing } else if (OB_FAIL(flattened_exprs.append(raw_expr))) { LOG_WARN("fail to push raw expr", K(ret), K(raw_expr)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < raw_expr->get_param_count(); i++) { if (OB_ISNULL(raw_expr->get_param_expr(i))) { ret = OB_INVALID_ARGUMENT; LOG_WARN("expr is null"); } else if (OB_FAIL(SMART_CALL(flatten_raw_expr(raw_expr->get_param_expr(i), flattened_exprs, filter)))) { LOG_WARN("fail to flatten raw expr", K(ret), K(i)); } } if (OB_SUCC(ret) && raw_expr->get_expr_type() == T_CTE_CYCLE_COLUMN) { ObPseudoColumnRawExpr* cycle_expr = static_cast(raw_expr); ObRawExpr *v_raw_expr, *d_v_raw_expr; cycle_expr->get_cte_cycle_value(v_raw_expr, d_v_raw_expr); if (OB_ISNULL(v_raw_expr) || OB_ISNULL(d_v_raw_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Invalid raw expr", K(ret)); } else if (OB_FAIL(SMART_CALL(flatten_raw_expr(v_raw_expr, flattened_exprs, filter)))) { LOG_WARN("fail to flatten raw expr", K(ret), K(v_raw_expr)); } else if (OB_FAIL(SMART_CALL(flatten_raw_expr(d_v_raw_expr, flattened_exprs, filter)))) { LOG_WARN("fail to flatten raw expr", K(ret), K(d_v_raw_expr)); } } // flatten dependent expr if (OB_SUCC(ret) && T_REF_COLUMN == raw_expr->get_expr_type()) { ObColumnRefRawExpr* col_expr = static_cast(raw_expr); ObRawExpr* dependant_expr = col_expr->get_dependant_expr(); if (NULL == dependant_expr) { // do nothing } else if (OB_FAIL(SMART_CALL(flatten_raw_expr(dependant_expr, flattened_exprs, filter)))) { LOG_WARN("failed to flatten raw expr", K(ret), K(*dependant_expr)); } } } return ret; } int ObRawExprUtils::try_add_bool_expr(ObCaseOpRawExpr* parent, ObRawExprFactory& expr_factory) { int ret = OB_SUCCESS; if (OB_ISNULL(parent)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("in expr is NULL", K(ret)); } else if (OB_UNLIKELY(T_OP_ARG_CASE == parent->get_expr_type())) { // ignore T_OP_ARG_CASE LOG_DEBUG("ignore adding bool expr for arg_case expr", K(ret), K(*parent)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < parent->get_when_expr_size(); ++i) { ObRawExpr* when_expr = parent->get_when_param_expr(i); ObRawExpr* new_when_expr = NULL; if (OB_FAIL(try_create_bool_expr(when_expr, new_when_expr, expr_factory))) { LOG_WARN("create_bool_expr failed", K(ret)); } else if (OB_ISNULL(new_when_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("new param_expr is NULL", K(ret)); } else { parent->replace_when_param_expr(i, new_when_expr); } } } return ret; } int ObRawExprUtils::try_add_bool_expr(ObOpRawExpr* parent, ObRawExprFactory& expr_factory) { int ret = OB_SUCCESS; if (OB_ISNULL(parent)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("in expr is NULL", K(ret)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < parent->get_param_count(); ++i) { ObRawExpr* param_expr = parent->get_param_expr(i); ObRawExpr* new_param_expr = NULL; if (OB_FAIL(try_create_bool_expr(param_expr, new_param_expr, expr_factory))) { LOG_WARN("create_bool_expr failed", K(ret)); } else if (OB_ISNULL(new_param_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("new param_expr is NULL", K(ret)); } else { parent->replace_param_expr(i, new_param_expr); } } } return ret; } int ObRawExprUtils::try_create_bool_expr(ObRawExpr* src_expr, ObRawExpr*& out_expr, ObRawExprFactory& expr_factory) { int ret = OB_SUCCESS; out_expr = NULL; if (OB_ISNULL(src_expr)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("in expr is NULL", K(ret)); } else { ObOpRawExpr* bool_expr = NULL; bool need_bool_expr = true; if (OB_FAIL(check_need_bool_expr(src_expr, need_bool_expr))) { LOG_WARN("check_need_bool_expr failed", K(ret)); } else if (!need_bool_expr) { out_expr = src_expr; } else if (OB_FAIL(expr_factory.create_raw_expr(T_OP_BOOL, bool_expr))) { LOG_WARN("create bool expr failed", K(ret)); } else if (OB_ISNULL(bool_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("bool_expr is NULL", K(ret)); } else { OZ(bool_expr->add_flag(IS_INNER_ADDED_EXPR)); OZ(bool_expr->add_param_expr(src_expr)); OX(out_expr = bool_expr); } } return ret; } bool ObRawExprUtils::check_need_bool_expr(const ObRawExpr* expr, bool& need_bool_expr) { int ret = OB_SUCCESS; need_bool_expr = true; if (OB_ISNULL(expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("in expr is NULL", K(ret)); } else if (is_oracle_mode()) { need_bool_expr = false; } else { ObItemType expr_type = expr->get_expr_type(); switch (expr_type) { case T_OP_EQ: case T_OP_NSEQ: case T_OP_LE: case T_OP_LT: case T_OP_GE: case T_OP_GT: case T_OP_NE: case T_OP_SQ_EQ: case T_OP_SQ_NSEQ: case T_OP_SQ_LE: case T_OP_SQ_LT: case T_OP_SQ_GE: case T_OP_SQ_GT: case T_OP_SQ_NE: case T_OP_IS: case T_OP_IS_NOT: case T_OP_BTW: case T_OP_NOT_BTW: case T_OP_LIKE: case T_OP_NOT_LIKE: case T_OP_REGEXP: case T_OP_NOT_REGEXP: case T_OP_NOT: case T_OP_AND: case T_OP_OR: case T_OP_IN: case T_OP_NOT_IN: case T_OP_EXISTS: case T_OP_NOT_EXISTS: // all int is 8 byte in datum, so safe for expr to use get_int() for tinyint type case T_TINYINT: case T_SMALLINT: case T_MEDIUMINT: case T_INT32: case T_INT: case T_UTINYINT: case T_USMALLINT: case T_UMEDIUMINT: case T_UINT32: case T_UINT64: case T_OP_XOR: case T_OP_BOOL: { need_bool_expr = false; break; } default: { need_bool_expr = true; break; } } } return ret; } int ObRawExprUtils::get_real_expr_without_cast( const bool is_static_typing_engine, const ObRawExpr* expr, const ObRawExpr*& out_expr) { int ret = OB_SUCCESS; if (OB_ISNULL(expr)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("expr is NULL", K(ret)); } else { if (is_static_typing_engine) { while (T_FUN_SYS_CAST == expr->get_expr_type() && CM_IS_IMPLICIT_CAST(expr->get_extra())) { if (OB_UNLIKELY(2 != expr->get_param_count())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("param_count of cast expr should be 2", K(ret), K(*expr)); } else if (OB_ISNULL(expr = expr->get_param_expr(0))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("first child of cast expr is NULL", K(ret), K(*expr)); } } } if (OB_SUCC(ret)) { out_expr = expr; LOG_DEBUG("get_real_expr_without_cast done", K(*out_expr)); } } return ret; } int ObRawExprUtils::build_remove_const_expr( ObRawExprFactory& factory, ObSQLSessionInfo& session_info, ObRawExpr* arg, ObRawExpr*& out) { int ret = OB_SUCCESS; CK(NULL != arg); if (OB_SUCC(ret)) { ObSysFunRawExpr* rc_expr = NULL; OZ(factory.create_raw_expr(T_FUN_SYS_REMOVE_CONST, rc_expr)); CK(NULL != rc_expr); OZ(rc_expr->add_param_expr(arg)); OX(rc_expr->set_func_name(ObString::make_string(N_REMOVE_CONST))); OZ(rc_expr->formalize(&session_info)); OZ(rc_expr->add_flag(IS_INNER_ADDED_EXPR)); OX(out = rc_expr); } return ret; }; bool ObRawExprUtils::is_pseudo_column_like_expr(const ObRawExpr& expr) { bool bret = false; if (ObRawExpr::EXPR_PSEUDO_COLUMN == expr.get_expr_class() || T_FUN_SYS_ROWNUM == expr.get_expr_type() || T_FUN_SYS_SEQ_NEXTVAL == expr.get_expr_type()) { bret = true; } return bret; } bool ObRawExprUtils::is_sharable_expr(const ObRawExpr& expr) { int bret = false; if (expr.is_query_ref_expr() || expr.is_column_ref_expr() || expr.is_aggr_expr() || expr.is_win_func_expr() || is_pseudo_column_like_expr(expr)) { bret = true; } return bret; } int ObRawExprUtils::check_need_cast_expr(const ObExprResType& src_type, const ObExprResType& dst_type, bool& need_cast) { int ret = OB_SUCCESS; need_cast = false; ObObjType in_type = src_type.get_type(); ObObjType out_type = dst_type.get_type(); ObCollationType in_cs_type = src_type.get_collation_type(); ObCollationType out_cs_type = dst_type.get_collation_type(); bool is_both_string = (ob_is_string_type(in_type) && ob_is_string_type(out_type)); const bool is_same_need = true; bool need_wrap = false; if (!ob_is_valid_obj_type(in_type) || !ob_is_valid_obj_type(out_type) || (ob_is_string_type(in_type) && !ObCharset::is_valid_collation(in_cs_type)) || (ob_is_string_type(out_type) && !ObCharset::is_valid_collation(out_cs_type))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid src type or dst type", K(ret), K(src_type), K(dst_type)); } else if ((!is_both_string && in_type == out_type) || (is_both_string && in_type == out_type && in_cs_type == out_cs_type)) { need_cast = false; } else if (ob_is_enumset_tc(out_type)) { // no need add cast, will add column_conv later need_cast = false; } else if (OB_FAIL(ObRawExprUtils::need_wrap_to_string(in_type, out_type, is_same_need, need_wrap))) { LOG_WARN("failed to check_need_wrap_to_string", K(ret)); } else if (need_wrap) { // no need add cast, add enumset_str expr later need_cast = false; } else if (!cast_supported(in_type, in_cs_type, out_type, out_cs_type)) { ret = OB_ERR_INVALID_TYPE_FOR_OP; LOG_WARN("transition does not support", K(in_type), K(out_type)); } else if (src_type.is_null() || dst_type.is_null()) { // null -> xxx or xxx -> null // xxx->null will report an error. need_cast = true; } else { need_cast = true; } LOG_DEBUG("check_need_cast_expr", K(ret), K(need_cast), K(src_type), K(dst_type)); return ret; } // private member, use create_cast_expr() instead. int ObRawExprUtils::create_real_cast_expr(ObRawExprFactory& expr_factory, ObRawExpr* src_expr, const ObExprResType& dst_type, ObSysFunRawExpr*& func_expr, const ObSQLSessionInfo* session_info) { int ret = OB_SUCCESS; ObConstRawExpr* dst_expr = NULL; ParseNode parse_node; ObObj val; if (OB_ISNULL(src_expr) || OB_ISNULL(session_info)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", KP(src_expr), KP(session_info)); } else { if (OB_FAIL(expr_factory.create_raw_expr(T_FUN_SYS_CAST, func_expr))) { LOG_WARN("create cast expr failed", K(ret)); } else if (OB_FAIL(expr_factory.create_raw_expr(T_INT, dst_expr))) { LOG_WARN("create dest type expr failed", K(ret)); } else if (OB_FAIL(func_expr->add_param_expr(src_expr))) { LOG_WARN("add real param expr failed", K(ret)); } else { func_expr->set_orig_expr(src_expr); ObString func_name = ObString::make_string(N_CAST); parse_node.int16_values_[OB_NODE_CAST_TYPE_IDX] = static_cast(dst_type.get_type()); parse_node.int16_values_[OB_NODE_CAST_COLL_IDX] = static_cast(dst_type.get_collation_type()); if (ob_is_string_or_lob_type(dst_type.get_type())) { parse_node.int32_values_[OB_NODE_CAST_C_LEN_IDX] = dst_type.get_length(); if (share::is_oracle_mode()) { dst_expr->set_length_semantics(dst_type.get_length_semantics()); } } else if (ob_is_rowid_tc(dst_type.get_type())) { int32_t urowid_len = dst_type.get_length(); if (urowid_len <= -1) { urowid_len = 4000; } parse_node.int32_values_[OB_NODE_CAST_C_LEN_IDX] = 4000; } else if (ObIntervalYMType == dst_type.get_type()) { parse_node.int16_values_[OB_NODE_CAST_N_SCALE_IDX] = dst_type.get_scale(); // year } else if (ObIntervalDSType == dst_type.get_type()) { parse_node.int16_values_[OB_NODE_CAST_N_PREC_IDX] = (dst_type.get_scale() / 10); // day parse_node.int16_values_[OB_NODE_CAST_N_SCALE_IDX] = (dst_type.get_scale() % 10); // second } else { parse_node.int16_values_[OB_NODE_CAST_N_PREC_IDX] = dst_type.get_precision(); parse_node.int16_values_[OB_NODE_CAST_N_SCALE_IDX] = dst_type.get_scale(); } val.set_int(parse_node.value_); dst_expr->set_value(val); dst_expr->set_param(val); func_expr->set_func_name(func_name); if (src_expr->is_for_generated_column()) { func_expr->set_for_generated_column(); } if (OB_FAIL(func_expr->add_param_expr(dst_expr))) { LOG_WARN("add dest type expr failed", K(ret)); } LOG_DEBUG("create_cast_expr debug", K(ret), K(*src_expr), K(dst_type), K(*func_expr), K(lbt())); } } return ret; } int ObRawExprUtils::build_add_expr( ObRawExprFactory& expr_factory, ObRawExpr* param_expr1, ObRawExpr* param_expr2, ObOpRawExpr*& add_expr) { int ret = OB_SUCCESS; if (OB_ISNULL(param_expr1) || OB_ISNULL(param_expr2)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid argument", K(param_expr1), K(param_expr2), K(ret)); } else if (OB_FAIL(expr_factory.create_raw_expr(T_OP_ADD, add_expr))) { LOG_WARN("create add expr failed", K(ret)); } else if (OB_ISNULL(add_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("add expr is null", K(ret), K(add_expr)); } else if (OB_FAIL(add_expr->add_param_expr(param_expr1))) { LOG_WARN("add text expr to add expr failed", K(ret)); } else if (OB_FAIL(add_expr->add_param_expr(param_expr2))) { LOG_WARN("add pattern expr to add expr failed", K(ret)); } return ret; } int ObRawExprUtils::build_minus_expr( ObRawExprFactory& expr_factory, ObRawExpr* param_expr1, ObRawExpr* param_expr2, ObOpRawExpr*& minus_expr) { int ret = OB_SUCCESS; if (OB_ISNULL(param_expr1) || OB_ISNULL(param_expr2)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid argument", K(param_expr1), K(param_expr2), K(ret)); } else if (OB_FAIL(expr_factory.create_raw_expr(T_OP_MINUS, minus_expr))) { LOG_WARN("create minus expr failed", K(ret)); } else if (OB_ISNULL(minus_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("minus expr is null", K(ret), K(minus_expr)); } else if (OB_FAIL(minus_expr->add_param_expr(param_expr1))) { LOG_WARN("add text expr to minus expr failed", K(ret)); } else if (OB_FAIL(minus_expr->add_param_expr(param_expr2))) { LOG_WARN("add pattern expr to minus expr failed", K(ret)); } return ret; } int ObRawExprUtils::build_date_add_expr(ObRawExprFactory& expr_factory, ObRawExpr* param_expr1, ObRawExpr* param_expr2, ObRawExpr* param_expr3, ObSysFunRawExpr*& date_add_expr) { int ret = OB_SUCCESS; if (OB_ISNULL(param_expr1) || OB_ISNULL(param_expr2) || OB_ISNULL(param_expr3)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid argument", K(param_expr1), K(param_expr2), K(param_expr3), K(ret)); } else if (OB_FAIL(expr_factory.create_raw_expr(T_FUN_SYS_DATE_ADD, date_add_expr))) { LOG_WARN("create to_type expr failed", K(ret)); } else if (OB_ISNULL(date_add_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("date add expr is null", K(ret), K(date_add_expr)); } else if (OB_FAIL(date_add_expr->set_param_exprs(param_expr1, param_expr2, param_expr3))) { LOG_WARN("add param expr failed", K(ret)); } else { ObString func_name = ObString::make_string("date_add"); date_add_expr->set_func_name(func_name); } return ret; } int ObRawExprUtils::build_date_sub_expr(ObRawExprFactory& expr_factory, ObRawExpr* param_expr1, ObRawExpr* param_expr2, ObRawExpr* param_expr3, ObSysFunRawExpr*& date_sub_expr) { int ret = OB_SUCCESS; if (OB_ISNULL(param_expr1) || OB_ISNULL(param_expr2) || OB_ISNULL(param_expr3)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid argument", K(param_expr1), K(param_expr2), K(param_expr3), K(ret)); } else if (OB_FAIL(expr_factory.create_raw_expr(T_FUN_SYS_DATE_SUB, date_sub_expr))) { LOG_WARN("create to_type expr failed", K(ret)); } else if (OB_ISNULL(date_sub_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("date sub expr is null", K(ret), K(date_sub_expr)); } else if (OB_FAIL(date_sub_expr->set_param_exprs(param_expr1, param_expr2, param_expr3))) { LOG_WARN("add param expr failed", K(ret)); } else { ObString func_name = ObString::make_string("date_sub"); date_sub_expr->set_func_name(func_name); } return ret; } int ObRawExprUtils::build_common_binary_op_expr(ObRawExprFactory& expr_factory, const ObItemType expect_op_type, ObRawExpr* param_expr1, ObRawExpr* param_expr2, ObRawExpr*& expr) { int ret = OB_SUCCESS; ObOpRawExpr* op_expr = NULL; if (OB_ISNULL(param_expr1) || OB_ISNULL(param_expr2)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid argument", K(param_expr1), K(param_expr2), K(ret)); } else if (OB_FAIL(expr_factory.create_raw_expr(expect_op_type, op_expr))) { LOG_WARN("create op expr failed", K(ret)); } else if (OB_ISNULL(op_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("add expr is null", K(ret), K(op_expr)); } else if (OB_FAIL(op_expr->add_param_expr(param_expr1))) { LOG_WARN("add text expr to add expr failed", K(ret)); } else if (OB_FAIL(op_expr->add_param_expr(param_expr2))) { LOG_WARN("add pattern expr to add expr failed", K(ret)); } else { expr = op_expr; } return ret; } int ObRawExprUtils::build_case_when_expr(ObRawExprFactory& expr_factory, ObRawExpr* when_expr, ObRawExpr* then_expr, ObRawExpr* default_expr, ObRawExpr*& case_when_expr) { int ret = OB_SUCCESS; ObCaseOpRawExpr* c_case_when_expr = NULL; if (OB_ISNULL(when_expr) || OB_ISNULL(then_expr) || OB_ISNULL(default_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid argument", K(when_expr), K(then_expr), K(default_expr), K(ret)); } else if (OB_FAIL(expr_factory.create_raw_expr(T_OP_CASE, c_case_when_expr))) { LOG_WARN("create add expr failed", K(ret)); } else if (OB_ISNULL(c_case_when_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret), K(c_case_when_expr)); } else if (OB_FAIL(c_case_when_expr->add_when_param_expr(when_expr))) { LOG_WARN("failed to add when param expr", K(ret)); } else if (OB_FAIL(c_case_when_expr->add_then_param_expr(then_expr))) { LOG_WARN("failed to add then expr", K(ret)); } else { c_case_when_expr->set_default_param_expr(default_expr); case_when_expr = c_case_when_expr; } return ret; } int ObRawExprUtils::build_is_not_expr(ObRawExprFactory& expr_factory, ObRawExpr* param_expr1, ObRawExpr* param_expr2, ObRawExpr* param_expr3, ObRawExpr*& is_not_expr) { int ret = OB_SUCCESS; ObOpRawExpr* not_expr = NULL; if (OB_ISNULL(param_expr1) || OB_ISNULL(param_expr2) || OB_ISNULL(param_expr3)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid argument", K(param_expr1), K(param_expr2), K(param_expr3), K(ret)); } else if (OB_FAIL(expr_factory.create_raw_expr(T_OP_IS_NOT, not_expr))) { LOG_WARN("failed to create a new expr", K(ret)); } else if (OB_ISNULL(not_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("not_expr is null", K(ret), K(not_expr)); } else if (OB_FAIL(not_expr->set_param_exprs(param_expr1, param_expr2, param_expr3))) { LOG_WARN("failed to set param for not expr", K(ret), K(not_expr)); } else { is_not_expr = not_expr; } return ret; } int ObRawExprUtils::build_is_not_null_expr( ObRawExprFactory& expr_factory, ObRawExpr* param_expr, ObRawExpr*& is_not_null_expr) { int ret = OB_SUCCESS; ObConstRawExpr* null_expr = NULL; ObConstRawExpr* flag_expr = NULL; ObOpRawExpr* is_not_expr = NULL; is_not_null_expr = NULL; if (OB_ISNULL(param_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid argument", K(param_expr), K(ret)); } else if (OB_FAIL(expr_factory.create_raw_expr(T_OP_IS_NOT, is_not_expr))) { LOG_WARN("failed to create a new expr", K(ret)); } else if (OB_FAIL(expr_factory.create_raw_expr(T_NULL, null_expr))) { LOG_WARN("failed to create const null expr", K(ret)); } else if (OB_FAIL(expr_factory.create_raw_expr(T_BOOL, flag_expr))) { LOG_WARN("failed to create flag bool expr", K(ret)); } else if (OB_ISNULL(is_not_expr) || OB_ISNULL(null_expr) || OB_ISNULL(flag_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("failed to create not null expr", K(ret)); } else { ObObjParam null_val; null_val.set_null(); null_val.set_param_meta(); null_expr->set_param(null_val); null_expr->set_value(null_val); ObObjParam flag_val; flag_val.set_bool(false); flag_val.set_param_meta(); flag_expr->set_param(flag_val); flag_expr->set_value(flag_val); } if (OB_FAIL(ret)) { } else if (OB_FAIL(is_not_expr->set_param_exprs(param_expr, null_expr, flag_expr))) { LOG_WARN("failed to set param for not_null op", K(ret), K(*is_not_expr)); } else { is_not_null_expr = is_not_expr; } return ret; } int ObRawExprUtils::process_window_complex_agg_expr(ObRawExprFactory& expr_factory, const ObItemType func_type, ObWinFunRawExpr* win_func, ObRawExpr*& window_agg_expr, ObIArray* win_exprs) { int ret = OB_SUCCESS; bool is_stack_overflow = false; if (OB_ISNULL(win_func) || OB_ISNULL(window_agg_expr) || OB_ISNULL(win_exprs)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("get unexpected null", K(ret), K(win_func), K(window_agg_expr), K(win_exprs)); } else if (OB_FAIL(check_stack_overflow(is_stack_overflow))) { LOG_WARN("check stack overflow failed", K(ret), K(is_stack_overflow)); } else if (is_stack_overflow) { ret = OB_SIZE_OVERFLOW; LOG_WARN("too deep recursive", K(ret), K(is_stack_overflow)); } else if (ObOptimizerUtil::find_item(*win_exprs, window_agg_expr)) { /*do nothing*/ } else if (T_FUN_SUM == func_type || T_FUN_COUNT == func_type || T_FUN_KEEP_SUM == func_type || T_FUN_KEEP_COUNT == func_type) { ObWinFunRawExpr* win_func_expr = NULL; ObAggFunRawExpr* agg_expr = static_cast(window_agg_expr); if (agg_expr->is_param_distinct() && (win_func->has_order_items() || win_func->has_frame_orig())) { ret = OB_ORDERBY_CLAUSE_NOT_ALLOWED; } else if (OB_FAIL(expr_factory.create_raw_expr(T_WINDOW_FUNCTION, win_func_expr))) { LOG_WARN("failed to create window function expr", K(ret)); } else if (OB_ISNULL(win_func_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("win_func_expr is null", K(ret), K(win_func_expr)); } else if (OB_FAIL(win_func_expr->assign(*win_func))) { LOG_WARN("failed to assigned win func expr.", K(ret)); } else if (FALSE_IT(win_func_expr->set_agg_expr(agg_expr))) { LOG_WARN("failed to set agg expr.", K(ret)); } else if (FALSE_IT(window_agg_expr = win_func_expr)) { LOG_WARN("failed to replace the agg expr.", K(ret)); } else if (FALSE_IT(win_func_expr->set_func_type(func_type))) { LOG_WARN("failed to set func type.", K(ret)); } else if (OB_FAIL(win_exprs->push_back(win_func_expr))) { LOG_WARN("failed to push back win func epxr.", K(ret)); } else { /*do nothing */ } } else { for (int64_t i = 0; OB_SUCC(ret) && i < window_agg_expr->get_param_count(); i++) { ObRawExpr*& sub_expr = window_agg_expr->get_param_expr(i); if (OB_ISNULL(sub_expr)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("error argument.", K(ret)); } else if (OB_FAIL(process_window_complex_agg_expr( expr_factory, sub_expr->get_expr_type(), win_func, sub_expr, win_exprs))) { LOG_WARN("failed to process window complex agg node.", K(ret)); } else { /*do nothing*/ } } } return ret; } int ObRawExprUtils::build_common_aggr_expr(ObRawExprFactory& expr_factory, ObSQLSessionInfo* session_info, const ObItemType expect_op_type, ObRawExpr* param_expr, ObAggFunRawExpr*& aggr_expr) { int ret = OB_SUCCESS; aggr_expr = NULL; if (OB_ISNULL(param_expr) || OB_ISNULL(session_info)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret), K(param_expr), K(session_info)); } else if (OB_FAIL(expr_factory.create_raw_expr(expect_op_type, aggr_expr))) { LOG_WARN("create ObAggFunRawExpr failed", K(ret)); } else if (OB_ISNULL(aggr_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("agg_expr is null", K(ret), K(aggr_expr)); } else if (OB_FAIL(aggr_expr->add_real_param_expr(param_expr))) { LOG_WARN("failed to add param expr to agg expr", K(ret)); } else if (OB_FAIL(aggr_expr->formalize(session_info))) { LOG_WARN("failed to extract info", K(ret)); } else { /*do nothing */ } return ret; } // only use for limit_expr/offset_expr, for constructing case when limit_expr < 0 then 0 else limit_expr end int ObRawExprUtils::build_case_when_expr_for_limit( ObRawExprFactory& expr_factory, ObRawExpr* limit_expr, ObRawExpr*& expected_case_when_expr) { int ret = OB_SUCCESS; expected_case_when_expr = NULL; ObRawExpr* case_when_expr = NULL; ObRawExpr* less_expr = NULL; ObConstRawExpr* zero_expr = NULL; if (OB_ISNULL(limit_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret)); } else if (OB_FAIL(build_const_int_expr(expr_factory, ObIntType, 0, zero_expr))) { LOG_WARN("failed to build const int expr", K(ret)); } else if (OB_FAIL(build_common_binary_op_expr(expr_factory, T_OP_LT, limit_expr, zero_expr, less_expr))) { LOG_WARN("failed to build common binary op expr", K(ret)); } else if (OB_FAIL(build_case_when_expr(expr_factory, less_expr, zero_expr, limit_expr, case_when_expr))) { LOG_WARN("failed to build case when expr", K(ret)); } else { expected_case_when_expr = case_when_expr; } return ret; } int ObRawExprUtils::build_not_expr(ObRawExprFactory& expr_factory, ObRawExpr* expr, ObRawExpr*& not_expr) { int ret = OB_SUCCESS; ObOpRawExpr* new_expr = NULL; if (OB_ISNULL(expr)) { LOG_WARN("expr has null", K(ret)); } else if (OB_FAIL(expr_factory.create_raw_expr(T_OP_NOT, new_expr))) { LOG_WARN("failed to create a new expr", K(ret)); } else if (OB_ISNULL(new_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("failed to create not expr", K(ret)); } else if (OB_FAIL(new_expr->set_param_expr(expr))) { LOG_WARN("failed to set param for not op", K(ret), K(*not_expr)); } else { not_expr = new_expr; } return ret; } int ObRawExprUtils::build_or_exprs( ObRawExprFactory& expr_factory, const ObIArray& exprs, ObRawExpr*& or_expr) { int ret = OB_SUCCESS; ObOpRawExpr* new_expr = NULL; or_expr = NULL; if (exprs.count() == 0) { or_expr = NULL; } else if (exprs.count() == 1) { or_expr = exprs.at(0); } else if (OB_FAIL(expr_factory.create_raw_expr(T_OP_OR, new_expr))) { LOG_WARN("failed to create a new expr", K(ret)); } else if (OB_ISNULL(new_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("failed to create or expr", K(ret)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < exprs.count(); ++i) { ObRawExpr* expr = exprs.at(i); if (OB_ISNULL(expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("exprs has null child", K(i)); } else if (OB_FAIL(new_expr->add_param_expr(expr))) { LOG_WARN("add param expr to or expr failed", K(ret)); } else { /*do nothing*/ } } if (OB_SUCC(ret)) { or_expr = new_expr; } else { /*do nothing*/ } } return ret; } int ObRawExprUtils::build_and_expr( ObRawExprFactory& expr_factory, const ObIArray& exprs, ObRawExpr*& and_expr) { int ret = OB_SUCCESS; ObOpRawExpr* new_expr = NULL; and_expr = NULL; if (exprs.count() == 0) { and_expr = NULL; } else if (exprs.count() == 1) { and_expr = exprs.at(0); } else if (OB_FAIL(expr_factory.create_raw_expr(T_OP_AND, new_expr))) { LOG_WARN("failed to create a new expr", K(ret)); } else if (OB_ISNULL(new_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("failed to create or expr", K(ret)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < exprs.count(); ++i) { ObRawExpr* expr = exprs.at(i); if (OB_ISNULL(expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("exprs has null child", K(i)); } else if (OB_FAIL(new_expr->add_param_expr(expr))) { LOG_WARN("add param expr to or expr failed", K(ret)); } else { /*do nothing*/ } } if (OB_SUCC(ret)) { and_expr = new_expr; } else { /*do nothing*/ } } return ret; } int ObRawExprUtils::new_parse_node( ParseNode*& node, ObRawExprFactory& expr_factory, ObItemType type, int num, ObString str_val) { int ret = OB_SUCCESS; char* str_value = NULL; if (OB_FAIL(new_parse_node(node, expr_factory, type, num))) { LOG_WARN("fail to alloc new node", K(ret)); } else if (str_val.length() <= 0) { /*nothing*/ } else if (OB_ISNULL(str_value = static_cast(expr_factory.get_allocator().alloc(str_val.length())))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to alloc buf", K(ret)); } else { MEMCPY(str_value, str_val.ptr(), str_val.length()); node->str_value_ = str_value; node->str_len_ = str_val.length(); } return ret; } int ObRawExprUtils::new_parse_node(ParseNode*& node, ObRawExprFactory& expr_factory, ObItemType type, int num) { int ret = OB_SUCCESS; ObIAllocator* alloc_buf = &(expr_factory.get_allocator()); node = (ParseNode*)alloc_buf->alloc(sizeof(ParseNode)); if (OB_ISNULL(node)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("allocate parse node failed", K(ret), K(node)); } else { node->type_ = type; node->num_child_ = num; node->param_num_ = 0; node->is_neg_ = 0; node->is_hidden_const_ = 0; node->is_date_unit_ = 0; node->is_tree_not_param_ = 0; node->value_ = INT64_MAX; node->str_len_ = 0; node->str_value_ = NULL; node->text_len_ = 0; node->raw_text_ = NULL; node->pos_ = 0; if (num > 0) { int64_t alloc_size = sizeof(ParseNode*) * num; node->children_ = (ParseNode**)alloc_buf->alloc(alloc_size); if (OB_ISNULL(node->children_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("allocate children buffer failed", K(ret), K(node->children_)); } } else { node->children_ = NULL; } } return ret; } int ObRawExprUtils::build_rownum_expr(ObRawExprFactory& expr_factory, ObRawExpr*& rownum_expr) { int ret = OB_SUCCESS; ObSysFunRawExpr* rownum = NULL; rownum_expr = NULL; if (OB_FAIL(expr_factory.create_raw_expr(T_FUN_SYS_ROWNUM, rownum))) { LOG_WARN("failed to create raw expr", K(ret)); } else if (OB_ISNULL(rownum)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("null expr", K(ret)); } else { rownum->set_func_name(ObString::make_string("rownum")); rownum->set_data_type(ObNumberType); rownum_expr = rownum; } return ret; } int ObRawExprUtils::build_to_outfile_expr(ObRawExprFactory& expr_factory, const ObSQLSessionInfo* session_info, const ObSelectIntoItem* into_item, const ObIArray& exprs, ObRawExpr*& to_outfile_expr) { int ret = OB_SUCCESS; to_outfile_expr = NULL; ObOpRawExpr* new_expr = NULL; ObConstRawExpr* filed_expr = NULL; ObConstRawExpr* line_expr = NULL; char* closed_cht_buf = NULL; ObConstRawExpr* closed_cht_expr = NULL; ObRawExpr* is_optional_expr = NULL; if (OB_FAIL(expr_factory.create_raw_expr(T_OP_TO_OUTFILE_ROW, new_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_FAIL(build_const_string_expr(expr_factory, ObVarcharType, into_item->filed_str_.get_varchar(), into_item->filed_str_.get_collation_type(), filed_expr))) { LOG_WARN("fail to create string expr", K(ret)); } else if (OB_FAIL(build_const_string_expr(expr_factory, ObVarcharType, into_item->line_str_.get_varchar(), into_item->line_str_.get_collation_type(), line_expr))) { LOG_WARN("fail to create string expr", K(ret)); } else if (OB_ISNULL(closed_cht_buf = static_cast(expr_factory.get_allocator().alloc(1)))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to alloc buf", K(ret)); } else if (FALSE_IT(closed_cht_buf[0] = into_item->closed_cht_)) { // do nothing } else if (OB_FAIL(build_const_string_expr(expr_factory, ObVarcharType, into_item->closed_cht_ == 0 ? ObString() : ObString(1, closed_cht_buf), into_item->filed_str_.get_collation_type(), closed_cht_expr))) { LOG_WARN("fail to create string expr", K(ret)); } else if (OB_FAIL(build_const_bool_expr(&expr_factory, is_optional_expr, into_item->is_optional_))) { LOG_WARN("fail to create bool expr", K(ret)); } else if (new_expr->add_param_expr(filed_expr)) { LOG_WARN("fail to add filed_expr", K(ret)); } else if (new_expr->add_param_expr(line_expr)) { LOG_WARN("fail to add line_expr", K(ret)); } else if (new_expr->add_param_expr(closed_cht_expr)) { LOG_WARN("fail to add closed_cht_expr", K(ret)); } else if (new_expr->add_param_expr(is_optional_expr)) { LOG_WARN("fail to add is_optional_expr", K(ret)); } else { for (int i = 0; i < exprs.count() && OB_SUCC(ret); ++i) { if (OB_FAIL(new_expr->add_param_expr(exprs.at(i)))) { LOG_WARN("fail to add param expr", K(i), K(ret)); } } } if (OB_SUCC(ret)) { if (OB_FAIL(new_expr->formalize(session_info))) { LOG_WARN("failed to formalize expr", K(ret)); } else { to_outfile_expr = new_expr; } } return ret; } } // namespace sql } // namespace oceanbase