/** * 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 "ob_raw_expr_resolver_impl.h" #include "common/ob_smart_call.h" #include "common/ob_common_utility.h" #include "ob_raw_expr_info_extractor.h" #include "sql/parser/sql_parser_base.h" #include "sql/resolver/ob_column_ref.h" #include "sql/resolver/ob_resolver_utils.h" #include "sql/resolver/expr/ob_raw_expr_util.h" #include "sql/resolver/dml/ob_select_stmt.h" #include "sql/parser/ob_parser_utils.h" #include "sql/engine/expr/ob_expr_case.h" #include "lib/json/ob_json_print_utils.h" #include "lib/string/ob_sql_string.h" #include "pl/ob_pl_type.h" #include "pl/ob_pl_resolver.h" #include "common/ob_smart_call.h" #include "share/schema/ob_udt_info.h" #include "sql/resolver/ob_stmt.h" #include "sql/resolver/dml/ob_del_upd_stmt.h" #include "deps/oblib/src/lib/json_type/ob_json_path.h" #include "share/resource_manager/ob_resource_manager.h" namespace oceanbase { using namespace common; namespace sql { ObRawExprResolverImpl::ObRawExprResolverImpl(ObExprResolveContext &ctx) : ctx_(ctx), is_contains_assignment_(false) { } int ObRawExprResolverImpl::resolve(const ParseNode *node, ObRawExpr *&expr, ObIArray &columns, ObIArray &sys_vars, ObIArray &sub_query_info, ObIArray &aggr_exprs, ObIArray &win_exprs, ObIArray &udf_info, ObIArray &op_exprs, ObIArray &user_var_exprs) { ctx_.columns_ = &columns; ctx_.op_exprs_ = &op_exprs; ctx_.sys_vars_ = &sys_vars; ctx_.sub_query_info_ = &sub_query_info; ctx_.aggr_exprs_ = &aggr_exprs; ctx_.win_exprs_ = &win_exprs; ctx_.udf_info_ = &udf_info; ctx_.user_var_exprs_ = &user_var_exprs; int ret = recursive_resolve(node, expr); if (OB_SUCC(ret)) { if (OB_FAIL(expr->extract_info())) { LOG_WARN("failed to extract info", K(ret), K(*expr)); } } return ret; } int ObRawExprResolverImpl::get_opposite_string(const common::ObString &orig_string, common::ObString &new_string, common::ObIAllocator &allocator) { int ret = OB_SUCCESS; char *tmp_buf = NULL; if (OB_UNLIKELY(orig_string.empty())) { ret = OB_INVALID_ARGUMENT; SQL_LOG(WARN, "invalid argument", K(ret)); } else { if ('-' == orig_string[0]) { new_string.assign_ptr(orig_string.ptr() + 1, orig_string.length() - 1); } else { if (OB_ISNULL(tmp_buf = (char*)(allocator.alloc(orig_string.length() + 1)))) { ret = OB_ALLOCATE_MEMORY_FAILED; SQL_LOG(WARN, "failed to allocate memory", "size", orig_string.length() + 1, K(ret)); } else { tmp_buf[0] = '-'; MEMCPY(tmp_buf + 1, orig_string.ptr(), orig_string.length()); new_string.assign_ptr(tmp_buf, orig_string.length() + 1); } } } return ret; } int ObRawExprResolverImpl::try_negate_const(ObRawExpr *&expr, const int64_t neg_cnt, int64_t &remain_neg_cnt) { int ret = OB_SUCCESS; remain_neg_cnt = neg_cnt; bool neg_const = false; const bool is_odd = neg_cnt % 2 == 1; if (neg_cnt > 0 && NULL != expr && expr->is_const_raw_expr()) { ObConstRawExpr *const_expr = static_cast(expr); const ObString &orig_literal_prefix = const_expr->get_literal_prefix(); neg_const = true; switch (const_expr->get_expr_type()) { case T_INT: { int64_t val = OB_INVALID_ID; if (OB_SUCC(const_expr->get_value().get_int(val))) { if (INT64_MIN == val) { // -val will overflow if val is INT64_MIN, we must use neg expr to handle this. neg_const = false; } else if (is_odd) { ObObj new_val; new_val.set_int(-val); const_expr->set_expr_type(T_INT); const_expr->set_value(new_val); const_expr->set_precision(static_cast( const_expr->get_accuracy().get_precision() + 1)); } } break; } case T_FLOAT: { float val = static_cast(OB_INVALID_ID); if (is_odd && OB_SUCC(const_expr->get_value().get_float(val))) { if (!isnan(val)) { // OB only store nan, don't add negative nan ObObj new_val; new_val.set_float(-val); new_val.set_scale(const_expr->get_accuracy().get_scale()); const_expr->set_expr_type(T_FLOAT); const_expr->set_value(new_val); const_expr->set_precision(static_cast(const_expr->get_accuracy().get_precision() + 1)); } } break; } case T_DOUBLE: { double val = static_cast(OB_INVALID_ID); if (is_odd && OB_SUCC(const_expr->get_value().get_double(val))) { if (!isnan(val)) { // OB only store nan, don't add negative nan ObObj new_val; new_val.set_double(-val); new_val.set_scale(const_expr->get_accuracy().get_scale()); const_expr->set_expr_type(T_DOUBLE); const_expr->set_value(new_val); const_expr->set_precision(static_cast(const_expr->get_accuracy().get_precision() + 1)); } } break; } case T_NUMBER: { number::ObNumber val; number::ObNumber negative_val; if (is_odd && OB_SUCC(const_expr->get_value().get_number(val)) && OB_SUCC(val.negate(negative_val, ctx_.expr_factory_.get_allocator()))) { ObObj new_val; new_val.set_number(negative_val); new_val.set_scale(const_expr->get_accuracy().get_scale()); const_expr->set_expr_type(T_NUMBER); const_expr->set_value(new_val); if (lib::is_oracle_mode()) { const_expr->set_precision(static_cast(const_expr->get_accuracy().get_precision())); } else { const_expr->set_precision(static_cast(const_expr->get_accuracy().get_precision() + 1)); } } break; } case T_NUMBER_FLOAT: { number::ObNumber val; number::ObNumber negative_val; if (is_odd && OB_SUCC(const_expr->get_value().get_number_float(val)) && OB_SUCC(val.negate(negative_val, ctx_.expr_factory_.get_allocator()))) { ObObj new_val; new_val.set_number_float(negative_val); const_expr->set_expr_type(T_NUMBER_FLOAT); const_expr->set_value(new_val); const_expr->set_precision(static_cast(const_expr->get_accuracy().get_precision())); } break; } default: { neg_const = false; break; } } if (OB_SUCC(ret)) { if (!orig_literal_prefix.empty() && neg_const && is_odd) { ObString new_literal_prefix; if (OB_FAIL(get_opposite_string(orig_literal_prefix, new_literal_prefix, ctx_.expr_factory_.get_allocator()))) { SQL_LOG(WARN, "fail to get_opposite_string", KPC(const_expr), K(ret)); } else { const_expr->set_literal_prefix(new_literal_prefix); } } SQL_LOG(DEBUG, "finish try_negate_const", KPC(expr), K(ret), K(neg_cnt), K(neg_const), K(remain_neg_cnt)); } } if (OB_FAIL(ret)) { // ObConstRawExpr::type_ and ObConstRawExpr::value_ type may mismatch, value_ may be number // wile type_ is T_INT. This will cause get value error, ignore it. ret = OB_SUCCESS; neg_const = false; } if (0 == neg_cnt || neg_const) { remain_neg_cnt = 0; } else { // Reduce negative count to 2 for even number, 3 for odd number. Why not 1 or 2: // // c1: bigint unsigned, values is 9223372036854775808 // -c1: -9223372036854775808 // --c1: report out of range error // ---c1: report out of range error // remain_neg_cnt = is_odd ? (neg_cnt > 2 ? 3 : 1) : 2; } return ret; } int ObRawExprResolverImpl::recursive_resolve(const ParseNode *node, ObRawExpr *&expr) { return SMART_CALL(do_recursive_resolve(node, expr)); } int ObRawExprResolverImpl::do_recursive_resolve(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; bool is_stack_overflow = false; expr = NULL; if (OB_ISNULL(node)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(node)); } else if (OB_FAIL(check_stack_overflow(is_stack_overflow))) { LOG_WARN("failed to do stack overflow check", K(ret)); } else if (is_stack_overflow) { ret = OB_SIZE_OVERFLOW; LOG_WARN("stack overflow", K(ret)); } else { LOG_DEBUG("resolve item", "item_type", get_type_name(node->type_)); if (IS_DATATYPE_OR_QUESTIONMARK_OP(node->type_)) { if (OB_FAIL(process_datatype_or_questionmark(*node, expr))) { LOG_WARN("fail to process datetype or questionmark", K(ret), K(node)); } } else { switch (node->type_) { case T_DEFAULT: { ObConstRawExpr *c_expr = NULL; if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(node->type_, c_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else { expr = c_expr; } break; } case T_DEFAULT_INT: { ObConstRawExpr *c_expr = NULL; if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_INT, c_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(c_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("const expr is null"); } else { ObObj val; val.set_int(node->value_); c_expr->set_value(val); c_expr->set_param(val); expr = c_expr; } break; } case T_SFU_DOUBLE: { ParseNode *tmp_node = const_cast(node); tmp_node->type_ = T_DOUBLE; if (OB_FAIL(process_datatype_or_questionmark(*tmp_node, expr))) { LOG_WARN("fail to process datetype or questionmark", K(ret), K(tmp_node)); } else {/*do nothing*/} break; } case T_CAST_ARGUMENT: { ObConstRawExpr *c_expr = NULL; if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_INT, c_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(c_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("const expr is null"); } else { ObObj val; ObObjType data_type = static_cast(node->int16_values_[OB_NODE_CAST_TYPE_IDX]); if (ob_is_string_tc(data_type)) { int32_t len = node->int32_values_[1]; if (lib::is_oracle_mode()) { if (OB_UNLIKELY(0 == len)) { ret = OB_ERR_ZERO_LEN_COL; LOG_WARN("Oracle not allowed zero length", K(ret)); } else if (((ObVarcharType == data_type || ObNVarchar2Type == data_type) && OB_MAX_ORACLE_VARCHAR_LENGTH < len) || ((ObCharType == data_type || ObNCharType == data_type) && OB_MAX_ORACLE_CHAR_LENGTH_BYTE < len)) { ret = OB_ERR_TOO_LONG_COLUMN_LENGTH; LOG_WARN("column data length is invalid", K(ret), K(len), K(data_type)); LOG_USER_ERROR(OB_ERR_TOO_LONG_COLUMN_LENGTH, "cast ", static_cast((ObVarcharType == data_type || ObNVarchar2Type == data_type) ? OB_MAX_ORACLE_VARCHAR_LENGTH : OB_MAX_ORACLE_CHAR_LENGTH_BYTE)); } else if (node->length_semantics_ == LS_DEFAULT) { const ObLengthSemantics default_length_semantics = (OB_NOT_NULL(ctx_.session_info_) ? ctx_.session_info_->get_actual_nls_length_semantics() : LS_BYTE); c_expr->set_length_semantics(default_length_semantics); } else if (OB_UNLIKELY(node->length_semantics_ != LS_BYTE && node->length_semantics_ != LS_CHAR)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("length_semantics_ is invalid", K(ret), K(node->length_semantics_)); } else { c_expr->set_length_semantics(node->length_semantics_); } } if (OB_SUCC(ret) && OUT_OF_STR_LEN == len) { ret = OB_ERR_TOO_BIG_DISPLAYWIDTH; int64_t max_str_len = static_cast(UINT32_MAX); LOG_USER_ERROR(OB_ERR_TOO_BIG_DISPLAYWIDTH, "cast of char", max_str_len); } } else if (ob_is_raw(data_type)) { int32_t len = node->int32_values_[1]; if (lib::is_oracle_mode()) { if (len > OB_MAX_ORACLE_RAW_PL_VAR_LENGTH || len < 0) { ret = OB_ERR_TOO_LONG_COLUMN_LENGTH; LOG_WARN("column data length is invalid", K(ret), K(len), K(data_type)); LOG_USER_ERROR(OB_ERR_TOO_LONG_COLUMN_LENGTH, "cast ", static_cast(OB_MAX_ORACLE_RAW_PL_VAR_LENGTH)); } else if (0 == len) { ret = OB_ERR_ZERO_LEN_COL; LOG_WARN("column data length cannot be zero on oracle mode", K(ret), K(len)); } } } else if (ob_is_extend(data_type)) { if (lib::is_mysql_mode()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("extend type in mysql is invalid", K(ret)); } else { const ParseNode *name_node = node->children_[0]; CK (OB_NOT_NULL(ctx_.session_info_), OB_NOT_NULL(ctx_.schema_checker_)); CK (OB_NOT_NULL(name_node)); CK (T_SP_TYPE == name_node->type_); if (OB_SUCC(ret)) { uint64_t udt_id = OB_INVALID_ID; uint64_t db_id = ctx_.session_info_->get_database_id(); ObString udt_name(name_node->children_[1]->str_len_, name_node->children_[1]->str_value_); if (NULL != name_node->children_[0]) { OZ (ctx_.schema_checker_->get_database_id(ctx_.session_info_->get_effective_tenant_id(), ObString(name_node->children_[0]->str_len_, name_node->children_[0]->str_value_), db_id)); } OZ (ctx_.schema_checker_->get_udt_id(ctx_.session_info_->get_effective_tenant_id(), db_id, OB_INVALID_ID, ObString(name_node->children_[1]->str_len_, name_node->children_[1]->str_value_), udt_id)); if (OB_SUCC(ret) && OB_INVALID_ID == udt_id) { if(OB_FAIL(ctx_.schema_checker_->get_udt_id(OB_SYS_TENANT_ID, OB_SYS_DATABASE_ID, OB_INVALID_ID, udt_name, udt_id))) { LOG_WARN("get udt id from sys fail", K(ret), K(udt_name)); } } if (OB_SUCC(ret)) { if (OB_INVALID_ID == udt_id) { ret = OB_ERR_INVALID_TYPE_FOR_ARGUMENT; LOG_WARN("Invalid type to cast", K(ObString(name_node->children_[1]->str_len_, name_node->children_[1]->str_value_)), K(ret)); } else { c_expr->set_udt_id(udt_id); } } } } } if (OB_SUCC(ret)) { if (is_oracle_mode()) { val.set_int(node->value_); } else { ObCollationType coll_type = static_cast(node->int16_values_[OB_NODE_CAST_COLL_IDX]); if (CS_TYPE_INVALID != coll_type) { // do nothing, for cast('a' as binary) } else if (NULL != node->str_value_) { // for cast('a' as char char set cs_name) ObString cs_name = ObString(node->str_value_); ObCharsetType charset_type = CHARSET_INVALID; if (CHARSET_INVALID == (charset_type = ObCharset::charset_type(cs_name.trim()))) { ret = OB_ERR_UNKNOWN_CHARSET; LOG_WARN("unknown charset", K(ret), K(cs_name)); } else { coll_type = ObCharset::get_default_collation(charset_type); } } else { // use connection_collation. for cast('a' as char) if (OB_ISNULL(ctx_.session_info_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected collation type", K(ret)); } else if (OB_FAIL(ctx_.session_info_->get_collation_connection(coll_type))) { LOG_WARN("failed to get collation", K(ret)); } } if (OB_SUCC(ret)) { ParseNode tmp_node; tmp_node.value_ = node->value_; tmp_node.int16_values_[OB_NODE_CAST_COLL_IDX] = coll_type; val.set_int(tmp_node.value_); } } c_expr->set_value(val); c_expr->set_param(val); expr = c_expr; } } break; } case T_CHAR_CHARSET: { //for char(), we need to set collation to first obj which will be used during //calc_result_type if (OB_FAIL(process_char_charset_node(node, expr))) { LOG_WARN("fail to process char charset node", K(ret), K(node)); } break; } case T_LEFT_VALUE: { // @user_var := xxx; if (OB_FAIL(process_left_value_node(node, expr))) { LOG_WARN("fail to process left_value node", K(ret), K(node)); } break; } case T_SYSTEM_VARIABLE: { if (OB_FAIL(process_system_variable_node(node, expr))) { LOG_WARN("fail to process system variable node", K(ret), K(node)); } break; } case T_OP_ORACLE_OUTER_JOIN_SYMBOL: { if (OB_FAIL(process_outer_join_symbol_node(node, expr))) { LOG_WARN("fail to process outer join column ref node", K(ret), K(node)); } break; } case T_COLUMN_REF: { // star has been expand before, @see ObSelectResolver::resolve_star() if (OB_FAIL(process_column_ref_node(node, expr))) { LOG_WARN("fail to process column ref node", K(ret), K(node)); } break; } case T_OP_EXISTS: //fall through case T_ANY: //fall through case T_ALL: { if (OB_FAIL(process_any_or_all_node(node, expr))) { LOG_WARN("fail to process any or all node", K(ret), K(node)); } break; } case T_OP_GET_USER_VAR: { if (OB_FAIL(process_user_var_node(node, expr))) { LOG_WARN("fail to process any or all node", K(ret), K(node)); } break; } case T_FUN_PLSQL_VARIABLE: { if (OB_FAIL(process_plsql_var_node(node, expr))) { LOG_WARN("failed to process plsql variable node", K(ret), K(node)); } break; } case T_OP_NOT: { if (OB_FAIL(process_not_node(node, expr))) { LOG_WARN("fail to process any or all node", K(ret), K(node)); } break; } case T_OP_POS: case T_OP_NEG: { if (OB_FAIL(process_pos_or_neg_node(node, expr))) { LOG_WARN("fail to process any or all node", K(ret), K(node)); } break; } case T_OP_AND: case T_OP_OR: case T_OP_XOR: { ObOpRawExpr *m_expr = NULL; int64_t num_child = 2; if (OB_FAIL(process_node_with_children(node, num_child, m_expr))) { LOG_WARN("fail to process node with children", K(ret), K(node)); } else if (OB_ISNULL(ctx_.session_info_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("session_info_ is NULL", K(ret)); } else if (OB_FAIL(ObRawExprUtils::try_add_bool_expr(m_expr, ctx_.expr_factory_))) { LOG_WARN("try_add_bool_expr for add or expr failed", K(ret)); } else { expr = m_expr; } break; } case T_OP_ASSIGN: case T_OP_ADD: case T_OP_MINUS: case T_OP_MUL: case T_OP_DIV: case T_OP_REM: case T_OP_POW: case T_OP_MOD: case T_OP_INT_DIV: case T_OP_LE: case T_OP_LT: case T_OP_EQ: case T_OP_NSEQ: case T_OP_GE: case T_OP_GT: case T_OP_NE: case T_OP_CNN: case T_OP_BIT_AND: case T_OP_BIT_OR: case T_OP_BIT_XOR: case T_OP_BIT_LEFT_SHIFT: case T_OP_BIT_RIGHT_SHIFT: { if (T_OP_ASSIGN == node->type_) { is_contains_assignment_ |= true; } if (OB_FAIL(process_operator_node(node, expr))) { LOG_WARN("fail to process any or all node", K(ret), K(node)); } break; } case T_OP_IS: case T_OP_IS_NOT: { if (OB_FAIL(process_is_or_is_not_node(node, expr))) { LOG_WARN("fail to process any or all node", K(ret), K(node)); } break; } case T_OP_BIT_NEG: { int64_t child_num = 1; ObOpRawExpr *b_expr = NULL; if (OB_FAIL(process_node_with_children(node, child_num, b_expr))) { LOG_WARN("fail to process node with child", K(ret), K(node->type_)); } else { expr = b_expr; } break; } case T_OP_CONNECT_BY_ROOT: { if (OB_FAIL(process_connect_by_root_node(*node, expr))) { LOG_WARN("fail to process connect_by_root node", K(ret)); } break; } case T_FUN_SYS_CONNECT_BY_PATH: { if (OB_FAIL(process_sys_connect_by_path_node(node, expr))) { LOG_WARN("fail to process sys_connect_by_path node", K(ret)); } break; } case T_OP_PRIOR: { if (OB_FAIL(process_prior_node(*node, expr))) { LOG_WARN("fail to process prior node", K(node), K(ret)); } break; } case T_OP_REGEXP: case T_OP_NOT_REGEXP: { if (OB_FAIL(process_regexp_or_not_regexp_node(node, expr))) { LOG_WARN("fail to process prgexp_or_not_pegexp node", K(ret), K(node)); } break; } case T_OP_BTW: case T_OP_NOT_BTW: { // We will transform between to >= and <= all the time in oracle mode // or while expr2 and expr3 have the same res types in mysql mode // // expr1 NOT BETWEEN expr2 AND expr3 ==> NOT (expr1 BETWEEN expr2 AND expr3) // expr1 BETWEEN expr2 AND expr3 ==> expr1 >= expr2 AND expr1 <= expr3 if (OB_FAIL(process_between_node(node, expr))) { LOG_WARN("fail to process between", K(ret), K(node)); } break; } case T_OP_LIKE: case T_OP_NOT_LIKE: { if (OB_FAIL(process_like_node(node, expr))) { LOG_WARN("fail to process like_or_between", K(ret), K(node)); } break; } case T_OP_IN: // get through case T_OP_NOT_IN: { if (OB_FAIL(process_in_or_not_in_node(node, expr))) { LOG_WARN("fail to process any or all node", K(ret), K(node)); } break; } case T_CASE: { if (OB_FAIL(process_case_node(node, expr))) { LOG_WARN("fail to process case node", K(ret), K(node)); } break; } case T_EXPR_LIST: { if (lib::is_oracle_mode()) { /* remove meaningless level */ ParseNode *child_node = NULL; for (int i = 0; i < node->num_child_; i++) { child_node = node->children_[i]; while (T_EXPR_LIST == child_node->type_ && 1 == child_node->num_child_) { child_node = child_node->children_[0]; } if (child_node->type_ != T_EXPR_LIST) { node->children_[i] = child_node; } } /* expr like (expr1) -> expr1 */ if (1 == node->num_child_ && T_EXPR_LIST != node->children_[0]->type_) { if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[0], expr)))) { LOG_WARN("fail to process node with children only", K(ret), K(node->children_[0]->type_), K(node->children_[0]->num_child_)); } break; } } ObOpRawExpr *multi_expr = NULL; if (OB_FAIL(process_node_with_children(node, node->num_child_, multi_expr))) { LOG_WARN("fail to process node with children", K(ret), K(node)); } else { multi_expr->set_expr_type(T_OP_ROW); expr = multi_expr; } break; } case T_SELECT: case T_INSERT: case T_DELETE: case T_UPDATE: { if (OB_FAIL(process_sub_query_node(node, expr))) { LOG_WARN("fail to process sub query node", K(ret), K(node)); } break; } case T_FUN_GROUP_ID: { if (lib::is_oracle_mode()) { ObAggFunRawExpr *agg_expr = NULL; if (OB_ISNULL(ctx_.aggr_exprs_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("aggr exprs is null", K(ret)); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(node->type_, agg_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(agg_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("agg_expr is null"); } else if (OB_FAIL(ctx_.aggr_exprs_->push_back(agg_expr))) { LOG_WARN("store aggr expr failed", K(ret)); } else { bool need_add_flag = !ctx_.parents_expr_info_.has_member(IS_AGG); if (need_add_flag && OB_FAIL(ctx_.parents_expr_info_.add_member(IS_AGG))) { LOG_WARN("failed to add member", K(ret)); } } expr = agg_expr; } else { ret = OB_ERR_UNEXPECTED; LOG_WARN("group_id is only allowed in oracle mode"); } break; } case T_FUN_GROUPING: case T_FUN_GROUPING_ID: case T_FUN_COUNT: case T_FUN_MAX: case T_FUN_MIN: case T_FUN_SUM: case T_FUN_AVG: case T_FUN_MEDIAN: case T_FUN_APPROX_COUNT_DISTINCT: case T_FUN_APPROX_COUNT_DISTINCT_SYNOPSIS: case T_FUN_APPROX_COUNT_DISTINCT_SYNOPSIS_MERGE: case T_FUN_STDDEV_POP: case T_FUN_STDDEV_SAMP: case T_FUN_STDDEV: case T_FUN_VARIANCE: case T_FUN_CORR: case T_FUN_COVAR_POP: case T_FUN_COVAR_SAMP: case T_FUN_VAR_POP: case T_FUN_VAR_SAMP: case T_FUN_REGR_SLOPE: case T_FUN_REGR_INTERCEPT: case T_FUN_REGR_R2: case T_FUN_REGR_COUNT: case T_FUN_REGR_AVGX: case T_FUN_REGR_AVGY: case T_FUN_REGR_SXX: case T_FUN_REGR_SYY: case T_FUN_REGR_SXY: case T_FUN_WM_CONCAT: case T_FUN_TOP_FRE_HIST: case T_FUN_HYBRID_HIST: case T_FUN_SYS_BIT_AND: case T_FUN_SYS_BIT_OR: case T_FUN_SYS_BIT_XOR: case T_FUN_JSON_ARRAYAGG: case T_FUN_JSON_OBJECTAGG: case T_FUN_ORA_JSON_ARRAYAGG: case T_FUN_ORA_JSON_OBJECTAGG: { if (OB_FAIL(process_agg_node(node, expr))) { LOG_WARN("fail to process agg node", K(ret), K(node)); } break; } case T_FUN_GROUP_CUME_DIST: case T_FUN_GROUP_RANK: case T_FUN_GROUP_DENSE_RANK: case T_FUN_GROUP_PERCENT_RANK: case T_FUN_GROUP_PERCENTILE_CONT: case T_FUN_GROUP_PERCENTILE_DISC: case T_FUN_GROUP_CONCAT: { if (OB_FAIL(process_group_aggr_node(node, expr))) { LOG_WARN("fail to process group concat node", K(ret), K(node)); } break; } case T_FUN_KEEP_MAX: case T_FUN_KEEP_SUM: case T_FUN_KEEP_MIN: case T_FUN_KEEP_COUNT: case T_FUN_KEEP_AVG: case T_FUN_KEEP_VARIANCE: case T_FUN_KEEP_STDDEV: case T_FUN_KEEP_WM_CONCAT: { if (OB_FAIL(process_keep_aggr_node(node, expr))) { LOG_WARN("fail to process keep aggr node", K(ret), K(node)); } break; } case T_FUN_SYS_UTC_TIMESTAMP: { ObString err_info("utc_timestamp"); if (OB_FAIL(process_timestamp_node(node, err_info, expr))) { LOG_WARN("fail to process timestamp node", K(ret), K(node)); } else { static_cast(expr)->set_func_name(ObString::make_string(N_UTC_TIMESTAMP)); } break; } case T_FUN_SYS_UTC_TIME: { ObString err_info("utc_time"); if (OB_FAIL(process_timestamp_node(node, err_info, expr))) { LOG_WARN("fail to process timestamp node", K(ret), K(node)); } else { static_cast(expr)->set_func_name(ObString::make_string(N_UTC_TIME)); } break; } case T_FUN_SYS_CUR_TIMESTAMP: { if (lib::is_oracle_mode()) { if (OB_FAIL(process_oracle_timestamp_node(node, expr, MIN_SCALE_FOR_TEMPORAL, OB_MAX_TIMESTAMP_TZ_PRECISION, DEFAULT_SCALE_FOR_ORACLE_FRACTIONAL_SECONDS))) { LOG_WARN("fail to process timestamp node", K(ret), K(node)); } } else { //oracle mode ObString err_info("now"); if (OB_FAIL(process_timestamp_node(node, err_info, expr))) { LOG_WARN("fail to process timestamp node", K(ret), K(node)); } } if (OB_SUCC(ret)) { static_cast(expr)->set_func_name(ObString::make_string(N_CUR_TIMESTAMP)); } break; } case T_FUN_SYS_LOCALTIMESTAMP: { if (lib::is_oracle_mode()) { if (OB_FAIL(process_oracle_timestamp_node(node, expr, MIN_SCALE_FOR_TEMPORAL, OB_MAX_TIMESTAMP_TZ_PRECISION, DEFAULT_SCALE_FOR_ORACLE_FRACTIONAL_SECONDS))) { LOG_WARN("fail to process timestamp node", K(ret), K(node)); } } else { //oracle mode ObString err_info("now"); if (OB_FAIL(process_timestamp_node(node, err_info, expr))) { LOG_WARN("fail to process timestamp node", K(ret), K(node)); } } if (OB_SUCC(ret)) { static_cast(expr)->set_func_name(ObString::make_string(N_LOCALTIMESTAMP)); } break; } case T_FUN_SYS_SYSDATE: { if (lib::is_oracle_mode()) { if (OB_FAIL(process_oracle_timestamp_node(node, expr, MIN_SCALE_FOR_TEMPORAL, OB_MAX_TIMESTAMP_TZ_PRECISION, DEFAULT_SCALE_FOR_DATE))) { LOG_WARN("fail to process timestamp node", K(ret), K(node)); } } else { //oracle mode ObString err_info("sysdate"); if (OB_FAIL(process_timestamp_node(node, err_info, expr))) { LOG_WARN("fail to process timestamp node", K(ret), K(node)); } } if (OB_SUCC(ret)) { static_cast(expr)->set_func_name(ObString::make_string(N_SYSDATE)); } break; } case T_FUN_SYS_CUR_TIME: { ObString err_info("current_time"); if (OB_FAIL(process_timestamp_node(node, err_info, expr))) { LOG_WARN("fail to process timestamp node", K(ret), K(node)); } else { static_cast(expr)->set_func_name(ObString::make_string(N_CUR_TIME)); } break; } case T_FUN_SYS_CUR_DATE: { ObSysFunRawExpr *f_expr = NULL; if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_FUN_SYS_CUR_DATE, f_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else { f_expr->set_func_name(ObString::make_string(N_CUR_DATE)); expr = f_expr; } break; } case T_FUN_SYS_UTC_DATE: { ObSysFunRawExpr *f_expr = NULL; if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_FUN_SYS_UTC_DATE, f_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else { f_expr->set_func_name(ObString::make_string(N_UTC_DATE)); expr = f_expr; } break; } case T_COLLATION: { // used in internal function `set_collation' to implement COLLATE clause if (OB_FAIL(process_collation_node(node, expr))) { LOG_WARN("fail to process collation node", K(ret), K(node)); } break; } case T_FUN_SYS_IF: { if (OB_FAIL(process_if_node(node, expr))) { LOG_WARN("fail to process if node", K(ret), K(node)); } break; } case T_FUN_SYS_INTERVAL: { if (OB_FAIL(process_fun_interval_node(node, expr))) { LOG_WARN("fail to process fun interval node", K(ret), K(node)); } break; } case T_FUN_SYS_ISNULL: { if (OB_FAIL(process_isnull_node(node, expr))) { LOG_WARN("fail to process ifnull node", K(ret), K(node)); } break; } case T_FUN_SYS_LNNVL: { if (OB_FAIL(process_lnnvl_node(node, expr))) { LOG_WARN("fail to process lnnvl node", K(ret), K(node)); } break; } case T_FUN_SYS_JSON_ARRAY: { if (OB_FAIL(process_json_array_node(node, expr))) { LOG_WARN("fail to process array node", K(ret), K(node)); } break; } case T_FUN_SYS_JSON_VALUE: { if (OB_FAIL(process_json_value_node(node, expr))) { LOG_WARN("fail to process js value node", K(ret), K(node)); } break; } case T_FUN_SYS_IS_JSON: { if (OB_FAIL(process_is_json_node(node, expr))) { LOG_WARN("fail to process is json node", K(ret), K(node)); } break; } case T_FUN_SYS_JSON_EQUAL: { if (OB_FAIL(process_json_equal_node(node, expr))) { LOG_WARN("fail to process json equal node", K(ret), K(node)); } break; } case T_FUN_SYS_JSON_MERGE_PATCH: { if (OB_FAIL(process_json_mergepatch_node(node, expr))) { LOG_WARN("fail to process json mergepatch node", K(ret), K(node)); } break; } case T_FUN_SYS_JSON_QUERY: { if (OB_FAIL(process_json_query_node(node, expr))) { LOG_WARN("fail to process lnnvl node", K(ret), K(node)); } break; } case T_FUN_SYS_JSON_EXISTS: { if (OB_FAIL(process_json_exists_node(node, expr))) { LOG_WARN("fail to process json_exists node", K(ret), K(node)); } break; } case T_FUN_SYS_JSON_OBJECT: { if (OB_FAIL(process_ora_json_object_node(node, expr))) { LOG_WARN("fail to process lnnvl node", K(ret), K(node)); } break; } case T_FUN_SYS_REGEXP_LIKE: case T_FUN_SYS: { if (OB_FAIL(process_fun_sys_node(node, expr))) { if (ret != OB_ERR_FUNCTION_UNKNOWN) { LOG_WARN("fail to process system function node", K(ret), K(node)); } else if (OB_FAIL(process_dll_udf_node(node, expr))) { if (ret != OB_ERR_FUNCTION_UNKNOWN) { LOG_WARN("fail to process dll user function node", K(ret), K(node)); } else { ParseNode *udf_node = NULL; ObString empty_db_name; ObString empty_pkg_name; bool record_udf_info = true; if (OB_FAIL(ObResolverUtils::transform_func_sys_to_udf(&ctx_.expr_factory_.get_allocator(), node, empty_db_name, empty_pkg_name, udf_node))) { LOG_WARN("transform func sys to udf node failed", K(ret)); ret = OB_ERR_FUNCTION_UNKNOWN; } else if (OB_FAIL(process_udf_node(udf_node, record_udf_info, expr))) { LOG_WARN("fail to process user defined function node", K(ret), K(node)); if(get_udf_param_syntax_err()) { // do nothing } else { ObString func_name(node->children_[0]->str_len_, node->children_[0]->str_value_); ret = OB_ERR_WRONG_PARAMETERS_TO_NATIVE_FCT; LOG_USER_ERROR(OB_ERR_WRONG_PARAMETERS_TO_NATIVE_FCT, func_name.length(), func_name.ptr()); } } } } } break; } case T_FUN_UDF: { bool record_udf_info = true; if (OB_FAIL(process_udf_node(node, record_udf_info, expr))) { LOG_WARN("fail to process user defined function node", K(ret), K(node)); } break; } case T_WINDOW_FUNCTION: { const int64_t orig_win_func_cnt = ctx_.win_exprs_->count(); if (OB_FAIL(process_window_function_node(node, expr))) { LOG_WARN("process window function failed", K(ret)); } for (int64_t i = orig_win_func_cnt; OB_SUCC(ret) && i < ctx_.win_exprs_->count(); ++i) { if (OB_FAIL(check_and_canonicalize_window_expr(ctx_.win_exprs_->at(i)))) { LOG_WARN("check and canonicalize window expr failed", K(ret)); } } if (OB_SUCC(ret)) { // remove aggr generated by window_function ObIArray &aggr_exprs = *ctx_.aggr_exprs_; ObSEArray clone_aggr_exprs; ret = clone_aggr_exprs.assign(aggr_exprs); aggr_exprs.reset(); for (int64_t i = 0; OB_SUCC(ret) && i < clone_aggr_exprs.count(); ++i) { bool exist = false; for (int64_t j = orig_win_func_cnt; j < ctx_.win_exprs_->count(); ++j) { if (clone_aggr_exprs.at(i) == ctx_.win_exprs_->at(j)->get_agg_expr()) { exist = true; break; } } if (!exist) { ret = aggr_exprs.push_back(clone_aggr_exprs.at(i)); } } } break; } case T_IDENT: { if (OB_FAIL(process_ident_node(*node, expr))) { LOG_WARN("process obj access node failed", K(ret)); } break; } case T_OBJ_ACCESS_REF: { if (OB_FAIL(process_obj_access_node(*node, expr))) { LOG_WARN("process obj access node failed", K(ret)); } break; } case T_SP_EXPLICIT_CURSOR_ATTR: case T_SP_IMPLICIT_CURSOR_ATTR: { if (OB_FAIL(process_cursor_attr_node(*node, expr))) { LOG_WARN("process cursor attr node failed", K(ret)); } break; } case T_PSEUDO_COLUMN: { if (OB_FAIL(process_pseudo_column_node(*node, expr))) { LOG_WARN("fail to process pseudo column", K(ret)); } break; } case T_FUN_SYS_SYSTIMESTAMP: { if (OB_FAIL(process_oracle_timestamp_node(node, expr, MIN_SCALE_FOR_TEMPORAL, OB_MAX_TIMESTAMP_TZ_PRECISION, DEFAULT_SCALE_FOR_ORACLE_FRACTIONAL_SECONDS))) { LOG_WARN("fail to process timestamp node", K(ret), K(node)); } else { static_cast(expr)->set_func_name(ObString::make_string(N_SYSTIMESTAMP)); } break; } case T_SP_CPARAM: { OZ (process_call_param_node(node, expr)); break; } case T_OP_COLL_PRED: case T_OP_MULTISET :{ OZ (process_multiset_node(node, expr)); break; } case T_FUN_SYS_DML_EVENT: { OZ (process_dml_event_node(node, expr)); break; } case T_FUN_SYS_PART_HASH: case T_FUN_SYS_PART_KEY: case T_FUN_SYS_SET_COLLATION: { OZ (process_internal_sys_function_node(node, expr, node->type_)); break; } case T_ODBC_ESCAPE_SEQUENCES: { if (OB_FAIL(process_odbc_escape_sequences(node, expr))) { LOG_WARN("failed to process odbc escape sequences", K(ret)); } break; } case T_FUN_SYS_POINT: case T_FUN_SYS_LINESTRING: case T_FUN_SYS_MULTIPOINT: case T_FUN_SYS_MULTILINESTRING: case T_FUN_SYS_POLYGON: case T_FUN_SYS_MULTIPOLYGON: case T_FUN_SYS_GEOMCOLLECTION: { OZ (process_geo_func_node(node, expr)); break; } default: ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("Wrong type in expression", K(get_type_name(node->type_))); break; } } } return ret; } int ObRawExprResolverImpl::process_multiset_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; if (OB_ISNULL(node)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("parse node is null", K(ret)); } else if (OB_FAIL(process_operator_node(node, expr))) { LOG_WARN("process node failed.", K(ret)); } else if (OB_ISNULL(expr)) { LOG_WARN("expr is null", K(ret)); } else { if (T_OP_MULTISET == node->type_) { ObMultiSetRawExpr *ms_expr = static_cast(expr); ms_expr->set_multiset_type(static_cast(node->int32_values_[1])); ms_expr->set_multiset_modifier(static_cast(node->int32_values_[0])); } else { ObCollPredRawExpr *ms_expr = static_cast(expr); ms_expr->set_multiset_type(static_cast(node->int32_values_[1])); ms_expr->set_multiset_modifier(static_cast(node->int32_values_[0])); } } return ret; } int ObRawExprResolverImpl::process_ident_node(const ParseNode &node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObQualifiedName q_name; if (OB_ISNULL(ctx_.columns_)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K_(ctx_.columns)); } else { ObString ident_name(static_cast(node.str_len_), node.str_value_); ObObjAccessIdent access_ident(ident_name, OB_INVALID_INDEX); if (OB_FAIL(q_name.access_idents_.push_back(access_ident))) { LOG_WARN("push back access ident failed", K(ret)); } else { q_name.format_qualified_name(ctx_.case_mode_); q_name.parents_expr_info_ = ctx_.parents_expr_info_; ObColumnRefRawExpr *b_expr = NULL; if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_REF_COLUMN, b_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(b_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("column ref expr is null"); } else { q_name.ref_expr_ = b_expr; if (OB_FAIL(ctx_.columns_->push_back(q_name))) { LOG_WARN("Add column failed", K(ret)); } else { expr = b_expr; } } } } return ret; } int ObRawExprResolverImpl::process_cursor_attr_node(const ParseNode &node, ObRawExpr *&expr) { int ret = OB_SUCCESS; pl::ObPLGetCursorAttrInfo info; ObRawExpr *child_expr = NULL; ObPLGetCursorAttrRawExpr *c_expr = NULL; int64_t child_start = ctx_.columns_->count(); CK (node.type_ == T_SP_EXPLICIT_CURSOR_ATTR || node.type_ == T_SP_IMPLICIT_CURSOR_ATTR); OZ (ctx_.expr_factory_.create_raw_expr(T_FUN_PL_GET_CURSOR_ATTR, c_expr)); CK (OB_NOT_NULL(c_expr)); OX (static_cast(c_expr) ->set_func_name(ObString::make_string(N_PL_GET_CURSOR_ATTR))); if (OB_FAIL(ret)) { } else if (T_SP_EXPLICIT_CURSOR_ATTR == node.type_) { CK (OB_NOT_NULL(node.children_[0])); OV (T_OBJ_ACCESS_REF == node.children_[0]->type_, OB_ERR_UNEXPECTED, node.children_[0]->type_); OX (info.set_is_explicit(true)); OX (info.set_type(node.value_)); OZ (process_obj_access_node(*(node.children_[0]), child_expr)); if (OB_SUCC(ret) && T_SP_CURSOR_ROWID == node.value_ && NULL != child_expr) { // in current of // 1. the value must to be a cursor name // 2. the cursor must to be a for update cursor const pl::ObPLCursor *cursor = NULL; const ObQualifiedName &col = ctx_.columns_->at(ctx_.columns_->count()-1); ctx_.secondary_namespace_->get_cursor_by_name(ctx_, col.database_name_, col.tbl_name_, col.col_name_, cursor); if (NULL == cursor) { ret = OB_ERR_NOT_CURSOR_NAME_IN_CURRENT_OF; LOG_WARN(" not a cursor name", K(col.col_name_), K(col.tbl_name_), K(col.database_name_), K(ret)); } else if (!cursor->is_for_update()) { ret = OB_ERR_NOT_FOR_UPDATE_CURSOR_IN_CURRENT_OF; LOG_USER_ERROR(OB_ERR_NOT_FOR_UPDATE_CURSOR_IN_CURRENT_OF, col.col_name_.length(), col.col_name_.ptr()); LOG_WARN("current of only support for update select.", K(ret), K(col.col_name_)); } else if (cursor->has_hidden_rowid()) { if (OB_ISNULL(ctx_.stmt_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("stmt is NULL", K(ret)); } else if (ObStmt::is_dml_write_stmt(ctx_.stmt_->stmt_type_)) { ObDelUpdStmt *del_upd_stmt = static_cast(ctx_.stmt_); if (OB_ISNULL(del_upd_stmt)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("del_upd_stmt is NULL", K(ret)); } else if (1 == del_upd_stmt->get_table_items().count()) { if (OB_ISNULL(del_upd_stmt->get_table_items().at(0))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("table item is NULL", K(ret)); } else if (del_upd_stmt->get_table_items().at(0)->ref_id_ != cursor->get_rowid_table_id()) { ret = OB_INVALID_ROWID; LOG_WARN("invalid ROWID", K(del_upd_stmt->get_table_items().at(0)->ref_id_), K(cursor->get_rowid_table_id()), K(ret)); } } } } } } else { // implicit cursor attribute node info.set_is_explicit(false); if (0 == node.num_child_) { info.set_type(node.value_); } else if (1 == node.num_child_) { CK (OB_NOT_NULL(node.children_[0])); if (OB_SUCC(ret)) { ObItemType type = node.children_[0]->type_; info.set_type(type); switch (type) { case T_SP_CURSOR_BULK_ROWCOUNT: case T_SP_CURSOR_BULK_EXCEPTIONS: { ParseNode* bulk_node = node.children_[0]; CK (OB_LIKELY(1 == bulk_node->num_child_)); CK (OB_NOT_NULL(bulk_node->children_[0])); OZ (SMART_CALL(recursive_resolve(bulk_node->children_[0], child_expr))); if (OB_SUCC(ret) && T_SP_CURSOR_BULK_EXCEPTIONS == type) { info.set_bulk_exceptions_code_or_idx(bulk_node->value_); } break; } case T_SP_CURSOR_BULK_EXCEPTIONS_COUNT: { break; } default: { ret = OB_ERR_UNEXPECTED; LOG_WARN("invlid node type", K(node.children_[0]->type_)); } } } } } OX (c_expr->set_pl_get_cursor_attr_info(info)); // 注意: 在添加Child之前做一次formalize仅仅是为了推导出ROWID属性的类型 OZ (c_expr->formalize(ctx_.session_info_)); if (OB_SUCC(ret) && OB_NOT_NULL(child_expr)) { OZ (c_expr->add_param_expr(child_expr)); } if (OB_SUCC(ret)) { if (T_FUN_PL_GET_CURSOR_ATTR == c_expr->get_expr_type()) { // 注意: 替换为ColumnRef的目的是为了在DML语句中把CURSOR%ROWID替换为QuenstionMark // 参见: ObDMLResolver::resolve_qualified_identifier ObQualifiedName column_ref; ObObjAccessIdent access_ident; ObColumnRefRawExpr *column_expr = NULL; access_ident.set_sys_func(); access_ident.sys_func_expr_ = c_expr; OZ (column_ref.access_idents_.push_back(access_ident)); OX (column_ref.parents_expr_info_ = ctx_.parents_expr_info_); OZ (ctx_.expr_factory_.create_raw_expr(T_REF_COLUMN, column_expr)); CK (OB_NOT_NULL(column_expr)); OX (column_ref.ref_expr_ = column_expr); //GetCursorAttr依赖的所有孩子节点都不是Root for (int64_t i = child_start; OB_SUCC(ret) && i < ctx_.columns_->count(); ++i) { ctx_.columns_->at(i).is_access_root_ = false; } OZ (ctx_.columns_->push_back(column_ref)); OX (expr = column_expr); } else { OX (expr = c_expr); } } return ret; } int ObRawExprResolverImpl::process_obj_access_node(const ParseNode &node, ObRawExpr *&expr) { int ret = OB_SUCCESS; if (OB_ISNULL(ctx_.columns_)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K_(ctx_.columns)); } else if (IS_AGGR_FUN(node.children_[0]->type_)) { //in oracle ,we could not define standalone or package function with the same name as agg function if (IS_KEEP_AGGR_FUN(node.children_[0]->type_)) { if (OB_FAIL(process_keep_aggr_node(node.children_[0], expr))) { LOG_WARN("process keep agg node failed", K(ret)); } } else if (OB_FAIL(process_agg_node(node.children_[0], expr))) { LOG_WARN("process agg node failed", K(ret)); } } else { ObQualifiedName column_ref; int64_t child_start = ctx_.columns_->count(); if (OB_FAIL(resolve_obj_access_idents(node, column_ref))) { LOG_WARN("resolve obj acess idents failed", K(ret)); } else { column_ref.format_qualified_name(ctx_.case_mode_); column_ref.parents_expr_info_ = ctx_.parents_expr_info_; ObColumnRefRawExpr *b_expr = NULL; if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_REF_COLUMN, b_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(b_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("column ref expr is null", K(ret)); } else { column_ref.ref_expr_ = b_expr; if (column_ref.is_pl_var()) { //PL变量的所有生成的孩子ObQualifiedName都不是root for (int64_t i = child_start; OB_SUCC(ret) && i < ctx_.columns_->count(); ++i) { ctx_.columns_->at(i).is_access_root_ = false; } } if (OB_FAIL(ctx_.columns_->push_back(column_ref))) { LOG_WARN("Add column failed", K(ret)); } else { expr = b_expr; } } } } return ret; } int ObRawExprResolverImpl::check_sys_connect_by_path_params(const ObRawExpr *param1, const ObRawExpr *param2) { int ret = OB_SUCCESS; if (OB_ISNULL(param1) || OB_ISNULL(param2)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid parameters", KPC(param1), KPC(param2), K(ret)); } else if (param1->has_flag(CNT_SYS_CONNECT_BY_PATH)) { ret = OB_ERR_CBY_PSEUDO_COLUMN_NOT_ALLOWED; LOG_WARN("Specified functions not allowed here", KPC(param1), K(ret)); } else if (OB_UNLIKELY(param2->get_expr_class() != ObRawExpr::EXPR_CONST)) { ret = OB_ERR_ILLEGAL_PARAM_FOR_CBY_PATH; LOG_WARN("invalid param for sys_connect_by_path", KPC(param2), K(ret)); } else { const ObConstRawExpr *const_param2 = static_cast(param2); const ObObj *param2_value = &const_param2->get_value(); if (T_QUESTIONMARK == param2->get_expr_type()) { int64_t idx = param2_value->get_unknown(); if (OB_ISNULL(ctx_.param_list_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("param_list_ is null", K(ret), K(ctx_.param_list_)); } else if (idx < 0 || idx >= ctx_.param_list_->count()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("index is out of range", K(idx), K(ctx_.param_list_->count())); } else { param2_value = &ctx_.param_list_->at(idx); } } if (OB_FAIL(ret)) { } else if (param2_value->is_null()) { ret = OB_ERR_CBY_CONNECT_BY_PATH_ILLEGAL_PARAM; LOG_WARN("invalid argument for sys_connect_by_path", KPC(const_param2), K(ret)); } else if (param2_value->is_string_type() && param2_value->get_string().empty()) { ret = OB_ERR_CBY_CONNECT_BY_PATH_ILLEGAL_PARAM; LOG_WARN("invalid argument for sys_connect_by_path", KPC(const_param2), K(ret)); } else if (param2_value->is_integer_type()) { //TODO negative number } } return ret; } int ObRawExprResolverImpl::is_explict_func_expr(const ParseNode &node, bool &is_func) { int ret = OB_SUCCESS; is_func = false; const share::schema::ObUDF *udf_info = NULL; bool exist = false; if (OB_ISNULL(node.children_) || OB_UNLIKELY(node.num_child_ != 2)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("node is invalid", "node", SJ(ObParserResultPrintWrapper(node))); } else if (node.children_[1] == NULL) { if (!IS_AGGR_FUN(node.children_[0]->type_) && !IS_FUN_SYS_TYPE(node.children_[0]->type_) && node.children_[0]->type_ != T_IDENT) { ret = OB_ERR_UNEXPECTED; LOG_WARN("child node is invalid", "node", SJ(ObParserResultPrintWrapper(node))); } else if (T_FUN_SYS == node.children_[0]->type_) { const ParseNode &func_node = *(node.children_[0]); ObString func_name(static_cast(func_node.children_[0]->str_len_), func_node.children_[0]->str_value_); if (IS_FUN_SYS_TYPE(ObExprOperatorFactory::get_type_by_name(func_name))) { is_func = true; } else if (OB_ISNULL(ctx_.session_info_) || OB_ISNULL(ctx_.schema_checker_)) { //PL resovler don't have session info and schema checker } else if (OB_FAIL(ctx_.schema_checker_->get_udf_info(ctx_.session_info_->get_effective_tenant_id(), func_name, udf_info, exist))) { LOG_WARN("failed to get udf info"); } else if (exist) { is_func = true; } else { //do nothing //ret = OB_ERR_FUNCTION_UNKNOWN; //LOG_USER_ERROR(ret, "FUNCTION", to_cstring(func_name));//throw this error to user } LOG_DEBUG("is_explict_func_expr", K(func_name), K(is_func), K(exist), "node", SJ(ObParserResultPrintWrapper(node))); } else if (IS_FUN_SYS_TYPE(node.children_[0]->type_) || IS_AGGR_FUN(node.children_[0]->type_)) { is_func = true; } } return ret; } int ObRawExprResolverImpl::process_sys_connect_by_path_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObSysFunRawExpr *path_expr = NULL; ObRawExpr *param1 = NULL; ObRawExpr *param2 = NULL; if (OB_ISNULL(node)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpeced parameter", K(node), K(ret)); } else if (OB_UNLIKELY(node->type_ != T_FUN_SYS_CONNECT_BY_PATH) || OB_UNLIKELY(node->num_child_ != 2) || OB_ISNULL(node->children_) || OB_ISNULL(node->children_[0]) || OB_ISNULL(node->children_[1])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid node", K(node->type_), K(node->num_child_), K(node->children_), K(ret)); } else if (OB_ISNULL(ctx_.stmt_) || OB_UNLIKELY(false == ctx_.stmt_->is_select_stmt())) { ret = OB_ERR_CBY_CONNECT_BY_REQUIRED; LOG_WARN("CONNECT BY clause required in this query block", K(ret)); } else if (OB_UNLIKELY(false == static_cast(ctx_.stmt_)->is_hierarchical_query())) { ret = OB_ERR_CBY_CONNECT_BY_REQUIRED; LOG_WARN("CONNECT BY clause required in this query block", K(ret)); } else if (OB_UNLIKELY(false == is_sys_connect_by_path_expr_valid_scope(ctx_.current_scope_))) { ret = OB_ERR_CBY_CONNECT_BY_PATH_NOT_ALLOWED; LOG_WARN("Connect by path not allowed here", K(ret)); } else if (ctx_.expr_factory_.create_raw_expr(T_FUN_SYS_CONNECT_BY_PATH, path_expr)) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(path_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("create expr is NULL", K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[0], param1)))) { LOG_WARN("fail to resolve param1 node", K(ret)); } else if (OB_FAIL(param1->extract_info())) { LOG_WARN("fail to extract info", K(param1), K(ret)); } else if (OB_UNLIKELY(OB_UNLIKELY(param1->has_flag(CNT_AGG)) || OB_UNLIKELY(param1->has_flag(CNT_SUB_QUERY)))) { ret = OB_NOT_SUPPORTED; LOG_USER_ERROR(OB_NOT_SUPPORTED, "Subquery or aggregate function in sys_connect_by_path is"); } else if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[1], param2)))) { LOG_WARN("fail to resolve param2 node", K(ret)); } else if (OB_FAIL(check_sys_connect_by_path_params(param1, param2))) { LOG_WARN("fail to check sys_connect_by_path params", KPC(param1), KPC(param2), K(ret)); } else if (OB_FAIL(path_expr->add_param_expr(param1))) { LOG_WARN("fail to push back param", KPC(param1)); } else if (OB_FAIL(path_expr->add_param_expr(param2))) { LOG_WARN("fail to push back param", KPC(param2)); } else { path_expr->set_func_name(N_SYS_CONNECT_BY_PATH); expr = path_expr; LOG_DEBUG("sys connect by path", K(expr), KPC(expr)); } return ret; } int ObRawExprResolverImpl::check_pseudo_column_exist(ObItemType type, ObPseudoColumnRawExpr *&expr) { int ret = OB_SUCCESS; bool found = false; if (OB_ISNULL(ctx_.stmt_) || OB_UNLIKELY(false == ctx_.stmt_->is_select_stmt())) { ret = OB_ERR_CBY_CONNECT_BY_REQUIRED; LOG_WARN("CONNECT BY clause required in this query block", K(ret)); } else { ObDMLStmt *stmt = static_cast(ctx_.stmt_); for (int64_t i = 0; OB_SUCC(ret) && !found && i < stmt->get_pseudo_column_like_exprs().count(); ++i) { ObRawExpr *pseudo_column_expr = stmt->get_pseudo_column_like_exprs().at(i); if (OB_ISNULL(pseudo_column_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr is NULL", K(i), K(ret)); } else if (pseudo_column_expr->get_expr_type() == type) { if (OB_LIKELY(pseudo_column_expr->is_pseudo_column_expr())) { expr = static_cast(pseudo_column_expr); found = true; } else { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr should be ObPseudoColumnRawExpr", K(ret), K(*pseudo_column_expr)); } } } } return ret; } int ObRawExprResolverImpl::check_name_type(ObQualifiedName &q_name, ObStmtScope scope, AccessNameType &type) { int ret = OB_SUCCESS; SET_LOG_CHECK_MODE(); type = UNKNOWN; bool check_success = false; if (OB_SUCC(ret) && !check_success) { if (T_PL_SCOPE == scope) { //PL scope里优先解释为var,次优先udf,最后是sys func if (OB_FAIL(check_pl_variable(q_name, check_success))) { LOG_WARN("check pl variable failed", K(q_name), K(ret)); } else if (check_success) { type = q_name.is_type_method() ? TYPE_METHOD : PL_VAR; } else if (OB_FAIL(check_pl_udf(q_name, ctx_.session_info_, ctx_.schema_checker_, ctx_.secondary_namespace_, check_success))) { LOG_WARN("check pl variable failed", K(q_name), K(ret)); } else if (check_success) { type = PL_UDF; } else if (OB_FAIL(check_sys_func(q_name, check_success))) { LOG_WARN("check pl variable failed", K(q_name), K(ret)); } else if (check_success) { type = SYS_FUNC; } else { /*do nothing*/ } } else { //SQL scope里优先解释为sys func,次优先var,最后是udf if (OB_FAIL(check_sys_func(q_name, check_success))) { LOG_WARN("check pl variable failed", K(q_name), K(ret)); } else if (check_success) { type = SYS_FUNC; } else if (OB_FAIL(check_pl_variable(q_name, check_success))) { LOG_WARN("check pl variable failed", K(q_name), K(ret)); } else if (check_success) { type = q_name.is_type_method() ? TYPE_METHOD : PL_VAR;; } else if (OB_FAIL(check_pl_udf(q_name, ctx_.session_info_, ctx_.schema_checker_, ctx_.secondary_namespace_, check_success))) { LOG_WARN("check pl variable failed", K(q_name), K(ret)); } else if (check_success) { type = PL_UDF; } else { /*do nothing*/ } } } if ((OB_SUCC(ret) && !check_success) || (OB_ERR_INVOKE_STATIC_BY_INSTANCE != ret && OB_FAIL(ret))) { ret = OB_SUCCESS; CK (q_name.access_idents_.count() <= 3 && q_name.access_idents_.count() >= 1); if (3 == q_name.access_idents_.count()) { OX (q_name.database_name_ = q_name.access_idents_.at(0).access_name_); OX (q_name.tbl_name_ = q_name.access_idents_.at(1).access_name_); } else if (2 == q_name.access_idents_.count()) { OX (q_name.tbl_name_ = q_name.access_idents_.at(0).access_name_); } //如果sys func和pl udf都找不到,那么认为可能是还没有创建出来的UDF OX (type = PL_UDF); OX (q_name.access_idents_.at(q_name.access_idents_.count() - 1).set_pl_udf()); } CANCLE_LOG_CHECK_MODE(); return ret; } int ObRawExprResolverImpl::check_pl_variable(ObQualifiedName &q_name, bool &is_pl_var) { int ret = OB_SUCCESS; is_pl_var = false; common::ObArenaAllocator allocator; ObRawExprFactory expr_factory(allocator); ObRawExpr *var = NULL; if (NULL == ctx_.secondary_namespace_) { //非PL语境,返回false即可(package对象不可在纯sql语境里访问,但是package里的function可以) } else { SET_LOG_CHECK_MODE(); CK(OB_NOT_NULL(ctx_.secondary_namespace_->get_external_ns())); if (OB_SUCC(ret)) { ObArray fake_columns; ObArray fake_exprs; if (OB_FAIL(ObResolverUtils::resolve_external_symbol(allocator, expr_factory, ctx_.secondary_namespace_->get_external_ns()->get_resolve_ctx().session_info_, ctx_.secondary_namespace_->get_external_ns()->get_resolve_ctx().schema_guard_, &ctx_.secondary_namespace_->get_external_ns()->get_resolve_ctx().sql_proxy_, ctx_.external_param_info_, ctx_.secondary_namespace_, q_name, fake_columns, fake_exprs, var, false,/*is_prepare_protocol*/ true,/*is_check_mode*/ ctx_.current_scope_ != T_PL_SCOPE /*is_sql_scope*/))) { LOG_INFO("failed to resolve external symbol", K(q_name), K(ret)); if (OB_ERR_INVOKE_STATIC_BY_INSTANCE != ret) { ret = OB_SUCCESS; //TODO:@ryan.ly 只针对某些错误码 } } else if (OB_ISNULL(var)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Invalid expr", K(q_name), K(ret)); } else if (T_QUESTIONMARK == var->get_expr_type()) { // PL基础变量 is_pl_var = true; q_name.access_idents_.at(q_name.access_idents_.count() - 1).set_pl_var(); } else if (var->is_obj_access_expr()) { ObObjAccessRawExpr* obj_access_expr = static_cast(var); OX (is_pl_var = true); CK (OB_NOT_NULL(obj_access_expr)); if (OB_FAIL(ret)) { } else if (obj_access_expr->is_property()) { q_name.access_idents_.at(q_name.access_idents_.count() - 1).set_type_method(); } else { q_name.access_idents_.at(q_name.access_idents_.count() - 1).set_pl_var(); } } else { /*do nothing*/ } } CANCLE_LOG_CHECK_MODE(); } return ret; } int ObRawExprResolverImpl::check_sys_func(ObQualifiedName &q_name, bool &is_sys_func) { int ret = OB_SUCCESS; is_sys_func = 1 == q_name.access_idents_.count() && (IS_FUN_SYS_TYPE(ObExprOperatorFactory::get_type_by_name(q_name.access_idents_.at(0).access_name_)) || 0 == q_name.access_idents_.at(0).access_name_.case_compare("sqlerrm")); if (is_sys_func) { q_name.access_idents_.at(0).set_sys_func(); } return ret; } static bool check_is_pl_jsontype(const ObString& name) { return ((name.length() == 13 && ObString("JSON_OBJECT_T").compare(name) == 0) || (name.length() == 14 && ObString("JSON_ELEMENT_T").compare(name) == 0)); } int ObRawExprResolverImpl::check_dll_udf(ObQualifiedName &q_name, bool &is_dll_udf) { int ret = OB_SUCCESS; is_dll_udf = false; if (!q_name.access_idents_.empty()) { const share::schema::ObUDF *udf_info = NULL; ObString &func_name = q_name.access_idents_.at(q_name.access_idents_.count() - 1).access_name_; if (OB_ISNULL(ctx_.session_info_) || OB_ISNULL(ctx_.schema_checker_)) { //PL resovler don't have session info and schema checker } else if (OB_FAIL(ctx_.schema_checker_->get_udf_info(ctx_.session_info_->get_effective_tenant_id(), func_name, udf_info, is_dll_udf))) { LOG_WARN("failed to get udf info"); } else if (is_dll_udf) { q_name.access_idents_.at(0).set_dll_udf(); } else { /*do nothing*/ } } return ret; } int ObRawExprResolverImpl::check_pl_udf(ObQualifiedName &q_name, const ObSQLSessionInfo *session_info, ObSchemaChecker *schema_checker, pl::ObPLBlockNS *secondary_namespace, bool &is_pl_udf) { int ret = OB_SUCCESS; SET_LOG_CHECK_MODE(); is_pl_udf = false; pl::ObProcType proc_type = pl::INVALID_PROC_TYPE; uint64_t udt_id = OB_INVALID_ID; if (q_name.access_idents_.empty()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Invalid name", K(q_name), K(ret)); } else if (q_name.access_idents_.count() < 4) { ObString db_name; ObString pkg_name; ObString udt_name; ObString &func_name = q_name.access_idents_.at(q_name.access_idents_.count() - 1).access_name_; switch (q_name.access_idents_.count()) { #define CKECK_ROUTINE_EXISTS \ do { \ if (OB_SUCC(ret)) { \ if (OB_FAIL(ObResolverUtils::check_routine_exists(session_info, \ schema_checker, \ secondary_namespace, \ db_name, \ pkg_name, \ func_name, \ share::schema::ObRoutineType::ROUTINE_FUNCTION_TYPE, \ is_pl_udf, \ proc_type, \ udt_id))) { \ LOG_WARN("failed to check_routine_exists", K(q_name), K(db_name), K(pkg_name), K(func_name), K(ret)); \ } \ } \ } while (0) case 1: { CKECK_ROUTINE_EXISTS; if (OB_SUCC(ret) && is_pl_udf) { //对于一个func,优先级顺序是:package local func > sys func > standalone func if (pl::STANDALONE_PROCEDURE == proc_type || pl::STANDALONE_FUNCTION == proc_type) { bool is_sys_func = false; if (OB_FAIL(check_sys_func(q_name, is_sys_func))) { LOG_WARN("check sys func failed", K(q_name), K(ret)); } else if (is_sys_func) { is_pl_udf = false; } else { /*do nothing*/ } } if (OB_SUCC(ret) && is_pl_udf) { q_name.access_idents_.at(0).set_pl_udf(); q_name.col_name_ = func_name; } } else { // two case: /* * object type may have: * 1. return object_cons; which object_cons is object constructor * 2. expr(a, object_cons); which object_cons is also object constructor */ bool is_udt_exist = false; if (OB_NOT_NULL(schema_checker) && OB_NOT_NULL(session_info)) { OZ (schema_checker->check_udt_exist(session_info->get_effective_tenant_id(), session_info->get_database_id(), OB_INVALID_ID, share::schema::ObUDTTypeCode::UDT_TYPE_OBJECT, func_name, is_udt_exist)); if (OB_SUCC(ret) && is_udt_exist) { OZ (schema_checker->get_udt_id(session_info->get_effective_tenant_id(), session_info->get_database_name(), func_name, udt_id)); } if (OB_SUCC(ret) && OB_INVALID_ID == udt_id && !is_udt_exist) { // may system udt OZ (schema_checker->get_udt_id(OB_SYS_TENANT_ID, OB_SYS_DATABASE_ID, OB_INVALID_ID, func_name, udt_id), K(func_name), K(udt_id)); } if (OB_SUCC(ret) && OB_INVALID_ID != udt_id) { int tmp_ret = ret; ret = OB_SUCCESS; pkg_name = func_name; CKECK_ROUTINE_EXISTS; if (OB_SUCC(ret) && is_pl_udf) { q_name.access_idents_.at(0).set_pl_udf(); q_name.tbl_name_ = pkg_name; q_name.col_name_ = func_name; } else { ret = tmp_ret; } } } } } break; case 2: { // try pkg.routine() first db_name = session_info->get_database_name(); pkg_name = q_name.access_idents_.at(0).access_name_; CKECK_ROUTINE_EXISTS; if (OB_SUCC(ret) && is_pl_udf) { q_name.access_idents_.at(0).set_pkg_ns(); q_name.access_idents_.at(1).set_pl_udf(); q_name.database_name_ = db_name; q_name.tbl_name_ = pkg_name; q_name.col_name_ = func_name; } else { ret = OB_SUCCESS; //TODO:@ryan.ly 特定的错误码才处理 db_name = q_name.access_idents_.at(0).access_name_; pkg_name.reset(); CKECK_ROUTINE_EXISTS; if (OB_SUCC(ret) && is_pl_udf) { q_name.access_idents_.at(0).set_db_ns(); q_name.access_idents_.at(1).set_pl_udf(); q_name.database_name_ = db_name; q_name.tbl_name_.reset(); q_name.col_name_ = func_name; } else { // try system package routine ret = OB_SUCCESS; db_name = ObString(OB_SYS_DATABASE_NAME); pkg_name = q_name.access_idents_.at(0).access_name_; CKECK_ROUTINE_EXISTS; if (OB_SUCC(ret) && is_pl_udf) { q_name.access_idents_.at(0).set_pkg_ns(); q_name.tbl_name_ = pkg_name; q_name.access_idents_.at(1).set_pl_udf(); q_name.database_name_ = db_name; q_name.col_name_ = func_name; } else { } } } } break; case 3: { db_name = q_name.access_idents_.at(0).access_name_; pkg_name = q_name.access_idents_.at(1).access_name_; CKECK_ROUTINE_EXISTS; if (OB_SUCC(ret) && is_pl_udf) { q_name.access_idents_.at(0).set_db_ns(); q_name.access_idents_.at(1).set_pkg_ns(); q_name.tbl_name_ = pkg_name; q_name.access_idents_.at(2).set_pl_udf(); q_name.database_name_ = db_name; q_name.col_name_ = func_name; } else { ret = OB_SUCCESS; // db.obj_type.routine, obj_type只能是一个udt type,db.obj.routine不可能, // 因为obj要么定义在匿名块里面 // 要么定义在package里面,这种是 db.package.obj.routine,是这个的. db.label.obj.routine有可能吗? db_name = q_name.access_idents_.at(0).access_name_; pkg_name = q_name.access_idents_.at(1).access_name_; udt_name = pkg_name; uint64_t db_id = OB_INVALID_ID; if (OB_NOT_NULL(schema_checker)) { if (OB_FAIL(schema_checker->get_database_id(session_info->get_effective_tenant_id(), db_name, db_id))) { LOG_WARN("failed to get db_id", K(db_name), K(pkg_name), K(ret)); } else if (OB_FAIL(schema_checker->get_udt_id(session_info->get_effective_tenant_id(), db_id, OB_INVALID_ID, udt_name, udt_id))) { LOG_WARN("failed to get udt id", K(db_name), K(db_id), K(udt_name), K(ret)); } } if (OB_ERR_BAD_DATABASE == ret) { ret = OB_SUCCESS; } if (OB_SUCC(ret)) { if (OB_INVALID_ID == udt_id) { is_pl_udf = false; } else { CKECK_ROUTINE_EXISTS; } if (OB_SUCC(ret) && is_pl_udf) { q_name.access_idents_.at(0).set_db_ns(); q_name.access_idents_.at(1).set_udt_ns(); q_name.tbl_name_ = udt_name; q_name.access_idents_.at(2).set_pl_udf(); q_name.database_name_ = db_name; q_name.col_name_ = func_name; } else { ret = OB_SUCCESS; // pkg.object.routine, it's possbile, ObString udt_var_name; int64_t compatible_mode = lib::is_oracle_mode() ? COMPATIBLE_ORACLE_MODE : COMPATIBLE_MYSQL_MODE; uint64_t pkg_id = OB_INVALID_ID; OX (db_name = session_info->get_database_name()); OX (pkg_name = q_name.access_idents_.at(0).access_name_); OX (udt_var_name = q_name.access_idents_.at(1).access_name_); if (OB_ISNULL(secondary_namespace) || OB_ISNULL(schema_checker)) { // do nothing; } else if (OB_FAIL(schema_checker->get_package_id(session_info->get_effective_tenant_id(), db_name, pkg_name, compatible_mode, pkg_id))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get package unexpected", K(ret), K(pkg_name), K(db_name)); } else if (OB_INVALID_ID == pkg_id) { // do nothing } else if (OB_FAIL(schema_checker->get_udt_id(session_info->get_effective_tenant_id(), session_info->get_database_id(), OB_INVALID_ID, udt_var_name, udt_id))) { LOG_WARN("failed to get udt id", K(ret), K(udt_var_name), K(db_name)); } else if (OB_INVALID_ID != udt_id) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected, object type defined inside package", K(ret), K(udt_var_name), K(db_name)); // pkg.object_type.routine // impossible, because a object type cann't be defined inside a package } else if (FALSE_IT(secondary_namespace->try_resolve_udt_name(udt_var_name, udt_name, udt_id, pl::ObPLExternalNS::ExternalType::PKG_VAR, pkg_id))) { } else if (OB_FAIL(schema_checker->get_udt_id(session_info->get_effective_tenant_id(), session_info->get_database_id(), OB_INVALID_ID, udt_name, udt_id))) { LOG_WARN("failed to get udt id", K(db_name), K(db_id), K(udt_name), K(ret)); } else if (OB_INVALID_ID != udt_id) { pkg_name = udt_name; CKECK_ROUTINE_EXISTS; // pkg.object_instance.routine if (OB_SUCC(ret) && is_pl_udf) { q_name.access_idents_.at(0).set_pkg_ns(); q_name.access_idents_.at(1).set_udt_ns(); q_name.access_idents_.at(2).set_pl_udf(); q_name.database_name_ = q_name.access_idents_.at(0).access_name_; q_name.tbl_name_ = udt_name; q_name.col_name_ = func_name; } } } } } } break; default: { ret = OB_ERR_UNEXPECTED; LOG_WARN("what happend?", K(q_name), K(ret)); } break; } } else { /*do nothing*/ } CANCLE_LOG_CHECK_MODE(); return ret; } int ObRawExprResolverImpl::resolve_obj_access_idents(const ParseNode &node, ObQualifiedName &q_name) { int ret = OB_SUCCESS; if (OB_UNLIKELY(node.type_ != T_OBJ_ACCESS_REF) || OB_UNLIKELY(node.num_child_ != 2)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid node type", K_(node.type), K(node.num_child_), K(ret)); } else { //1、首先解T_OBJ_ACCESS_REF的左支,左支只可能是T_IDENT或T_FUN_SYS if (OB_ISNULL(node.children_[0])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("node is NULL", K(node.num_child_)); } else if (T_IDENT == node.children_[0]->type_) { ObString ident_name(static_cast(node.children_[0]->str_len_), node.children_[0]->str_value_); if (lib::is_oracle_mode() && T_PL_SCOPE == ctx_.current_scope_ && ident_name.empty()) { ret = OB_ERR_IDENT_EMPTY; LOG_WARN("Identifier cannot be an empty string", K(ret), K(ident_name)); } OZ (q_name.access_idents_.push_back(ObObjAccessIdent(ident_name, OB_INVALID_INDEX)), q_name); if (OB_SUCC(ret) && T_PL_SCOPE == ctx_.current_scope_ && q_name.access_idents_.count() > 1 && (0 == ident_name.case_compare("NEXT") || 0 == ident_name.case_compare("PRIOR") || 0 == ident_name.case_compare("EXISTS")) && lib::is_oracle_mode()) { AccessNameType name_type = UNKNOWN; OZ (check_name_type(q_name, ctx_.current_scope_, name_type)); if (OB_SUCC(ret) && name_type == TYPE_METHOD) { ret = OB_ERR_CALL_WRONG_ARG; LOG_WARN("wrong number or types of arguments in call to procedure", K(ret), K(q_name)); LOG_USER_ERROR(OB_ERR_CALL_WRONG_ARG, ident_name.length(), ident_name.ptr()); } } } else if (T_QUESTIONMARK == node.children_[0]->type_) { if (q_name.access_idents_.count() > 0) { ret = OB_ERR_UNEXPECTED; LOG_WARN("quesitonmark in obj access ref muse be top node.", K(ret), K(q_name.access_idents_)); } else { ObObjAccessIdent ident(ObString(""), node.children_[0]->value_); OX (ident.set_pl_var()); OZ (q_name.access_idents_.push_back(ident)); } } else if (T_FUN_SYS == node.children_[0]->type_) { const ParseNode &func_node = *(node.children_[0]); if (OB_ISNULL(func_node.children_[0])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("node is NULL", K(node.num_child_), K(ret)); } else { ObString ident_name(static_cast(func_node.children_[0]->str_len_), func_node.children_[0]->str_value_); // first bit in value_ of T_FUN_SYS node is used to mark NEW keyword, // value_ & 0x1 == 1: not used, // value_ & 0x1 == 0: used, // refer to sql_parser_oracle_mode.y bool is_new_key_word_used = !(func_node.value_ & 0x1); if (lib::is_oracle_mode() && T_PL_SCOPE == ctx_.current_scope_ && ident_name.empty()) { ret = OB_ERR_IDENT_EMPTY; LOG_WARN("Identifier cannot be an empty string", K(ret), K(ident_name)); } OZ (q_name.access_idents_.push_back( ObObjAccessIdent(ident_name, OB_INVALID_INDEX)), K(ident_name)); if (OB_SUCC(ret)) { ObObjAccessIdent &access_ident = q_name.access_idents_.at(q_name.access_idents_.count() - 1); AccessNameType name_type = UNKNOWN; if (OB_FAIL(check_name_type(q_name, ctx_.current_scope_, name_type))) { LOG_WARN("check name type failed", K(ret), K(q_name)); //only pl agg udf allow have distinct/unique/all as common aggr. } else if (name_type != PL_UDF && func_node.num_child_ == 3 && (func_node.children_[2]->type_ == T_DISTINCT || func_node.children_[2]->type_ == T_ALL)) { ret = OB_DISTINCT_NOT_ALLOWED; LOG_WARN("distinct/all/unique not allowed here", K(ret)); } else if (is_new_key_word_used && PL_UDF != name_type) { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("NEW keyword is only allowed for constructors", K(q_name)); } else { switch (name_type) { case SYS_FUNC: { ObRawExpr *func_expr = NULL; if (0 == q_name.access_idents_.at(0).access_name_.case_compare("SQLERRM")) { OZ (process_sqlerrm_node(&func_node, func_expr)); } else if (0 == q_name.access_idents_.at(0).access_name_.case_compare("json_equal")) { ret = OB_ERR_JSON_EQUAL_OUTSIDE_PREDICATE; } else { OZ (process_fun_sys_node(&func_node, func_expr)); } CK (OB_NOT_NULL(func_expr)); OX (access_ident.sys_func_expr_ = static_cast(func_expr)); for (int64_t i = 0; OB_SUCC(ret) && i < func_expr->get_param_count(); ++i) { std::pair param(func_expr->get_param_expr(i), 0); OZ (access_ident.params_.push_back(param)); } } break; case PL_UDF: { ParseNode *udf_node = NULL; ObRawExpr *udf_expr = NULL; bool is_member = false; int64_t cnt = q_name.access_idents_.count(); ParseNode *udt_udf_self_param_node = NULL; ObRawExpr *self_param = NULL; access_ident.udf_info_.is_new_keyword_used_ = is_new_key_word_used; if (OB_FAIL(ObResolverUtils::transform_func_sys_to_udf(&ctx_.expr_factory_.get_allocator(), &func_node, q_name.database_name_, q_name.tbl_name_, udf_node))) { LOG_WARN("transform fun sys to udf node failed", K(ret)); } else if (OB_FAIL(resolve_udf_info(udf_node, false, access_ident.udf_info_, udt_udf_self_param_node, self_param))) { LOG_WARN("process udf node failed", K(ret)); } else if (OB_ISNULL(udf_expr = access_ident.udf_info_.ref_expr_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid udf expr", K(ret)); } else { if (func_node.num_child_ == 3 && func_node.children_[2]->type_ == T_DISTINCT) { static_cast(udf_expr)->set_is_aggr_udf_distinct(true); } for (int64_t i = 0; OB_SUCC(ret) && i < udf_expr->get_param_count(); ++i) { std::pair param(udf_expr->get_param_expr(i), 0); if (OB_FAIL(access_ident.params_.push_back(param))) { LOG_WARN("push back error", K(ret)); } } if (OB_SUCC(ret) && 3 == cnt) { bool is_pkg_ns = q_name.access_idents_.at(0).is_pkg_ns(); bool is_udt_ns = q_name.access_idents_.at(1).is_udt_ns(); bool is_pl_udf = q_name.access_idents_.at(2).is_pl_udf(); access_ident.udf_info_.is_udt_udf_inside_pkg_ = is_pkg_ns && is_udt_ns && is_pl_udf; } } } break; case TYPE_METHOD: { if (0 == access_ident.access_name_.case_compare("LIMIT") || 0 == access_ident.access_name_.case_compare("COUNT")) { if (func_node.num_child_ > 1 && OB_NOT_NULL(func_node.children_[1])) { ret = OB_ERR_CALL_WRONG_ARG; LOG_WARN("wrong number or types of arguments in call to procedure", K(ret), K(access_ident)); LOG_USER_ERROR(OB_ERR_CALL_WRONG_ARG, access_ident.access_name_.length(), access_ident.access_name_.ptr()); } break; } else { // fall through. } } case PL_VAR: { if (func_node.num_child_ != 2 || OB_ISNULL(func_node.children_[1])) { ret = OB_ERR_NO_FUNCTION_EXIST; LOG_WARN("PLS-00222: no function with name 'string' exists in this scope", K(ret), K(func_node.num_child_), K(access_ident)); } else if (T_EXPR_LIST != func_node.children_[1]->type_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("not expr list node!", K(func_node.children_[1]->type_), K(func_node.children_[1]->num_child_), K(ret)); } else if (func_node.children_[1]->num_child_ != 1) { ret = OB_ERR_TABLE_SINGLE_INDEX; LOG_WARN("PLS-00316: PL/SQL TABLEs must use a single index", K(ret), K(func_node.children_[1]->num_child_)); } else { const ParseNode *expr_node = func_node.children_[1]->children_[0]; ObRawExpr *index_expr = NULL; if (OB_FAIL(ctx_.parents_expr_info_.add_member(IS_PL_ACCESS_IDX))) { LOG_WARN("failed to add parents expr info", K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(expr_node, index_expr)))) { LOG_WARN("failed to recursive resolve", K(ret)); } else { std::pair param(index_expr, 0); if (OB_FAIL(access_ident.params_.push_back(param))) { LOG_WARN("push back error", K(ret)); } } ctx_.parents_expr_info_.del_member(IS_PL_ACCESS_IDX); } } break; case UNKNOWN: case DLL_UDF: case DB_NS: case PKG_NS: case REC_ELEM: default: { ret = OB_ERR_UNEXPECTED; LOG_WARN("node is NULL", K(q_name), K(ctx_.current_scope_), K(name_type)); } break; } } } } } else { ret = OB_ERR_UNEXPECTED; LOG_WARN("Invalid node type", K(node.children_[0]->type_), K(ret)); } //2、然后解T_OBJ_ACCESS_REF的右支,右支只可能是T_OBJ_ACCESS_REF('.'的情况)或T_EXPR_LIST('()'的情况) if (OB_SUCC(ret) && node.children_[1] != NULL) { if (T_OBJ_ACCESS_REF == node.children_[1]->type_) { OZ (resolve_obj_access_idents(*(node.children_[1]), q_name), K(q_name)); } else { const ParseNode *element_list = node.children_[1]; CK (OB_LIKELY(!q_name.access_idents_.empty())); for (int64_t i = 0; OB_SUCC(ret) && i < element_list->num_child_; ++i) { ObObjAccessIdent &access_ident = q_name.access_idents_.at(q_name.access_idents_.count() - 1); ObRawExpr *param_expr = NULL; int64_t param_level = OB_INVALID_INDEX; CK (OB_NOT_NULL(element_list->children_[i])); OZ (SMART_CALL(recursive_resolve(element_list->children_[i], param_expr))); if (OB_FAIL(ret)) { } else if (access_ident.params_.empty()) { if (access_ident.is_pl_var() && access_ident.access_name_.empty()) { // :a(index) param_level = 0; } else { // f()(index) param_level = 1; } } else { param_level = access_ident.params_.at(access_ident.params_.count() - 1).second + 1; } OZ (access_ident.params_.push_back(std::make_pair(param_expr, param_level)), KPC(param_expr), K(param_level)); } } } } return ret; } int ObRawExprResolverImpl::process_pseudo_column_node(const ParseNode &node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObPseudoColumnRawExpr *pseudo_column_expr = NULL; const ParseNode *pseudo_column_node = NULL; ObString column_name; if (OB_UNLIKELY(node.num_child_ != 1 && node.num_child_ != 2) || OB_ISNULL(pseudo_column_node = node.children_[0])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected parameter",K(node.num_child_), K(pseudo_column_node), K(ret)); } else if ((!IS_PSEUDO_COLUMN_TYPE(pseudo_column_node->type_)) && pseudo_column_node->type_ != T_CTE_SEARCH_COLUMN && pseudo_column_node->type_ != T_CTE_CYCLE_COLUMN) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected pseudo column type", K(ret)); } else if (OB_UNLIKELY(false == is_pseudo_column_valid_scope(ctx_.current_scope_))) { ret = OB_ERR_CBY_PSEUDO_COLUMN_NOT_ALLOWED; LOG_WARN("pseudo column at invalid scope", K(ctx_.current_scope_), K(ret)); } else if (OB_FAIL(check_pseudo_column_exist(pseudo_column_node->type_, pseudo_column_expr))) { LOG_WARN("fail to check pseudo column exist", K(ret)); } else if (pseudo_column_expr != NULL) { //this type of pseudo_column_expr has been add expr = pseudo_column_expr; } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(pseudo_column_node->type_, pseudo_column_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(pseudo_column_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("pseudo column expr is NULL", K(ret)); } else if (pseudo_column_expr->is_hierarchical_query_type() && (OB_ISNULL(ctx_.stmt_) || OB_UNLIKELY(false == ctx_.stmt_->is_select_stmt()) || (false == static_cast(ctx_.stmt_)->is_hierarchical_query()))) { ret = OB_ERR_CBY_CONNECT_BY_REQUIRED; LOG_WARN("CONNECT BY clause required in this query block", K(ret)); } else { switch (pseudo_column_expr->get_expr_type()) { case T_LEVEL: pseudo_column_expr->set_data_type(ObNumberType); pseudo_column_expr->set_accuracy(ObAccuracy::DDL_DEFAULT_ACCURACY2[is_oracle_mode()][ObNumberType]); break; case T_CONNECT_BY_ISLEAF: pseudo_column_expr->set_data_type(ObNumberType); pseudo_column_expr->set_accuracy(ObAccuracy::DDL_DEFAULT_ACCURACY2[is_oracle_mode()][ObNumberType]); break; case T_CONNECT_BY_ISCYCLE: pseudo_column_expr->set_data_type(ObNumberType); pseudo_column_expr->set_accuracy(ObAccuracy::DDL_DEFAULT_ACCURACY2[is_oracle_mode()][ObNumberType]); break; case T_CTE_SEARCH_COLUMN: pseudo_column_expr->set_data_type(ObNumberType); pseudo_column_expr->set_accuracy(ObAccuracy::DDL_DEFAULT_ACCURACY2[is_oracle_mode()][ObNumberType]); if (OB_ISNULL(node.children_[1])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("search clause's set var_name has null node"); } else if (node.children_[1]->str_len_<=0) { ret = OB_ERR_UNEXPECTED; LOG_WARN("search clause's set var_name has 0 str len"); } else { column_name.assign_ptr((char *) node.children_[1]->str_value_, static_cast(node.children_[1]->str_len_)); pseudo_column_expr->set_alias_column_name(column_name); } break; case T_CTE_CYCLE_COLUMN: { pseudo_column_expr->set_data_type(ObVarcharType); ObAccuracy accuracy = ObAccuracy::MAX_ACCURACY[ObVarcharType]; //cycle mark value and non-cycle mark value must be one byte character string values accuracy.set_length(1); pseudo_column_expr->set_accuracy(accuracy); if (OB_ISNULL(node.children_[1])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("search clause's set var_name has null node"); } else if (node.children_[1]->str_len_<=0) { ret = OB_ERR_UNEXPECTED; LOG_WARN("search clause's set var_name has 0 str len"); } else { column_name.assign_ptr((char *) node.children_[1]->str_value_, static_cast(node.children_[1]->str_len_)); pseudo_column_expr->set_alias_column_name(column_name); } break; } default: ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid expr type", KPC(pseudo_column_expr), K(ret)); } if (OB_FAIL(ret)) { } else if (pseudo_column_expr->is_hierarchical_query_type() || pseudo_column_expr->is_cte_query_type()) { if (OB_FAIL(static_cast(ctx_.stmt_)->get_pseudo_column_like_exprs(). push_back(pseudo_column_expr))) { LOG_WARN("fail to push back pseudo column expr", K(ret)); } else { expr = pseudo_column_expr; } } else { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected expr type", K(pseudo_column_expr->get_expr_type()), K(ret)); } } return ret; } int ObRawExprResolverImpl::process_connect_by_root_node(const ParseNode &node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObOpRawExpr *root_expr = NULL; ObRawExpr *child_expr = NULL; if (node.num_child_ != 1 || OB_ISNULL(node.children_) || OB_UNLIKELY(node.type_ != T_OP_CONNECT_BY_ROOT)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid parametor", K(node.num_child_), K(node.type_), K(ret)); } else if (OB_ISNULL(ctx_.stmt_) || OB_UNLIKELY(false == ctx_.stmt_->is_select_stmt())) { ret = OB_ERR_CBY_CONNECT_BY_REQUIRED; LOG_WARN("CONNECT BY clause required in this query block", K(ret)); } else if (OB_UNLIKELY(false == static_cast(ctx_.stmt_)->is_hierarchical_query())) { ret = OB_ERR_CBY_CONNECT_BY_REQUIRED; LOG_WARN("CONNECT BY clause required in this query block", K(ret)); } else if (OB_UNLIKELY(false == is_connec_by_root_expr_valid_scope(ctx_.current_scope_))) { ret = OB_ERR_CBY_CONNECT_BY_ROOT_ILLEGAL_USED; LOG_WARN("Connect by root not allowed here", K(ret)); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(node.type_, root_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(node.children_[0], child_expr)))) { LOG_WARN("fail to resolve child expr", K(ret)); } else if (OB_ISNULL(root_expr) || OB_ISNULL(child_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("prior expr is NULL", KPC(root_expr), KPC(child_expr), K(ret)); } else if (OB_FAIL(child_expr->extract_info())) { LOG_WARN("fail to extract_info", KPC(child_expr), K(ret)); } else if (OB_UNLIKELY(child_expr->has_flag(CNT_PSEUDO_COLUMN)) || OB_UNLIKELY(child_expr->has_flag(CNT_PRIOR))) { ret = OB_ERR_CBY_PSEUDO_COLUMN_NOT_ALLOWED; LOG_WARN("Specified pseudocolumn or operator not allowed here", KPC(child_expr), K(ret)); } else if (OB_UNLIKELY(child_expr->has_flag(CNT_CONNECT_BY_ROOT) || child_expr->has_flag(CNT_SYS_CONNECT_BY_PATH))) { ret = OB_ERR_CBY_PSEUDO_COLUMN_NOT_ALLOWED; LOG_WARN("Specified functions not allowed here", KPC(child_expr), K(ret)); } else if (OB_UNLIKELY(child_expr->has_flag(CNT_AGG)) || OB_UNLIKELY(child_expr->has_flag(CNT_SUB_QUERY))) { ret = OB_ERR_CBY_PSEUDO_COLUMN_NOT_ALLOWED; LOG_WARN("Specified pseudocolumn or operator not allowed here", KPC(child_expr), K(ret)); } else if (OB_FAIL(root_expr->add_param_expr(child_expr))) { LOG_WARN("fail to add param", KPC(root_expr), KPC(child_expr), K(ret)); } else { expr = root_expr; } return ret; } int ObRawExprResolverImpl::process_prior_node(const ParseNode &node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObOpRawExpr *prior_expr = NULL; ObRawExpr *child_expr = NULL; if (node.num_child_ != 1 || OB_ISNULL(node.children_) || OB_UNLIKELY(node.type_ != T_OP_PRIOR)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid parameter", K(node.num_child_), K(node.type_), K(ret)); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(node.type_, prior_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(node.children_[0], child_expr)))) { LOG_WARN("fail to resolve child expr", K(ret)); } else if (OB_ISNULL(prior_expr) || OB_ISNULL(child_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("prior expr is NULL", KPC(prior_expr), KPC(child_expr), K(ret)); } else if (OB_ISNULL(ctx_.stmt_) || OB_UNLIKELY(false == ctx_.stmt_->is_select_stmt())) { ret = OB_ERR_CBY_CONNECT_BY_REQUIRED; LOG_WARN("CONNECT BY clause required in this query block", K(ret)); } else if (OB_UNLIKELY(false == static_cast(ctx_.stmt_)->is_hierarchical_query())) { ret = OB_ERR_CBY_CONNECT_BY_REQUIRED; LOG_WARN("CONNECT BY clause required in this query block", K(ret)); } else if (OB_UNLIKELY(false == is_prior_expr_valid_scope(ctx_.current_scope_))) { ret = OB_ERR_CBY_PSEUDO_COLUMN_NOT_ALLOWED; LOG_WARN("Specified pseudocolumn or operator not allowed here", KPC(child_expr), K(ret)); } else if (OB_FAIL(child_expr->extract_info())) { LOG_WARN("fail to formalize expr", KPC(child_expr), K(ret)); } else if (OB_UNLIKELY(child_expr->has_flag(CNT_PRIOR)) || OB_UNLIKELY(child_expr->has_flag(CNT_PSEUDO_COLUMN)) || OB_UNLIKELY(child_expr->has_flag(CNT_AGG)) || OB_UNLIKELY(child_expr->has_flag(CNT_CONNECT_BY_ROOT)) || OB_UNLIKELY(child_expr->has_flag(CNT_ROWNUM))) { ret = OB_ERR_CBY_PSEUDO_COLUMN_NOT_ALLOWED; LOG_WARN("Specified pseudocolumn or operator not allowed here", KPC(child_expr), K(ret)); } else if (OB_UNLIKELY(child_expr->has_flag(CNT_SUB_QUERY))) { ret = OB_NOT_SUPPORTED; LOG_WARN("prior a subquery still not supported", KPC(child_expr), K(ret)); LOG_USER_ERROR(OB_NOT_SUPPORTED, "subquery in prior is"); } else if (OB_FAIL(prior_expr->add_param_expr(child_expr))) { LOG_WARN("fail to add param", KPC(prior_expr), KPC(child_expr), K(ret)); } else { expr = prior_expr; LOG_DEBUG("prior expr", K(child_expr), KPC(child_expr), K(prior_expr), KPC(prior_expr)); } return ret; } int ObRawExprResolverImpl::process_datatype_or_questionmark(const ParseNode &node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObObjParam val; ObConstRawExpr *c_expr = NULL; ObString literal_prefix; bool is_paramlize = false; const ObLengthSemantics default_length_semantics = (OB_NOT_NULL(ctx_.session_info_) ? ctx_.session_info_->get_actual_nls_length_semantics() : LS_BYTE); const ObSQLSessionInfo *session_info = ctx_.session_info_; int64_t server_collation = CS_TYPE_INVALID; ObCollationType nation_collation = OB_NOT_NULL(ctx_.session_info_) ? ctx_.session_info_->get_nls_collation_nation() : CS_TYPE_INVALID; if (lib::is_oracle_mode() && nullptr == session_info) { ret = OB_ERR_UNEXPECTED; LOG_WARN("session info is null", K(ret)); } else if (lib::is_oracle_mode() && OB_FAIL( session_info->get_sys_variable(share::SYS_VAR_COLLATION_SERVER, server_collation))) { LOG_WARN("get sys variables failed", K(ret)); } else if (OB_FAIL(ObResolverUtils::resolve_const(&node, // stmt_type is only used in oracle mode lib::is_oracle_mode() ? session_info->get_stmt_type() : stmt::T_NONE, ctx_.expr_factory_.get_allocator(), ctx_.dest_collation_, nation_collation, ctx_.tz_info_, val, is_paramlize, literal_prefix, default_length_semantics, static_cast(server_collation), &(ctx_.parents_expr_info_), session_info->get_sql_mode(), nullptr != ctx_.secondary_namespace_))) { LOG_WARN("failed to resolve const", K(ret)); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(node.type_, c_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(c_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("const expr is null", K(ret), K(c_expr)); } else { if (node.is_date_unit_) { c_expr->set_is_date_unit(); } c_expr->set_value(val); //为空串重新设置一次meta信息 c_expr->set_expr_obj_meta(val.get_param_meta()); c_expr->set_literal_prefix(literal_prefix); // for mysql mode distinguish tinyint and literal bool if (T_BOOL == node.type_ || node.is_literal_bool_) { c_expr->set_is_literal_bool(true); } if (!val.is_unknown()) { c_expr->set_param(val); c_expr->set_accuracy(val.get_accuracy()); c_expr->set_result_flag(val.get_result_flag()); // not_null etc } else { if (!ctx_.is_extract_param_type_) { if (NULL == ctx_.param_list_) { LOG_INFO("NOTICE : UNIT TEST Code direction.", K(ret)); } else if (ctx_.param_list_->empty()) { //走到这里说明当前val是?,但是param_list是empty,说明是preapre阶段 ObObjMeta question_mark_meta; if (lib::is_oracle_mode()) { question_mark_meta.set_char(); question_mark_meta.set_collation_type(session_info->get_nls_collation()); c_expr->set_length_semantics(session_info->get_local_nls_length_semantics()); c_expr->set_length(ObAccuracy::PS_QUESTION_MARK_DEDUCE_LEN); } else { // Compatible with MySQL, use the default varbinary type for type deduce in the ps prepare phase question_mark_meta.set_varbinary(); } question_mark_meta.set_collation_level(CS_LEVEL_IMPLICIT); c_expr->set_meta_type(question_mark_meta); c_expr->set_expr_obj_meta(question_mark_meta); if (NULL == ctx_.external_param_info_) { /*do nothing...*/ } else if (ctx_.is_for_dbms_sql_ || (ctx_.is_for_dynamic_sql_ && OB_NOT_NULL(session_info->get_pl_context()))){ //NOTICE: only need to process PL dynamic sql and dbms sql /*dynmaic and dbms sql already prepare question mark in parse stage.*/ bool need_save = true; for (int64_t i = 0; OB_SUCC(ret) && i < ctx_.external_param_info_->count(); ++i) { CK (OB_NOT_NULL(ctx_.external_param_info_->at(i).first)); if (OB_SUCC(ret) && ctx_.external_param_info_->at(i).first->same_as(*c_expr)) { need_save = false; break; } } if (OB_SUCC(ret) && need_save) { OZ (ctx_.external_param_info_->push_back(std::make_pair(c_expr, c_expr))); OX (ctx_.prepare_param_count_++); } } else { //prepare stmt不需要type,只需要计算?的个数 if (OB_SUCC(ret) && nullptr != ctx_.secondary_namespace_) { const pl::ObPLSymbolTable* symbol_table = NULL; const pl::ObPLVar* var = NULL; CK (OB_NOT_NULL(symbol_table = ctx_.secondary_namespace_->get_symbol_table())); CK (OB_NOT_NULL(var = symbol_table->get_symbol(val.get_unknown()))); if (OB_SUCC(ret)) { if (0 == var->get_name().case_compare(pl::ObPLResolver::ANONYMOUS_ARG)) { CK (OB_NOT_NULL(var->get_type().get_meta_type())); CK (OB_NOT_NULL(var->get_type().get_data_type())); OX (c_expr->set_meta_type(*var->get_type().get_meta_type())); OX (c_expr->set_expr_obj_meta(*var->get_type().get_meta_type())); OX (c_expr->set_accuracy(var->get_type().get_data_type()->get_accuracy())); } } } ObRawExpr *original_expr = c_expr; OZ (ObResolverUtils::resolve_external_param_info(*ctx_.external_param_info_, ctx_.expr_factory_, ctx_.prepare_param_count_, original_expr)); OX (c_expr = static_cast(original_expr)); } } else if (val.get_unknown() >= ctx_.param_list_->count()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("question mark index out of param list count", "index", val.get_unknown(), "param_count", ctx_.param_list_->count()); } else { //execute stmt阶段,注:这里没有设置c_expr的accuracy会不会有问题 const ObObjParam ¶m = ctx_.param_list_->at(val.get_unknown()); c_expr->set_is_literal_bool(param.is_boolean()); if (param.is_ext()) { /* CK (OB_NOT_NULL(ctx_.session_info_), OB_NOT_NULL(ctx_.schema_checker_)); if (OB_SUCC(ret)) { const share::schema::ObUDTTypeInfo *udt_info = NULL; OZ (ctx_.schema_checker_->get_udt_info(param.get_udt_id(), udt_info), K(param.get_udt_id())); CK (OB_NOT_NULL(udt_info)); if (OB_SUCC(ret)) { if (udt_info->is_collection()) { */ //TODO: @ryan.ly 这里缺省认为一定是collection if (OB_SUCC(ret)) { c_expr->set_meta_type(param.get_meta()); c_expr->set_expr_obj_meta(param.get_param_meta()); c_expr->set_udt_id(param.get_udt_id()); c_expr->set_param(param); } /* } else { ret = OB_NOT_SUPPORTED; LOG_WARN("Record not support in sql yet", K(*udt_info), K(ret)); } } } */ } else { c_expr->set_meta_type(ObSQLUtils::is_oracle_empty_string(param) ? param.get_param_meta() : param.get_meta()); c_expr->set_expr_obj_meta(param.get_param_meta()); c_expr->set_accuracy(param.get_accuracy()); c_expr->set_result_flag(param.get_result_flag()); // not_null etc c_expr->set_param(param); sql::ObExprResType result_type = c_expr->get_result_type(); if (result_type.get_length() == -1) { if (result_type.is_varchar() || result_type.is_nvarchar2()) { result_type.set_length(OB_MAX_ORACLE_VARCHAR_LENGTH); } else if (result_type.is_char() || result_type.is_nchar()) { result_type.set_length(OB_MAX_ORACLE_CHAR_LENGTH_BYTE); } } c_expr->set_result_type(result_type); } //execute阶段不需要统计prepare_param_count_的个数 // ctx_.prepare_param_count_++; // LOG_DEBUG("prepare stmt add new param", K(ctx_.prepare_param_count_)); } } else { if (OB_ISNULL(ctx_.param_list_)) { ret = OB_NOT_INIT; LOG_WARN("context param list is null", K(ret)); } else if (val.get_unknown() >= ctx_.param_list_->count()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("question mark index out of param list count", "index", val.get_unknown(), "param_count", ctx_.param_list_->count()); } else { const ObObjParam ¶m = ctx_.param_list_->at(val.get_unknown()); c_expr->set_is_literal_bool(param.is_boolean()); if (param.is_ext()) { ret = OB_NOT_SUPPORTED; LOG_WARN("not support array binding", K(ret)); } else { //questionmark won't set meta_type again if (param.get_param_meta().get_type() != param.get_type()) { LOG_TRACE("question mark not suited", K(param.get_param_meta().get_type()), K(param.get_type()), K(common::lbt())); } c_expr->set_meta_type(param.get_param_meta()); c_expr->set_expr_obj_meta(param.get_param_meta()); c_expr->set_accuracy(param.get_accuracy()); c_expr->set_result_flag(param.get_result_flag()); // not_null etc c_expr->set_param(param); } } } } expr = c_expr; } return ret; } int ObRawExprResolverImpl::process_system_variable_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; if (OB_ISNULL(node) || OB_ISNULL(ctx_.sys_vars_)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(node), K_(ctx_.sys_vars)); } else { ObString str; str.assign_ptr(const_cast(node->str_value_), static_cast(node->str_len_)); if (OB_FAIL(ObRawExprUtils::build_get_sys_var(ctx_.expr_factory_, str, static_cast(node->value_), expr))) { LOG_WARN("failed to create expr", K(ret)); } else { ObVarInfo var_info; var_info.name_.assign_ptr(str.ptr(), static_cast(str.length())); var_info.type_ = SYS_VAR; if (OB_FAIL(ctx_.sys_vars_->push_back(var_info))) { LOG_WARN("failed to store var info", K(ret)); } } } return ret; } int ObRawExprResolverImpl::process_char_charset_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObConstRawExpr *c_expr = NULL; if (OB_ISNULL(node)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(node)); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_VARCHAR, c_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else { ObString charset_str(node->str_len_, node->str_value_); ObCharsetType charset_type = ObCharset::charset_type(charset_str); if (CHARSET_INVALID == charset_type) { ret = OB_ERR_UNKNOWN_CHARSET; LOG_WARN("invalid character set", K(charset_str), K(ret)); LOG_USER_ERROR(OB_ERR_UNKNOWN_CHARSET, charset_str.length(), charset_str.ptr()); } else if (OB_FAIL(sql::ObSQLUtils::is_charset_data_version_valid(charset_type, ctx_.session_info_->get_effective_tenant_id()))) { LOG_WARN("failed to check charset data version valid", K(ret)); } else { ObCollationType coll_type = ObCharset::get_system_collation(); ObObj val; val.set_varchar(charset_str); val.set_collation_type(coll_type); val.set_collation_level(CS_LEVEL_COERCIBLE); c_expr->set_value(val); expr = c_expr; } } return ret; } int ObRawExprResolverImpl::set_geo_func_name(ObSysFunRawExpr *func_expr, const ObItemType func_type) { int ret = OB_SUCCESS; if (OB_ISNULL(func_expr)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("null function expr", K(ret), K(get_type_name(func_type))); } else { switch (func_type) { case T_FUN_SYS_POINT: { OX(func_expr->set_func_name(N_POINT)); break; } case T_FUN_SYS_LINESTRING: { OX(func_expr->set_func_name(N_LINESTRING)); break; } case T_FUN_SYS_POLYGON: { OX(func_expr->set_func_name(N_POLYGON)); break; } case T_FUN_SYS_MULTIPOINT: { OX(func_expr->set_func_name(N_MULTIPOINT)); break; } case T_FUN_SYS_MULTILINESTRING: { OX(func_expr->set_func_name(N_MULTILINESTRING)); break; } case T_FUN_SYS_MULTIPOLYGON: { OX(func_expr->set_func_name(N_MULTIPOLYGON)); break; } case T_FUN_SYS_GEOMCOLLECTION: { OX(func_expr->set_func_name(N_GEOMCOLLECTION)); break; } default: { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid geometry function", K(ret), K(func_type)); break; } } } return ret; } int ObRawExprResolverImpl::process_geo_func_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObSysFunRawExpr *func_expr = NULL; if (OB_ISNULL(node)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(node)); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(node->type_, func_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_FAIL(set_geo_func_name(func_expr, node->type_))) { LOG_WARN("fail to set geo function name", K(ret), K(get_type_name(node->type_))); } else if (T_FUN_SYS_POINT == node->type_) { ObRawExpr *sub_expr1 = NULL; ObRawExpr *sub_expr2 = NULL; if (OB_UNLIKELY(2 != node->num_child_) || OB_ISNULL(node->children_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid node children", K(ret), K_(node->num_child), K_(node->children), K_(node->type)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[0], sub_expr1)))) { LOG_WARN("resolve x child failed", K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[1], sub_expr2)))) { LOG_WARN("resolve y child failed", K(ret)); } else if (OB_FAIL(func_expr->set_param_exprs(sub_expr1, sub_expr2))) { LOG_WARN("failed to add param expr", K(ret)); } } else if (OB_ISNULL(node->children_[0]) && T_FUN_SYS_GEOMCOLLECTION == node->type_) { // SELECT GEOMETRYCOLLECTION(); // do nothing } else { ParseNode *expr_list_node = node->children_[0]; if (OB_ISNULL(expr_list_node) || OB_UNLIKELY(T_EXPR_LIST != expr_list_node->type_) || OB_ISNULL(expr_list_node->children_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid children for geometry type function", K(node), K(expr_list_node)); } for (int64_t i = 0; OB_SUCC(ret) && i < expr_list_node->num_child_; ++i) { ObRawExpr *para_expr = NULL; if (OB_ISNULL(expr_list_node->children_[i])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid expr list node children", K(ret), K(i), K(expr_list_node->children_[i])); } else if (OB_FAIL(SMART_CALL(recursive_resolve(expr_list_node->children_[i], para_expr)))) { LOG_WARN("fail to recursive resolve expr list item", K(ret)); } else if (OB_FAIL(func_expr->add_param_expr(para_expr))) { LOG_WARN("fail to add param expr to expr", K(ret)); } } } if (OB_SUCC(ret)) { expr = func_expr; } return ret; } int ObRawExprResolverImpl::process_left_value_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObUserVarIdentRawExpr *var_expr = NULL; ObIArray *all_vars = (NULL == ctx_.query_ctx_ ? NULL : &ctx_.query_ctx_->all_user_variable_); bool query_has_udf = (NULL == ctx_.query_ctx_ ? false : ctx_.query_ctx_->has_udf_); if (OB_ISNULL(node) || OB_ISNULL(ctx_.sys_vars_) || OB_ISNULL(ctx_.user_var_exprs_)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(node), K_(ctx_.sys_vars), K(ctx_.user_var_exprs_)); } else { ObString str; str.assign_ptr(const_cast(node->str_value_), static_cast(node->str_len_)); 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); var_expr->set_is_contain_assign(true); } } } if (OB_SUCC(ret) && NULL == var_expr) { if (OB_FAIL(ctx_.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); var_expr->set_is_contain_assign(true); } } if (OB_SUCC(ret)) { var_expr->set_query_has_udf(query_has_udf); expr = var_expr; ObVarInfo var_info; var_info.name_.assign_ptr(str.ptr(), static_cast(str.length())); var_info.type_ = USER_VAR; if (OB_FAIL(ctx_.sys_vars_->push_back(var_info))) { SQL_ENG_LOG(WARN, "fail to push back var info", K(ret), K(var_info.name_)); } else if (OB_FAIL(add_var_to_array_no_dup(*ctx_.user_var_exprs_, var_expr))) { LOG_WARN("failed to add var to array no dup", K(ret)); } } } return ret; } int ObRawExprResolverImpl::process_outer_join_symbol_node( const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObOpRawExpr *b_expr = NULL; ObRawExpr *col_expr = NULL;; CK(OB_NOT_NULL(node), 1 == node->num_child_); OZ((ctx_.expr_factory_.create_raw_expr)(T_OP_ORACLE_OUTER_JOIN_SYMBOL, b_expr)); OZ(process_column_ref_node(node->children_[0], col_expr)); CK(OB_NOT_NULL(b_expr)); OZ((b_expr->add_param_expr)(col_expr)); if (OB_SUCC(ret)) { expr = b_expr; } return ret; } int ObRawExprResolverImpl::process_column_ref_node( const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObQualifiedName column_ref; if (OB_ISNULL(node) || OB_ISNULL(ctx_.columns_) || OB_ISNULL(ctx_.session_info_)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(node), K_(ctx_.columns), KPC(ctx_.session_info_), K(ret)); } else if (ctx_.session_info_->is_for_trigger_package() && ObRawExprUtils::is_new_old_column_ref(node) && !lib::is_oracle_mode()) { ParseNode *obj_access_node = NULL; OZ (ObRawExprUtils::mock_obj_access_ref_node(ctx_.expr_factory_.get_allocator(), obj_access_node, node, ctx_.tg_timing_event_)); CK (OB_NOT_NULL(obj_access_node)); OZ (process_obj_access_node(*obj_access_node, expr)); } else if (OB_FAIL(ObResolverUtils::resolve_column_ref( node, ctx_.case_mode_, column_ref))) { LOG_WARN("fail to resolve column ref", K(ret)); } else if (OB_UNLIKELY(column_ref.is_star_)) { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("all star should be replaced"); } else { if (column_ref.database_name_.empty() && column_ref.tbl_name_.empty() && !column_ref.col_name_.empty()) { if (OB_ISNULL(node->children_[2])) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(node), K(column_ref), K(ret)); } else { ObString ident_name(static_cast(node->children_[2]->str_len_), node->children_[2]->str_value_); ObObjAccessIdent access_ident(ident_name, OB_INVALID_INDEX); if (OB_FAIL(column_ref.access_idents_.push_back(access_ident))) { LOG_WARN("push back access ident failed", K(ret)); } } } if (OB_SUCC(ret)) { column_ref.parents_expr_info_ = ctx_.parents_expr_info_; ObColumnRefRawExpr *b_expr = NULL; if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_REF_COLUMN, b_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(b_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("column ref expr is null"); } else { column_ref.ref_expr_ = b_expr; if (OB_FAIL(ctx_.columns_->push_back(column_ref))) { LOG_WARN("Add column failed", K(ret)); } else { expr = b_expr; } } } } return ret; } int ObRawExprResolverImpl::process_any_or_all_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObRawExpr *sub_expr = NULL; if (OB_UNLIKELY(1 != node->num_child_) || OB_ISNULL(node->children_) || OB_ISNULL(node->children_[0])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid node children", K(ret), K(node->num_child_), K(node)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[0], sub_expr)))) { LOG_WARN("resolve sub-query failed", K(ret)); } else if (OB_ISNULL(sub_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("inavalid sub_expr", K(sub_expr)); } else if (T_REF_QUERY == sub_expr->get_expr_type()) { ObQueryRefRawExpr *sub_ref = static_cast(sub_expr); sub_ref->set_is_set(true); ObOpRawExpr *op_expr = NULL; if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(node->type_, op_expr))) { LOG_WARN("create ObOpRawExpr failed", K(ret)); } else if (OB_ISNULL(expr = op_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("op_expr is null"); } else if (OB_FAIL(op_expr->set_param_expr(sub_expr))) { LOG_WARN("failed to add param expr", K(ret)); } } else if (T_OP_ROW == sub_expr->get_expr_type()) { ObOpRawExpr *op_expr = NULL; if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(node->type_, op_expr))) { LOG_WARN("create ObOpRawExpr failed", K(ret)); } else if (OB_ISNULL(expr = op_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("op_expr is null"); } else if (OB_FAIL(op_expr->set_param_expr(sub_expr))) { LOG_WARN("failed to add param expr", K(ret)); } else { /*do nothing*/ } } else { expr = sub_expr; } return ret; } int ObRawExprResolverImpl::process_user_var_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; if (OB_ISNULL(node) || OB_ISNULL(ctx_.sys_vars_) || OB_ISNULL(ctx_.user_var_exprs_)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node), K_(ctx_.sys_vars), K(ctx_.user_var_exprs_)); } else if (OB_UNLIKELY(1 != node->num_child_) || OB_ISNULL(node->children_) || OB_ISNULL(node->children_[0])) { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("invalid node children for get user_val", K(ret), K(node->num_child_)); } else if (OB_FAIL(ObRawExprUtils::build_get_user_var( ctx_.expr_factory_, ObString(static_cast(node->children_[0]->str_len_), node->children_[0]->str_value_), expr, NULL, ctx_.query_ctx_, ctx_.user_var_exprs_))) { LOG_WARN("build get user var failed", K(ret)); } else { ObVarInfo var_info; var_info.name_.assign_ptr(node->children_[0]->str_value_, static_cast(node->children_[0]->str_len_)); var_info.type_ = USER_VAR; if (OB_FAIL(ctx_.sys_vars_->push_back(var_info))) { SQL_ENG_LOG(WARN, "fail to push back var info", K(ret), K(var_info.name_)); } } return ret; } int ObRawExprResolverImpl::process_not_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObRawExpr *sub_expr = NULL; ObOpRawExpr *not_expr = NULL; if (OB_ISNULL(node) || OB_UNLIKELY(1 != node->num_child_) || OB_ISNULL(node->children_) || node->type_ != T_OP_NOT || OB_ISNULL(ctx_.session_info_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid not expr or session_info_", K(node), KP(ctx_.session_info_)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[0], sub_expr)))) { LOG_WARN("resolve child expr failed", K(ret)); } else if (OB_ISNULL(sub_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("null ptr", K(ret), K(sub_expr)); } else if (T_OP_EXISTS == sub_expr->get_expr_type()) { sub_expr->set_expr_type(T_OP_NOT_EXISTS); expr = sub_expr; } else if (T_OP_NOT_EXISTS == sub_expr->get_expr_type()) { sub_expr->set_expr_type(T_OP_EXISTS); expr = sub_expr; } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(node->type_, not_expr))) { LOG_WARN("create ObOpRawExpr failed", K(ret)); } else if (OB_FAIL(not_expr->set_param_expr(sub_expr))) { LOG_WARN("failed to add param expr", K(ret)); } else if (OB_FAIL(ObRawExprUtils::try_add_bool_expr(not_expr, ctx_.expr_factory_))) { LOG_WARN("try_add_bool_expr failed", K(ret)); } else if (OB_ISNULL(expr = not_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("null ptr", K(ret), K(expr)); } return ret; } int ObRawExprResolverImpl::process_pos_or_neg_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; int64_t neg_cnt = 0; int64_t remain_neg_cnt = 0; const ParseNode *cur_expr = node; if (OB_ISNULL(cur_expr) || (T_OP_POS != cur_expr->type_ && T_OP_NEG != cur_expr->type_)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(cur_expr)); } for (; OB_SUCC(ret) && NULL != cur_expr && (cur_expr->type_ == T_OP_POS || cur_expr->type_ == T_OP_NEG);) { if (OB_UNLIKELY(1 != cur_expr->num_child_) || OB_ISNULL(cur_expr->children_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid cur expr", K(ret), K(cur_expr->num_child_)); } else { if (cur_expr->type_ == T_OP_NEG) { neg_cnt += 1; } cur_expr = cur_expr->children_[0]; } } // end for ObRawExpr *sub_expr = NULL; if (OB_SUCC(ret)) { if (OB_FAIL(SMART_CALL(recursive_resolve(cur_expr, sub_expr)))) { LOG_WARN("resolve child expr failed", K(ret)); } else if (OB_FAIL(try_negate_const(sub_expr, neg_cnt, remain_neg_cnt))) { LOG_WARN("try negate const failed", K(ret)); } else { expr = sub_expr; ObOpRawExpr *neg = NULL; for (int64_t i = 0; i < remain_neg_cnt && OB_SUCC(ret); i++) { if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_OP_NEG, neg))) { LOG_WARN("create ObOpRawExpr failed", K(ret)); } else if (OB_ISNULL(expr = neg)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("op expr is null"); } else if (OB_FAIL(neg->set_param_expr(sub_expr))) { LOG_WARN("failed to add param expr", K(ret)); } else { sub_expr = expr; } } } } return ret; } int ObRawExprResolverImpl::process_operator_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObRawExpr *sub_expr1 = NULL; ObRawExpr *sub_expr2 = NULL; ObOpRawExpr *b_expr = NULL; bool happened = false; if (OB_ISNULL(node)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(node)); } else if (OB_UNLIKELY(2 != node->num_child_) || OB_ISNULL(node->children_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid node children", K(ret), K_(node->num_child), K_(node->children), K_(node->type)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[0], sub_expr1)))) { LOG_WARN("resolve left child failed", K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[1], sub_expr2)))) { LOG_WARN("resolve right child failed", K(ret)); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(node->type_, b_expr))) { LOG_WARN("create ObOpRawExpr failed", K(ret)); } else if (OB_ISNULL(expr = b_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr is null"); } else if (OB_FAIL(b_expr->set_param_exprs(sub_expr1, sub_expr2))) { LOG_WARN("failed to add param expr", K(ret)); } else if (OB_FAIL(convert_any_or_all_expr(expr, happened))) { LOG_WARN("failed to convert any all expr", K(ret)); } else if (lib::is_oracle_mode() && !happened && T_OP_ROW != sub_expr1->get_expr_type() && T_OP_ROW != sub_expr2->get_expr_type()) { LOG_DEBUG("==============ORACLE MODE"); if (OB_ISNULL(ctx_.op_exprs_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ctx_.op_exprs_ is null", K(ctx_.op_exprs_), K(ret)); } else { ctx_.op_exprs_->push_back(b_expr); LOG_DEBUG("ctx_.op_exprs_ push", K(b_expr->get_param_count()), K(*b_expr)); } } return ret; } int ObRawExprResolverImpl::convert_any_or_all_expr(ObRawExpr *&expr, bool &happened) { int ret = OB_SUCCESS; ObRawExpr *sub_expr1 = NULL; ObRawExpr *sub_expr2 = NULL; ObRawExpr *sub_expr2_child = NULL; ObOpRawExpr *op_expr = NULL; happened = false; if (OB_ISNULL(expr) || OB_ISNULL(ctx_.op_exprs_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(expr), K(ctx_.op_exprs_), K(ret)); } else if (T_OP_EQ > expr->get_expr_type() || T_OP_NE < expr->get_expr_type()) { /*do nothing*/ } else if (OB_UNLIKELY(2 != expr->get_param_count()) || OB_ISNULL(sub_expr1 = expr->get_param_expr(0)) || OB_ISNULL(sub_expr2 = expr->get_param_expr(1))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected error", K(expr->get_param_count()), K(sub_expr1), K(sub_expr2), K(ret)); } else if (T_ANY != sub_expr2->get_expr_type() && T_ALL != sub_expr2->get_expr_type()) { /*do nothing*/ } else if (OB_UNLIKELY(1 != sub_expr2->get_param_count()) || OB_ISNULL(sub_expr2_child = sub_expr2->get_param_expr(0))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected error", K(sub_expr2->get_param_count()), K(sub_expr2_child), K(ret)); } else if (T_OP_ROW != sub_expr2_child->get_expr_type()) { /*do nothing*/ } else if (T_OP_EQ == expr->get_expr_type() && T_ANY == sub_expr2->get_expr_type() && OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_OP_IN, op_expr))) { LOG_WARN("create ObOpRawExpr failed", K(ret)); } else if (T_OP_NE == expr->get_expr_type() && T_ALL == sub_expr2->get_expr_type() && OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_OP_NOT_IN, op_expr))) { LOG_WARN("create ObOpRawExpr failed", K(ret)); } else if (OB_NOT_NULL(op_expr)) { if (OB_FAIL(op_expr->set_param_exprs(sub_expr1, sub_expr2_child))) { LOG_WARN("failed to set param exprs", K(ret)); } else if (T_OP_ROW != sub_expr1->get_expr_type() && T_OP_ROW != sub_expr2_child->get_expr_type() && OB_FAIL(ctx_.op_exprs_->push_back(op_expr))) { LOG_WARN("failed to push back exprs", K(ret)); } else { happened = true; expr = op_expr; LOG_DEBUG("succeed to convert any/all expr", K(*expr)); } } else if (T_ANY == sub_expr2->get_expr_type() && (T_OP_EQ < expr->get_expr_type() && expr->get_expr_type() <= T_OP_NE) && OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_OP_OR, op_expr))) { LOG_WARN("failed to create or expr", K(ret)); } else if (T_ALL == sub_expr2->get_expr_type() && (T_OP_EQ <= expr->get_expr_type() && expr->get_expr_type() < T_OP_NE) && OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_OP_AND, op_expr))) { LOG_WARN("failed to create and expr", K(ret)); } else if (OB_NOT_NULL(op_expr)) { for (int64_t i = 0; OB_SUCC(ret) && i < sub_expr2_child->get_param_count(); i++) { ObOpRawExpr *tmp_expr = NULL; if (OB_ISNULL(sub_expr2_child->get_param_expr(i))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret)); } else if ((T_OP_EQ != expr->get_expr_type() && T_OP_NE != expr->get_expr_type()) && (T_OP_ROW == sub_expr2_child->get_param_expr(i)->get_expr_type() || T_OP_ROW == sub_expr1->get_expr_type())) { //由于oracle不支持形如(2,3) < ((2,3)(2,4))向量列表,因此需要禁掉,'<='、'>'、'>='同理 ret = OB_ERR_OPERATOR_CANNOT_BE_USED_WITH_LIST; LOG_WARN("this operator cannot be used with lists", K(ret)); } else if (T_OP_EQ == expr->get_expr_type() && OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_OP_EQ, tmp_expr))) { LOG_WARN("failed to create equal expr", K(ret)); } else if (T_OP_NE == expr->get_expr_type() && OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_OP_NE, tmp_expr))) { LOG_WARN("failed to create not equal expr", K(ret)); } else if (T_OP_LT == expr->get_expr_type() && OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_OP_LT, tmp_expr))) { LOG_WARN("failed to create less expr", K(ret)); } else if (T_OP_LE == expr->get_expr_type() && OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_OP_LE, tmp_expr))) { LOG_WARN("failed to create less equal expr", K(ret)); } else if (T_OP_GT == expr->get_expr_type() && OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_OP_GT, tmp_expr))) { LOG_WARN("failed to create great expr", K(ret)); } else if (T_OP_GE == expr->get_expr_type() && OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_OP_GE, tmp_expr))) { LOG_WARN("failed to create great equal expr", K(ret)); } else if (OB_ISNULL(tmp_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret)); } else if (OB_FAIL(tmp_expr->set_param_exprs(sub_expr1, sub_expr2_child->get_param_expr(i)))) { LOG_WARN("failed to set param exprs", K(ret)); } else if (T_OP_ROW != sub_expr1->get_expr_type() && T_OP_ROW != sub_expr2_child->get_param_expr(i)->get_expr_type() && OB_FAIL(ctx_.op_exprs_->push_back(tmp_expr))) { LOG_WARN("failed to push back exprs", K(ret)); } else if (sub_expr2_child->get_param_count() == 1) {//any/all仅仅只有一个row时,没有必要创建and/or op_expr = tmp_expr; } else if (OB_FAIL(op_expr->add_param_expr(tmp_expr))) { LOG_WARN("failed to add param exprs", K(ret)); } else {/*do nothing*/} } if (OB_SUCC(ret)) { happened = true; expr = op_expr; LOG_DEBUG("succeed to convert great equal any expr to great equal or expr", K(*expr)); } } else { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret)); } return ret; } int ObRawExprResolverImpl::process_is_or_is_not_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObRawExpr *sub_expr1 = NULL; ObRawExpr *sub_expr2 = NULL; ObOpRawExpr *b_expr = NULL; ObConstRawExpr *c_expr = NULL; if (OB_ISNULL(node)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node)); } else if (OB_UNLIKELY(2 != node->num_child_) || OB_ISNULL(node->children_) || OB_ISNULL(node->children_[0]) || OB_ISNULL(node->children_[1])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid node children", K(ret), K(node->num_child_), K(node->type_)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[0], sub_expr1)))) { LOG_WARN("resolve left child failed", K(ret)); } else { if (T_DEFAULT_NULL == node->children_[1]->type_) { ParseNode default_node; default_node.type_ = T_NULL; default_node.num_child_ = 0; default_node.value_ = INT64_MAX; default_node.str_len_ = 0; default_node.str_value_ = NULL; default_node.text_len_ = 0; default_node.raw_text_ = NULL; if (OB_FAIL(process_datatype_or_questionmark(default_node, sub_expr2))) { LOG_WARN("fail to resolver right child node", K(ret), "node_type", node->children_[1]->type_); } } else if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[1], sub_expr2)))) { LOG_WARN("resolve right child failed", K(ret)); } } if (OB_SUCC(ret)) { if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(node->type_, b_expr))) { LOG_WARN("create ObOpRawExpr failed", K(ret)); } else if (OB_ISNULL(b_expr) ) { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr is null", KP(b_expr), KP(c_expr)); } else if (OB_FAIL(b_expr->set_param_exprs(sub_expr1, sub_expr2))) { LOG_WARN("failed to add param expr", K(ret)); } else { expr = b_expr; } } return ret; } int ObRawExprResolverImpl::process_regexp_or_not_regexp_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObOpRawExpr *t_expr = NULL; int64_t num_child = 2; if (OB_ISNULL(node)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node)); } else if (OB_FAIL(process_node_with_children(node, num_child, t_expr))) { LOG_WARN("fail to preocess node with children", K(ret)); } else if (OB_ISNULL(t_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("process node fail with invalid expr", K(ret), K(t_expr)); } else { // convert `A not regex B' to `NOT A regex B' if (T_OP_NOT_REGEXP != node->type_) { t_expr->set_expr_type(node->type_); } else { t_expr->set_expr_type(T_OP_REGEXP); ObOpRawExpr *not_expr = NULL; if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_OP_NOT, not_expr))) { LOG_WARN("create ObOpRawExpr failed", K(ret)); } else if (OB_ISNULL(not_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("not expr is null"); } else if (OB_FAIL(not_expr->set_param_expr(t_expr))) { LOG_WARN("failed to add param expr", K(ret)); } else { t_expr = not_expr; } } expr = t_expr; } return ret; } int ObRawExprResolverImpl::process_between_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; const int64_t BTW_PARAM_NUM = 3; // Why BTW_PARAM_NUM + 1 ? // The content of the 4th raw expr is same to that of the 1st raw expr. // But the ptr addresses need to be different because our optimizer relys on it. ObRawExpr *btw_params[BTW_PARAM_NUM + 1]; if (OB_ISNULL(node)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node)); } else if (node->type_ != T_OP_BTW && node->type_ != T_OP_NOT_BTW) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid node type", K(node->type_), K(ret)); } else if (3 != node->num_child_ || OB_ISNULL(node->children_) || OB_ISNULL(node->children_[0]) || OB_ISNULL(node->children_[1]) || OB_ISNULL(node->children_[2])) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid node", K(ret)); } else { bool can_transform_in_mysql_mode = false; for (int64_t i = 0; OB_SUCC(ret) && i < BTW_PARAM_NUM; ++i ) { if (OB_FAIL(recursive_resolve(node->children_[i], btw_params[i]))) { SQL_RESV_LOG(WARN, "resolve child expr failed", K(ret), K(i)); } else if (OB_ISNULL(btw_params[i])) { LOG_WARN("unexpected null", K(ret), K(i)); } } // The content of the 4th raw expr is same to that of the 1st raw expr. // But the ptr addresses need to be different because our optimizer relys on it. if (OB_FAIL(ret)) { } else if (OB_FAIL(recursive_resolve(node->children_[0], btw_params[BTW_PARAM_NUM]))) { SQL_RESV_LOG(WARN, "resolve child expr failed", K(ret), K(BTW_PARAM_NUM)); } else if (OB_ISNULL(btw_params[BTW_PARAM_NUM])) { LOG_WARN("unexpected null", K(ret), K(BTW_PARAM_NUM)); } if (OB_SUCC(ret) && lib::is_mysql_mode()) { if (OB_ISNULL(ctx_.session_info_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected null", K(ret), K(ctx_.session_info_)); } else if (OB_FAIL(btw_params[1]->extract_info())) { LOG_WARN("fail to extract info child 2 of between node", K(ret)); } else if (OB_FAIL(btw_params[2]->extract_info())) { LOG_WARN("fail to extract info child 3 of between node", K(ret)); } else if (btw_params[1]->has_flag(CNT_PL_UDF) || btw_params[2]->has_flag(CNT_PL_UDF)) { // skip rewrite, relevant issue : https://work.aone.alibaba-inc.com/issue/35465473 } else if (btw_params[1]->is_const_expr() && btw_params[2]->is_const_expr()) { // We will transform if the second and the third param are both const value or const expr // and the result meta types of them are same. // Why need const? Because 'resolve_columns' is called later than 'expr_resolver.resolve'. if (OB_FAIL(btw_params[1]->deduce_type(ctx_.session_info_))) { LOG_WARN("fail to deduce_type child 2 of between node", K(ret)); } else if (OB_FAIL(btw_params[2]->deduce_type(ctx_.session_info_))) { LOG_WARN("fail to deduce_type child 3 of between node", K(ret)); } else if (btw_params[1]->get_result_meta() == btw_params[2]->get_result_meta()) { can_transform_in_mysql_mode = true; } } } if (OB_SUCC(ret)) { if ((lib::is_oracle_mode() || can_transform_in_mysql_mode)) { // convert between expr to >= and <= if (OB_FAIL(transform_between_expr(btw_params, expr, T_OP_NOT_BTW == node->type_))) { LOG_WARN("fail to convert between expr", K(ret)); } } else { ObOpRawExpr *btw_expr = NULL; if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(node->type_, btw_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < BTW_PARAM_NUM; ++i) { if (OB_FAIL(btw_expr->add_param_expr(btw_params[i]))) { LOG_WARN("fail to set param expr", K(ret), K(i)); } } } expr = btw_expr; } } } return ret; } // We will transform between to >= and <= all the time in oracle mode // or while the result meta type of second param and the third param are same in mysql mode // expr1 NOT BETWEEN expr2 AND expr3 ==> NOT (expr1 >= expr2 AND expr1 <= expr3) // expr1 BETWEEN expr2 AND expr3 ==> expr1 >= expr2 AND expr1 <= expr3 int ObRawExprResolverImpl::transform_between_expr( ObRawExpr **btw_params, ObRawExpr *&expr, const bool is_not_btw) { int ret = OB_SUCCESS; ObOpRawExpr *ge_expr = NULL; ObOpRawExpr *le_expr = NULL; ObOpRawExpr *and_expr = NULL; if (OB_ISNULL(ctx_.session_info_) || OB_ISNULL(ctx_.op_exprs_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected null", K(ret), K(ctx_.session_info_), K(ctx_.op_exprs_)); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_OP_GE, ge_expr))) { LOG_WARN("failed to create great equal expr", K(ret)); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_OP_LE, le_expr))) { LOG_WARN("failed to create less equal expr", K(ret)); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_OP_AND, and_expr))) { LOG_WARN("failed to create a new expr", K(ret)); } else if (OB_ISNULL(ge_expr) || OB_ISNULL(le_expr) || OB_ISNULL(and_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret), K(ge_expr), K(le_expr), K(and_expr)); } else if (OB_FAIL(add_params_to_op_expr(btw_params[0], btw_params[1], ge_expr))) { LOG_WARN("add param to op_expr failed", K(ret), K(btw_params[0]), K(btw_params[1]), K(ge_expr)); } else if (OB_FAIL(add_params_to_op_expr(btw_params[3], btw_params[2], le_expr))) { LOG_WARN("add param to op_expr failed", K(ret), K(btw_params[3]), K(btw_params[2]), K(le_expr)); } else if (OB_FAIL(and_expr->add_param_expr(ge_expr))) { LOG_WARN("add ge_expr to or expr failed", K(ret), K(ge_expr), K(le_expr), K(and_expr)); } else if (OB_FAIL(and_expr->add_param_expr(le_expr))) { LOG_WARN("add le_expr to or expr failed", K(ret), K(ge_expr), K(le_expr), K(and_expr)); } if (OB_SUCC(ret)) { if (is_not_btw) { // T_OP_NOT_BTW == node->type_ // expr1 NOT BETWEEN expr2 AND expr3 ==> NOT (expr1 >= expr2 AND expr1 <= expr3) ObOpRawExpr *not_expr = NULL; if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_OP_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("failed to create not expr", K(ret)); } else if (OB_FAIL(not_expr->set_param_expr(and_expr))) { LOG_WARN("failed to set param for not op", K(ret), K(*not_expr)); } else { expr = not_expr; // T_OP_NOT_BTW } } else { expr = and_expr; // T_OP_BTW } } return ret; } int ObRawExprResolverImpl::add_params_to_op_expr( ObRawExpr *op_param_1, ObRawExpr *op_param_2, ObOpRawExpr *op_expr) { int ret = OB_SUCCESS; bool happened = false; ObRawExpr *expr = NULL; if (OB_ISNULL(op_param_1) || OB_ISNULL(op_param_2) || OB_ISNULL(op_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected null ptr", K(ret), K(op_param_1), K(op_param_2), K(op_expr)); } else if (OB_ISNULL(expr = op_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr is null"); } else if (OB_FAIL(op_expr->set_param_exprs(op_param_1, op_param_2))) { LOG_WARN("failed to add param expr", K(ret)); } else if (OB_FAIL(convert_any_or_all_expr(expr, happened))) { LOG_WARN("failed to convert any all expr", K(ret)); } else if (lib::is_oracle_mode() && !happened && T_OP_ROW != op_param_1->get_expr_type() && T_OP_ROW != op_param_2->get_expr_type()) { LOG_DEBUG("==============ORACLE MODE"); if (OB_ISNULL(ctx_.op_exprs_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ctx_.op_exprs_ is null", K(ctx_.op_exprs_), K(ret)); } else { ctx_.op_exprs_->push_back(op_expr); LOG_DEBUG("ctx_.op_exprs_ push", K(op_expr->get_param_count()), K(*op_expr)); } } return ret; } int ObRawExprResolverImpl::process_like_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObOpRawExpr *t_expr = NULL; if (OB_ISNULL(node)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node)); } else if ((T_OP_NOT_LIKE == node->type_ || T_OP_LIKE == node->type_) && (node->num_child_ == 3)) { // 如果显式指定了escape sign 为'', oracle模式应该报错 ParseNode* &escape_node = node->children_[2]; if (OB_ISNULL(escape_node)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected escape node", K(ret), K(escape_node)); } else if (T_QUESTIONMARK == escape_node->type_) { // 如果经过了fast parser, 那么escape 会被替换为?, 需要去param list中取真正的值 if (OB_ISNULL(ctx_.param_list_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("param_list_ is null", K(ret), K(ctx_.param_list_)); } else if (ctx_.param_list_->empty() && nullptr != ctx_.secondary_namespace_) { const pl::ObPLSymbolTable* symbol_table = NULL; const pl::ObPLVar* var = NULL; CK (OB_NOT_NULL(symbol_table = ctx_.secondary_namespace_->get_symbol_table())); CK (OB_NOT_NULL(var = symbol_table->get_symbol(escape_node->value_))); if (0 == var->get_name().case_compare(pl::ObPLResolver::ANONYMOUS_ARG) && NULL != var->get_pl_data_type().get_data_type() && ObNullType == var->get_pl_data_type().get_data_type()->get_obj_type()) { ret = OB_ERR_INVALID_ESCAPE_CHAR_LENGTH; LOG_WARN("invalid escape char length, expect 1, get 0", K(ret)); } } else if (escape_node->value_ < 0 || escape_node->value_ >= ctx_.param_list_->count()) { if (OB_NOT_NULL(ctx_.session_info_) && ctx_.session_info_->is_ps_prepare_stage()) { // skip check question mark about escape node in prepare statement } else { ret = OB_ERR_UNEXPECTED; LOG_WARN("index is out of range", K(escape_node->value_), K(ctx_.param_list_->count())); } // c1 like '123' escape null is illegal in oracle mode, but legal in mysql mode } else if (ctx_.param_list_->at(escape_node->value_).is_null() && lib::is_oracle_mode()) { ret = OB_ERR_INVALID_ESCAPE_CHAR_LENGTH; LOG_WARN("invalid escape char length, expect 1, get 0", K(ret)); } else if (ctx_.param_list_->at(escape_node->value_).is_null()) { // escape null is legal in mysql } else { // Note: currently when like node has escape, it's childs will not be parameterized and // therefore this line is meaningless. However when you wanna to open this, this line may // be somewhat useful. //escape = ctx_.param_list_->at(escape_node->value_).get_string()[0]; } } else if (((T_CHAR == escape_node->type_ && 0 == escape_node->str_len_) || T_NULL == escape_node->type_) && lib::is_oracle_mode()) { ret = OB_ERR_INVALID_ESCAPE_CHAR_LENGTH; LOG_WARN("invalid escape char length, expect 1, get 0", K(ret)); } } else { // do nothing } if (OB_FAIL(ret)){ } else if (OB_FAIL(process_node_with_children(node, node->num_child_, t_expr))) { LOG_WARN("fail to process node with children", K(ret), K(node)); } else if (OB_ISNULL(t_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("process node fail with invalid expr", K(ret), K(t_expr)); } else { //如果有两个child_,则说明like 或 not like的escape参数没有显示给出,这里给默认值'\\' if ((T_OP_NOT_LIKE == node->type_ || T_OP_LIKE == node->type_) && (2 == node->num_child_)) { ObRawExpr *escape_expr = NULL; ParseNode escape_node; escape_node.type_ = T_VARCHAR; escape_node.num_child_ = 0; escape_node.value_ = INT64_MAX; escape_node.str_len_ = 1; escape_node.str_value_ = "\\"; escape_node.text_len_ = 0; escape_node.raw_text_ = NULL; /* bugfix:https://work.aone.alibaba-inc.com/issue/36691548 in NO_BACKSLASH_ESCAPES mode, 'like BINARY xxx' stmt should also set the escapes as null, instead of '\' */ bool no_escapes = false; if (node->children_[1]->type_ == T_FUN_SYS && node->children_[1]->num_child_ == 2 && node->children_[1]->children_[0]->str_len_ ==4 && (0 == strcmp(node->children_[1]->children_[0]->str_value_, "cast")) && node->children_[1]->children_[1]->num_child_ == 2 // T_EXPR_LIST node && node->children_[1]->children_[1]->children_[1]->int16_values_[OB_NODE_CAST_TYPE_IDX] == T_VARCHAR && node->children_[1]->children_[1]->children_[1]->int16_values_[OB_NODE_CAST_COLL_IDX] == BINARY_COLLATION) { IS_NO_BACKSLASH_ESCAPES(ctx_.session_info_->get_sql_mode(), no_escapes); } if (OB_FAIL(process_datatype_or_questionmark(escape_node, escape_expr))) { LOG_WARN("fail to resolver defalut excape node", K(ret)); } else if (OB_FAIL(t_expr->add_param_expr(escape_expr))) { LOG_WARN("fail to set param expr"); } else if (lib::is_oracle_mode() || no_escapes) { // Oracle mode, if not specify escape, then no escape, but the implementation of like must contain escape // so we rewrite like without escape // c1 like '%x\x%' --> c1 like replace('%x\x%', '\','\\') escape '\' -> c1 like '%x\\x%' escape '\' ObRawExpr *replace_expr1 = NULL; ObRawExpr *replace_expr2 = NULL; ObSysFunRawExpr *replace_expr = NULL; ParseNode replace_node; replace_node.type_ = T_VARCHAR; replace_node.num_child_ = 0; replace_node.value_ = INT64_MAX; replace_node.str_len_ = 2; replace_node.str_value_ = "\\\\"; replace_node.text_len_ = 0; replace_node.raw_text_ = NULL; if (3 != t_expr->get_param_count()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("like expr with escape must contain 3 arguments"); } else { if (OB_FAIL(process_datatype_or_questionmark(escape_node, replace_expr1))) { LOG_WARN("fail to resolve replace expr1", K(ret)); } else if (OB_FAIL(process_datatype_or_questionmark(replace_node, replace_expr2))) { LOG_WARN("fail to resolve replace expr2"); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_FUN_SYS, replace_expr))) { LOG_WARN("create ObOpRawExpr failed", K(ret)); } else if (OB_ISNULL(replace_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("func_expr is null"); } else if (OB_FAIL(replace_expr->add_param_expr(t_expr->get_param_expr(1)))) { LOG_WARN("fail to set param expr"); } else if (OB_FAIL(replace_expr->add_param_expr(replace_expr1))) { LOG_WARN("fail to set param expr"); } else if (OB_FAIL(replace_expr->add_param_expr(replace_expr2))) { LOG_WARN("fail to set param expr"); } else { replace_expr->set_func_name(N_REPLACE); if (OB_FAIL(t_expr->replace_param_expr(1, replace_expr))) { LOG_WARN("fail to replace param expr"); } } } } else { //do nothing } } // convert `A not like B' to `NOT A like B' if (OB_SUCC(ret)) { ObOpRawExpr *not_expr = NULL; if (T_OP_NOT_LIKE != node->type_) { t_expr->set_expr_type(node->type_); } else { t_expr->set_expr_type(T_OP_LIKE); if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_OP_NOT, not_expr))) { LOG_WARN("create ObOpRawExpr failed", K(ret)); } else if (OB_ISNULL(not_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("not_expr is null"); } else if (OB_FAIL(not_expr->set_param_expr(t_expr))) { LOG_WARN("failed to add param expr", K(ret)); } else { t_expr = not_expr; } } expr = t_expr; } } return ret; } int ObRawExprResolverImpl::process_in_or_not_in_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObOpRawExpr *in_expr = NULL; ObRawExpr *sub_expr1 = NULL; ObRawExpr *sub_expr2 = NULL; if (OB_ISNULL(node)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node)); } else if (OB_UNLIKELY(2 != node->num_child_) || OB_ISNULL(node->children_) || OB_ISNULL(node->children_[0]) || OB_ISNULL(node->children_[1])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid node children", K(ret), K(node->children_)); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_INVALID, in_expr))) { LOG_WARN("create ObOpRawExpr failed", K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[0], sub_expr1)))) { LOG_WARN("resolve left raw expr failed", K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[1], sub_expr2)))) { LOG_WARN("resolve right child failed", K(ret)); } else if (OB_ISNULL(sub_expr1) || OB_ISNULL(sub_expr2)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("resolve get invalid expr", K(ret), K(sub_expr1), K(sub_expr2)); } else { ObItemType param_type2 = sub_expr2->get_expr_type(); LOG_DEBUG("in or not in with:", K(*sub_expr1), K(*sub_expr2), K(lib::is_oracle_mode())); if (T_REF_QUERY == param_type2) { ObQueryRefRawExpr *sub_ref = static_cast(sub_expr2); sub_ref->set_is_set(true); //rewrite expr in sub-query as expr = ANY(sub-query) //rewrite expr not in sub-query as expr != ALL(sub-query) ObOpRawExpr *u_expr = NULL; if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_INVALID, u_expr))) { LOG_WARN("create ObOpRawExpr failed", K(ret)); } else if (OB_ISNULL(in_expr) || OB_ISNULL(u_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr is null", KP(in_expr), KP(u_expr)); } else { ObItemType u_expr_type = (T_OP_IN == node->type_) ? T_ANY : T_ALL; ObItemType in_expr_type = (T_OP_IN == node->type_) ? T_OP_EQ : T_OP_NE; u_expr->set_expr_type(u_expr_type); if (OB_FAIL(u_expr->set_param_expr(sub_expr2))) { LOG_WARN("failed to add param expr", K(ret)); } else if (OB_FAIL(in_expr->set_param_exprs(sub_expr1, u_expr))) { LOG_WARN("failed to add param expr", K(ret)); } else { in_expr->set_expr_type(in_expr_type); expr = in_expr; } } } else if (T_OP_ROW == param_type2) { ObOpRawExpr *row_expr = static_cast(sub_expr2); if (OB_ISNULL(row_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("failed to cast ObOpRawExpr", K(ret)); } else if (1 == row_expr->get_param_count()) { ObRawExpr *param = lib::is_oracle_mode() ? row_expr : row_expr->get_param_expr(0); if (OB_FAIL(in_expr->set_param_exprs(sub_expr1, param))) { LOG_WARN("failed to add param expr", K(ret)); } else { ObItemType expr_type = (T_OP_IN == node->type_) ? T_OP_EQ : T_OP_NE; in_expr->set_expr_type(expr_type); expr = in_expr; } } else { if (OB_FAIL(in_expr->set_param_exprs(sub_expr1, sub_expr2))) { LOG_WARN("failed to add param expr", K(ret)); } else { in_expr->set_expr_type(node->type_); expr = in_expr; } } LOG_DEBUG("final in or not in expr ", K(*in_expr)); } else { if (OB_FAIL(in_expr->set_param_exprs(sub_expr1, sub_expr2))) { LOG_WARN("failed to add param expr", K(ret)); } else { ObItemType expr_type = (T_OP_IN == node->type_) ? T_OP_EQ : T_OP_NE; in_expr->set_expr_type(expr_type); expr = in_expr; } } } return ret; } int ObRawExprResolverImpl::process_case_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObCaseOpRawExpr *case_expr = NULL; ObRawExpr *arg_expr = NULL; bool all_then_null = true; if (OB_ISNULL(node) || OB_UNLIKELY(3 != node->num_child_) || OB_UNLIKELY(T_CASE != node->type_) || OB_ISNULL(ctx_.session_info_)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid PraseNode or session_info_", K(node), KP(ctx_.session_info_)); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_INVALID, case_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(case_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("case expr is null"); } else if (NULL != node->children_ && NULL != node->children_[0]) { if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[0], arg_expr)))) { LOG_WARN("fail to recursive resolve children", K(ret)); } else { case_expr->set_arg_param_expr(arg_expr); case_expr->set_expr_type(T_OP_ARG_CASE); } } else { case_expr->set_expr_type(T_OP_CASE); } if (OB_SUCC(ret)) { ParseNode *when_node = NULL; ObRawExpr *when_expr = NULL; ObRawExpr *then_expr = NULL; if (OB_ISNULL(node->children_) || OB_ISNULL(node->children_[1]) || T_WHEN_LIST != node->children_[1]->type_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid case children", K(node), K(node->children_)); } for (int32_t i = 0; OB_SUCC(ret) && i < node->children_[1]->num_child_; i++) { if (OB_ISNULL(node->children_[1]->children_) || OB_ISNULL(node->children_[1]->children_[i])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid children", K(node->children_[1]->children_)); } else { when_node = node->children_[1]->children_[i]; if (OB_UNLIKELY(2 != when_node->num_child_) || OB_ISNULL(when_node->children_) || OB_ISNULL(when_node->children_[0]) || OB_ISNULL(when_node->children_[1])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid when node children", K(when_node->children_)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(when_node->children_[0], when_expr)))) { LOG_WARN("fail to recursive resolver", K(ret), K(when_node->children_[0])); } else if (OB_FAIL(SMART_CALL(recursive_resolve(when_node->children_[1], then_expr)))) { LOG_WARN("fail to recursive resolve", K(ret), K(when_node->children_[1])); } else if (OB_FAIL(case_expr->add_when_param_expr(when_expr))) { LOG_WARN("Add when expression failed", K(ret)); } else if (OB_FAIL(case_expr->add_then_param_expr(then_expr))) { LOG_WARN("Add then expression failed", K(ret)); } else if(T_QUESTIONMARK == then_expr->get_expr_type()) { if (then_expr->get_result_meta().get_type() != ObNullType) { all_then_null = false; } } else if (then_expr->get_expr_type() != T_NULL) { all_then_null = false; } } //end else } // end for } if (OB_SUCC(ret)) { if (NULL != node->children_[2]) { ObRawExpr *default_expr = NULL; if (T_DEFAULT_NULL == node->children_[2]->type_) { ParseNode default_node; default_node.type_ = T_NULL; default_node.num_child_ = 0; default_node.value_ = INT64_MAX; default_node.str_len_ = 0; default_node.str_value_ = NULL; default_node.text_len_ = 0; default_node.raw_text_ = NULL; if (OB_FAIL(process_datatype_or_questionmark(default_node, default_expr))) { LOG_WARN("fail to resolver defalut excape node", K(ret)); } } else if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[2], default_expr)))) { LOG_WARN("fail to recursive resolve", K(ret), K(node->children_[2])); } if (OB_SUCC(ret)){ if (T_QUESTIONMARK == default_expr->get_expr_type()) { if (default_expr->get_result_meta().get_type() != ObNullType) { all_then_null = false; } } else if (default_expr->get_expr_type() != T_NULL) { all_then_null = false; } case_expr->set_default_param_expr(default_expr); } } } if (OB_SUCC(ret) && all_then_null && is_oracle_mode() && T_PL_SCOPE == ctx_.current_scope_) { ret = OB_ERR_CASE_NULL; LOG_WARN("at least one result in the CASE expression must not be NULL", K(ret)); } if (OB_SUCC(ret)) { if (OB_FAIL(ObRawExprUtils::try_add_bool_expr(case_expr, ctx_.expr_factory_))) { LOG_WARN("try_add_bool_expr for case expr failed", K(ret)); } } if (OB_SUCC(ret)) { expr = case_expr; } return ret; } int ObRawExprResolverImpl::process_sub_query_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObQueryRefRawExpr *sub_query_expr = NULL; if (OB_ISNULL(node) || OB_ISNULL(ctx_.sub_query_info_)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node), K_(ctx_.sub_query_info)); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_REF_QUERY, sub_query_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(expr = sub_query_expr) || OB_ISNULL(ctx_.session_info_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid argument", KP(expr), KP(ctx_.session_info_), K(ret)); } else if (node->is_multiset_ && ctx_.current_scope_ == T_PL_SCOPE) { ret = OB_ERR_INVALID_SUBQUERY_USE; LOG_WARN("subquery not allowed in this context", K(ret)); } else { sub_query_expr->set_cursor(1 == node->value_); sub_query_expr->set_is_multiset(node->is_multiset_); ObSubQueryInfo sq_info; sq_info.sub_query_ = node; sq_info.ref_expr_ = sub_query_expr; sq_info.parents_expr_info_ = ctx_.parents_expr_info_; if (OB_FAIL(ctx_.sub_query_info_->push_back(sq_info))) { LOG_WARN("resolve sub-query failed", K(ret)); } } return ret; } int ObRawExprResolverImpl::process_agg_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObRawExpr *sub_expr = NULL; ObAggFunRawExpr *agg_expr = NULL; if (OB_ISNULL(ctx_.aggr_exprs_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("aggr exprs is null", K(ret)); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(node->type_, agg_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(agg_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("agg_expr is null"); } else if (OB_FAIL(ctx_.aggr_exprs_->push_back(agg_expr))) { LOG_WARN("store aggr expr failed", K(ret)); } else if (OB_UNLIKELY(1 > node->num_child_) || OB_ISNULL(node->children_) || (2 == node->num_child_ && OB_ISNULL(node->children_[1])) || (T_FUN_COUNT == node->type_ && (OB_ISNULL(node->children_[0])))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid node children", K(node->num_child_)); } else { bool need_add_flag = !ctx_.parents_expr_info_.has_member(IS_AGG); if (need_add_flag && OB_FAIL(ctx_.parents_expr_info_.add_member(IS_AGG))) { LOG_WARN("failed to add member", K(ret)); } else if (T_FUN_COUNT == node->type_ && 1 == node->num_child_) { if (OB_UNLIKELY(T_STAR != node->children_[0]->type_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid node children", K(node), K(node->children_)); } //when '*', do not set parameter } else if (T_FUN_COUNT == node->type_ && 2 == node->num_child_ && T_DISTINCT == node->children_[0]->type_) { ParseNode *expr_list_node = node->children_[1]; if (OB_ISNULL(expr_list_node) || OB_UNLIKELY(T_EXPR_LIST != expr_list_node->type_) || OB_ISNULL(expr_list_node->children_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid children for COUNT function", K(node), K(expr_list_node)); } for (int64_t i = 0; OB_SUCC(ret) && i < expr_list_node->num_child_; ++i) { sub_expr = NULL; if (OB_ISNULL(expr_list_node->children_[i])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid expr list node children", K(ret), K(i), K(expr_list_node->children_[i])); } else if (OB_FAIL(SMART_CALL(recursive_resolve(expr_list_node->children_[i], sub_expr)))) { LOG_WARN("fail to recursive resolve expr list item", K(ret)); } else if (OB_FAIL(agg_expr->add_real_param_expr(sub_expr))) { LOG_WARN("fail to add param expr to agg expr", K(ret)); } } //end for } else if (T_FUN_APPROX_COUNT_DISTINCT == node->type_ || T_FUN_APPROX_COUNT_DISTINCT_SYNOPSIS == node->type_) { ParseNode *expr_list_node = node->children_[0]; if (OB_ISNULL(expr_list_node) || OB_UNLIKELY(T_EXPR_LIST != expr_list_node->type_) || OB_ISNULL(expr_list_node->children_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid children for APPROX_COUNT_DISTINCT(_SYNOPSIS) function", K(node), K(expr_list_node)); //oracle mode allow only 1 argument } else if (lib::is_oracle_mode() && expr_list_node->num_child_ != 1) { ret = OB_ERR_PARAM_SIZE; LOG_WARN("get invalid number of arguments", K(ret)); } for (int64_t i = 0; OB_SUCC(ret) && i < expr_list_node->num_child_; ++i) { sub_expr = NULL; if (OB_ISNULL(expr_list_node->children_[i])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid expr list node children", K(ret), K(i), K(expr_list_node->children_[i])); } else if (OB_FAIL(SMART_CALL(recursive_resolve(expr_list_node->children_[i], sub_expr)))) { LOG_WARN("fail to recursive resolve expr list item", K(ret)); } else if (OB_FAIL(agg_expr->add_real_param_expr(sub_expr))) { LOG_WARN("fail to add param expr to agg expr", K(ret)); } } // end for } else if (T_FUN_APPROX_COUNT_DISTINCT_SYNOPSIS_MERGE == node->type_) { sub_expr = NULL; if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[0], sub_expr)))) { LOG_WARN("fail to recursive resolve node child", K(ret), K(node->children_[0])); } else if (OB_FAIL(agg_expr->add_real_param_expr(sub_expr))) { LOG_WARN("fail to add param expr", K(ret)); } } else if (T_FUN_CORR == node->type_ || T_FUN_COVAR_POP == node->type_ || T_FUN_COVAR_SAMP == node->type_ || T_FUN_REGR_SLOPE == node->type_ || T_FUN_REGR_INTERCEPT == node->type_ || T_FUN_REGR_COUNT == node->type_ || T_FUN_REGR_R2 == node->type_ || T_FUN_REGR_AVGX == node->type_ || T_FUN_REGR_AVGY == node->type_ || T_FUN_REGR_SXX == node->type_ || T_FUN_REGR_SYY == node->type_ || T_FUN_REGR_SXY == node->type_) { sub_expr = NULL; if (OB_UNLIKELY(3 != node->num_child_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("op expected 3 childrens", K(ret)); } else if (node->children_[0] != NULL && node->children_[0]->type_ == T_DISTINCT) { ret = OB_DISTINCT_NOT_ALLOWED; LOG_WARN("distinct not allowed in aggr", K(ret)); } else if (OB_FAIL(recursive_resolve(node->children_[1], sub_expr))) { LOG_WARN("fail to recursive resolve expr list item", K(ret)); } else if (OB_FAIL(agg_expr->add_real_param_expr(sub_expr))) { LOG_WARN("fail to add param expr to agg expr", K(ret)); } else if (OB_FAIL(recursive_resolve(node->children_[2], sub_expr))) { LOG_WARN("fail to recursive resolve expr list item", K(ret)); } else if (OB_FAIL(agg_expr->add_real_param_expr(sub_expr))) { LOG_WARN("fail to add param expr to agg expr", K(ret)); } } else if (T_FUN_TOP_FRE_HIST == node->type_) { ObRawExpr *param_expr = NULL; ObRawExpr *error_expr = NULL; ObRawExpr *item_size_expr = NULL; ObSysFunRawExpr *window_size_expr = NULL; ObRawExpr *div_expr = NULL; ObConstRawExpr *one_expr = NULL; if (OB_ISNULL(ctx_.session_info_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret), K(ctx_.session_info_)); } else if (OB_UNLIKELY(3 != node->num_child_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected error", K(ret), K(node->num_child_)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[0], error_expr)))) { LOG_WARN("fail to recursive resolve expr item", K(ret)); } else if (OB_ISNULL(error_expr) || OB_UNLIKELY(ObRawExpr::EXPR_CONST != error_expr->get_expr_class())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("get invalid window_size_expr", K(ret), K(error_expr)); } else if (OB_FAIL(ObRawExprUtils::build_const_int_expr(ctx_.expr_factory_, ObIntType, 1, one_expr))) { LOG_WARN("failed to build const int expr", K(ret)); } else if (OB_FAIL(ObRawExprUtils::build_common_binary_op_expr(ctx_.expr_factory_, T_OP_DIV, one_expr, error_expr, div_expr))) { LOG_WARN("failed to common binary op expr", K(ret)); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_FUN_SYS_CEIL, window_size_expr))) { LOG_WARN("failed to create fun sys floor", K(ret)); } else if (OB_ISNULL(window_size_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("floor expr is null", K(ret)); } else if (OB_FAIL(window_size_expr->set_param_expr(div_expr))) { LOG_WARN("failed to set param expr", K(ret)); } else if (OB_FAIL(agg_expr->add_real_param_expr(window_size_expr))) { LOG_WARN("fail to add param expr to agg expr", K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[1], param_expr)))) { LOG_WARN("fail to recursive resolve expr item", K(ret)); } else if (OB_ISNULL(param_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get invalid param_expr", K(ret), K(param_expr)); } else if (OB_FAIL(agg_expr->add_real_param_expr(param_expr))) { LOG_WARN("fail to add param expr to agg expr", K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[2], item_size_expr)))) { LOG_WARN("fail to recursive resolve expr item", K(ret)); } else if (OB_ISNULL(item_size_expr) || OB_UNLIKELY(ObRawExpr::EXPR_CONST != item_size_expr->get_expr_class())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("get invalid item_size_expr", K(ret), K(item_size_expr)); } else if (OB_FAIL(agg_expr->add_real_param_expr(item_size_expr))) { LOG_WARN("fail to add param expr to agg expr", K(ret)); } else {/*do nothing*/} } else if (T_FUN_HYBRID_HIST == node->type_ || T_FUN_JSON_OBJECTAGG == node->type_) { if (OB_UNLIKELY(2 != node->num_child_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected error, node expected 2 arguments", K(ret), K(node->num_child_)); } else { sub_expr = NULL; ObRawExpr *sub_expr2 = NULL; if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[0], sub_expr)))) { LOG_WARN("fail to recursive resolve node child", K(ret)); } else if (OB_FAIL(agg_expr->add_real_param_expr(sub_expr))) { LOG_WARN("fail to add param expr", K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[1], sub_expr2)))) { LOG_WARN("fail to recursive resolve node child", K(ret)); } else if (OB_FAIL(agg_expr->add_real_param_expr(sub_expr2))) { LOG_WARN("fail to add param expr", K(ret)); } else { OrderItem order_item; order_item.expr_ = sub_expr; order_item.order_type_ = NULLS_FIRST_ASC; if (OB_FAIL(agg_expr->add_order_item(order_item))) { LOG_WARN("fail to add median order item", K(ret)); } else {/* do nothong */} } } } else if (T_FUN_GROUPING_ID == node->type_) { ParseNode *expr_list_node = node->children_[0]; if (OB_ISNULL(expr_list_node) || OB_UNLIKELY(T_EXPR_LIST != expr_list_node->type_) || OB_ISNULL(expr_list_node->children_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid children for GOUPING_ID function", K(node), K(expr_list_node)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < expr_list_node->num_child_; ++i) { sub_expr = NULL; if (OB_ISNULL(expr_list_node->children_[i])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid expr list node children", K(ret), K(i), K(expr_list_node->children_[i])); } else if (OB_FAIL(SMART_CALL(recursive_resolve(expr_list_node->children_[i], sub_expr)))) { LOG_WARN("fail to recursive resolve expr list item", K(ret)); } else if (OB_FAIL(agg_expr->add_real_param_expr(sub_expr))) { LOG_WARN("fail to add param expr to agg expr", K(ret)); } } // end for } } else if (T_FUN_ORA_JSON_ARRAYAGG == node->type_) { for (int64_t i = 0; OB_SUCC(ret) && i < node->num_child_; ++i) { sub_expr = NULL; if (OB_ISNULL(node->children_[i])) { // do nothing } else if (i == PARSE_JSON_ARRAYAGG_DISTINCT && node->children_[PARSE_JSON_ARRAYAGG_DISTINCT]->type_ == T_DISTINCT) { ret = OB_DISTINCT_NOT_ALLOWED; LOG_WARN("distinct not allowed in json arrayagg", K(ret)); } else if (i == PARSE_JSON_ARRAYAGG_DISTINCT && node->children_[PARSE_JSON_ARRAYAGG_DISTINCT]->type_ == T_ALL) { } else if (i == PARSE_JSON_ARRAYAGG_ORDER) { const ParseNode *sort_list = NULL; if (OB_UNLIKELY(node->children_[i]->type_ != T_ORDER_BY) || OB_UNLIKELY(node->children_[i]->num_child_ != 2) || OB_ISNULL(node->children_[i]->children_) || OB_ISNULL(sort_list = node->children_[i]->children_[0])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid parameter", K(node->children_[i]), K(sort_list), K(ret)); } else if (NULL != node->children_[i]->children_[1]) { ret = OB_ERR_ORDER_SIBLINGS_BY_NOT_ALLOWED; LOG_WARN("should not be here, invalid agg node", K(ret), K(node)); } else { for (int32_t i = 0; OB_SUCC(ret) && i < sort_list->num_child_; i++) { ParseNode *sort_node = sort_list->children_[i]; OrderItem order_item; if (OB_FAIL(SMART_CALL(recursive_resolve(sort_node->children_[0], sub_expr)))) { LOG_WARN("fail to recursive resolve expr list item", K(ret)); } else { order_item.expr_ = sub_expr; if (sort_node->children_[1]->value_ == 1) { order_item.order_type_ = NULLS_LAST_ASC; } else { order_item.order_type_ = NULLS_FIRST_DESC; } if (OB_FAIL(agg_expr->add_order_item(order_item))) { LOG_WARN("Add order expression error", K(ret)); } } } } } else if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[i], sub_expr)))) { LOG_WARN("fail to recursive resolve expr list item", K(ret)); } else if (OB_FAIL(agg_expr->add_real_param_expr(sub_expr))) { LOG_WARN("fail to add param expr to agg expr", K(ret)); } } // end for } else if (T_FUN_ORA_JSON_OBJECTAGG == node->type_) { for (int64_t i = 0; OB_SUCC(ret) && i < node->num_child_; ++i) { sub_expr = NULL; ObString def_val(7, "default"); if (OB_ISNULL(node->children_[i])) { // do nothing } else if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[i], sub_expr)))) { LOG_WARN("fail to recursive resolve expr list item", K(ret)); } else if ((i == 4) && (0 == def_val.case_compare(node->children_[i]->raw_text_))) { (static_cast(sub_expr))->set_scale(1); } if (OB_SUCC(ret) && OB_FAIL(agg_expr->add_real_param_expr(sub_expr))) { LOG_WARN("fail to add param expr to agg expr", K(ret)); } } // end for } else if (T_FUN_COUNT != node->type_ || (T_FUN_COUNT == node->type_ && 2 == node->num_child_ && T_ALL == node->children_[0]->type_) || T_FUN_GROUPING == node->type_) { sub_expr = NULL; int64_t pos = (T_FUN_GROUPING == node->type_) ? 0 : 1; if ((T_FUN_VAR_POP == node->type_ || T_FUN_VAR_SAMP == node->type_ || T_FUN_STDDEV_POP == node->type_ || T_FUN_STDDEV_SAMP == node->type_ || T_FUN_MEDIAN == node->type_ || T_FUN_JSON_ARRAYAGG == node->type_) && node->children_[0] != NULL && node->children_[0]->type_ == T_DISTINCT) { ret = OB_DISTINCT_NOT_ALLOWED; LOG_WARN("distinct not allowed in aggr", K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[pos], sub_expr)))) { LOG_WARN("fail to recursive resolve node child", K(ret)); } else if (OB_FAIL(agg_expr->add_real_param_expr(sub_expr))) { LOG_WARN("fail to add param expr", K(ret)); } else if (T_FUN_MEDIAN == node->type_) { OrderItem order_item; order_item.expr_ = sub_expr; order_item.order_type_ = NULLS_FIRST_ASC; if (OB_FAIL(agg_expr->add_order_item(order_item))) { LOG_WARN("fail to add median order item", K(ret)); } else { /* do nothong */ } } } else { ret = OB_ERR_UNEXPECTED; LOG_WARN("should not be here, invalid agg node", K(ret), K(node)); } if (OB_SUCC(ret)) { if (NULL != node->children_[0] && node->children_[0]->type_ == T_DISTINCT) { agg_expr->set_param_distinct(true); } // add invalid table bit index, avoid aggregate function expressions are used as filters if (OB_FAIL(agg_expr->get_relation_ids().add_member(0))) { LOG_WARN("failed to add member", K(ret)); } else if (need_add_flag && (ctx_.parents_expr_info_.del_member(IS_AGG))) { LOG_WARN("failed to del member", K(ret)); } else { expr = agg_expr; } } } OZ(param_not_row_check(expr)); return ret; } int ObRawExprResolverImpl::process_group_aggr_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObAggFunRawExpr *agg_expr = NULL; if (OB_ISNULL(ctx_.aggr_exprs_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("aggr_exprs_ is null"); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(node->type_, agg_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(agg_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("agg_expr is null"); } else if (OB_FAIL(ctx_.aggr_exprs_->push_back(agg_expr))) { LOG_WARN("store aggr expr failed", K(ret)); } else if (OB_ISNULL(node->children_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("inalid group concat node", K(ret), K(node->children_)); } else { bool need_add_flag = !ctx_.parents_expr_info_.has_member(IS_AGG); ParseNode *expr_list_node = node->children_[1]; if (need_add_flag && OB_FAIL(ctx_.parents_expr_info_.add_member(IS_AGG))) { LOG_WARN("failed to add member", K(ret)); } else if (OB_ISNULL(expr_list_node) || OB_UNLIKELY(T_EXPR_LIST != expr_list_node->type_) || OB_ISNULL(expr_list_node->children_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("group_concat node with invalid children", K(ret), K(expr_list_node)); } for (int64_t i = 0; OB_SUCC(ret) && i < expr_list_node->num_child_; ++i) { ObRawExpr *sub_expr = NULL; if (OB_ISNULL(expr_list_node->children_[i])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid expr list node children", K(ret), K(i), K(expr_list_node->children_[i])); } else if (OB_FAIL(SMART_CALL(recursive_resolve(expr_list_node->children_[i], sub_expr)))) { LOG_WARN("fail to recursive resolve expr list item", K(ret)); } else if (OB_FAIL(agg_expr->add_real_param_expr(sub_expr))) { LOG_WARN("fail to add param expr to agg expr", K(ret)); } else if ((T_FUN_GROUP_PERCENTILE_DISC == node->type_ || T_FUN_GROUP_PERCENTILE_CONT == node->type_) && OB_UNLIKELY(1 < agg_expr->get_real_param_count())) { ret = OB_ERR_PARAM_SIZE; LOG_WARN("invalid number of arguments", K(ret), K(node->type_), K(agg_expr->get_real_param_count())); } } // end for if (OB_SUCC(ret)) { if (NULL != node->children_[0] && T_DISTINCT == node->children_[0]->type_) { if (T_FUN_GROUP_CONCAT != node->type_ || T_FUN_GROUP_PERCENTILE_CONT == node->type_ || T_FUN_GROUP_PERCENTILE_DISC == node->type_) { ret = OB_DISTINCT_NOT_ALLOWED; LOG_WARN("distinct not allowed in aggr", K(ret)); } else { agg_expr->set_param_distinct(true); } } // add invalid table bit index, avoid aggregate function expressions are used as filters if (OB_SUCCESS == ret && OB_FAIL(agg_expr->get_relation_ids().add_member(0))) { LOG_WARN("failed to add member", K(ret)); } } if (OB_SUCC(ret)) { //解析separator ObRawExpr *separator_expr = NULL; if (NULL != node->children_[3]) { if (OB_UNLIKELY(1 != node->children_[3]->num_child_) || OB_ISNULL(node->children_[3]->children_) || OB_ISNULL(node->children_[3]->children_[0]) || !IS_DATATYPE_OR_QUESTIONMARK_OP(node->children_[3]->children_[0]->type_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid separator_expr child", K(ret), K(node->children_[3])); } else if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[3]->children_[0], separator_expr)))) { LOG_WARN("fail to recursive resolve separator expr", K(ret)); } else if (OB_ISNULL(separator_expr) || OB_UNLIKELY(ObRawExpr::EXPR_CONST != separator_expr->get_expr_class())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get invalid separator_expr", K(ret), K(separator_expr)); } } agg_expr->set_separator_param_expr(separator_expr); } if (OB_SUCC(ret)) { //解析order by if (NULL != node->children_[2]) { const ParseNode *order_by_node = node->children_[2]; if (OB_ISNULL(order_by_node) || OB_UNLIKELY(order_by_node->type_ != T_ORDER_BY) || OB_UNLIKELY(order_by_node->num_child_ != 2) || OB_ISNULL(order_by_node->children_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("order by node is null or invalid", K(order_by_node)); } else if (OB_UNLIKELY(NULL != order_by_node->children_[1])) { ret = OB_ERR_INVALID_SIBLINGS; LOG_WARN("ORDER SIBLINGS BY clause not allowed here"); } else if (OB_FAIL(process_sort_list_node(order_by_node->children_[0], agg_expr))) { LOG_WARN("fail to process sort list node", K(ret), K(node)); } else if ((T_FUN_GROUP_PERCENTILE_DISC == node->type_ || T_FUN_GROUP_PERCENTILE_CONT == node->type_) && OB_FAIL(reset_aggr_sort_nulls_first(agg_expr->get_order_items_for_update()))) { LOG_WARN("failed to reset median aggr sort direction", K(ret), K(node)); } else {/*do nothing*/} } } if (OB_SUCC(ret)) { if (need_add_flag && (ctx_.parents_expr_info_.del_member(IS_AGG))) { LOG_WARN("failed to del member", K(ret)); } else { expr = agg_expr; } } } OZ(param_not_row_check(expr)); return ret; } int ObRawExprResolverImpl::process_keep_aggr_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObAggFunRawExpr *agg_expr = NULL; bool keep_is_last = false; ObRawExpr *sub_expr = NULL; if (OB_ISNULL(ctx_.aggr_exprs_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("aggr_exprs_ is null"); } else if (OB_ISNULL(node) || OB_UNLIKELY(node->num_child_ != 4)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get invalid argument", K(ret), K(node)); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(node->type_, agg_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(agg_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("agg_expr is null"); } else if (OB_FAIL(ctx_.aggr_exprs_->push_back(agg_expr))) { LOG_WARN("store aggr expr failed", K(ret)); } else if (OB_ISNULL(node->children_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("inalid group concat node", K(ret), K(node->children_)); } else { bool need_add_flag = !ctx_.parents_expr_info_.has_member(IS_AGG); if (need_add_flag && OB_FAIL(ctx_.parents_expr_info_.add_member(IS_AGG))) { LOG_WARN("failed to add member", K(ret)); } else if (NULL != node->children_[0] && T_DISTINCT == node->children_[0]->type_) { ret = OB_DISTINCT_NOT_ALLOWED; LOG_WARN("distinct not allowed in aggr", K(ret)); } else if (T_FUN_KEEP_COUNT == node->type_ && node->children_[1] != NULL && T_STAR == node->children_[1]->type_) { /*do nothing*/ } else if (OB_FAIL(recursive_resolve(node->children_[1], sub_expr))) { LOG_WARN("fail to recursive resolve node child", K(ret), K(node->children_[1])); } else if (OB_FAIL(agg_expr->add_real_param_expr(sub_expr))) { LOG_WARN("fail to add param expr", K(ret)); } if (OB_SUCC(ret)) { if (NULL != node->children_[2] && node->children_[2]->type_ == T_LAST) { keep_is_last = true; } //解析order by if (NULL != node->children_[3]) { const ParseNode *order_by_node = node->children_[3]; if (OB_ISNULL(order_by_node) || OB_UNLIKELY(order_by_node->type_ != T_ORDER_BY) || OB_UNLIKELY(order_by_node->num_child_ != 2) || OB_ISNULL(order_by_node->children_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("order by node is null or invalid", K(order_by_node)); } else if (OB_UNLIKELY(NULL != order_by_node->children_[1])) { ret = OB_ERR_INVALID_SIBLINGS; LOG_WARN("ORDER SIBLINGS BY clause not allowed here"); } else if (OB_FAIL(process_sort_list_node(order_by_node->children_[0], agg_expr))) { LOG_WARN("fail to process sort list node", K(ret), K(node)); } } //当keep分析函数是取排完序之后的最后一行相等值的数据进行处理时,为了在执行的时候能够更加高效,在resolve阶段 //就可以转为对应的first形式,这样执行的时候只需要取第一行数据,同时还可以少使用一个变量,eg: // select max(c1) keep (dense_rank last order by c2) from t1; //<==> // select max(c1) keep (dense_rank first order by c2 desc NULLS FIRST) from t1; if (OB_SUCC(ret) && keep_is_last) { if (OB_FAIL(reset_keep_aggr_sort_direction(agg_expr->get_order_items_for_update()))) { LOG_WARN("failed to reset keep aggr sort direction", K(ret)); } else {/*do nothing*/} } //对于order by item为常量的情形,可以退化普通的聚合函数,比如: // count(*) keep(dense_rank first order by 1) from t1 <==> count(*) from t1; if (OB_SUCC(ret) && agg_expr->get_order_items().count() == 0) { if (OB_FAIL(convert_keep_aggr_to_common_aggr(agg_expr))) { LOG_WARN("failed to convert keep aggr to common aggr", K(ret)); } else {/*do nothing*/} } } if (OB_SUCC(ret)) { if (need_add_flag && (ctx_.parents_expr_info_.del_member(IS_AGG))) { LOG_WARN("failed to del member", K(ret)); } else { expr = agg_expr; } } } OZ(param_not_row_check(expr)); return ret; } int ObRawExprResolverImpl::convert_keep_aggr_to_common_aggr(ObAggFunRawExpr *&agg_expr) { int ret = OB_SUCCESS; if (OB_ISNULL(agg_expr) || OB_UNLIKELY(!IS_KEEP_AGGR_FUN(agg_expr->get_expr_type()) || agg_expr->get_order_items().count() != 0)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get invalid argument", K(agg_expr), K(ret)); } else { ObItemType aggr_type = T_INVALID; switch (agg_expr->get_expr_type()) { case T_FUN_KEEP_MAX: aggr_type = T_FUN_MAX; break; case T_FUN_KEEP_MIN: aggr_type = T_FUN_MIN; break; case T_FUN_KEEP_SUM: aggr_type = T_FUN_SUM; break; case T_FUN_KEEP_COUNT: aggr_type = T_FUN_COUNT; break; case T_FUN_KEEP_AVG: aggr_type = T_FUN_AVG; break; case T_FUN_KEEP_STDDEV: aggr_type = T_FUN_STDDEV; break; case T_FUN_KEEP_VARIANCE: aggr_type = T_FUN_VARIANCE; break; case T_FUN_KEEP_WM_CONCAT: aggr_type = T_FUN_GROUP_CONCAT; break; default: ret = OB_ERR_UNEXPECTED; LOG_WARN("get invalid type", K(aggr_type), K(ret)); break; } if (OB_SUCC(ret)) { agg_expr->set_expr_type(aggr_type);//由于所有的aggr的结构都是一样的,所以直接改变类型就可以 } } return ret; } //用于group/keep aggr int ObRawExprResolverImpl::process_sort_list_node(const ParseNode *node, ObAggFunRawExpr *parent_agg_expr) { int ret = OB_SUCCESS; // 只有agg function才会进这里 // 往agg_fun_expr中添加order item信息 if (OB_ISNULL(node) || OB_ISNULL(parent_agg_expr) || OB_ISNULL(node->children_)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node), K(parent_agg_expr)); } else { const ObIArray &agg_real_param_exprs = parent_agg_expr->get_real_param_exprs(); for (int64_t i = 0; OB_SUCC(ret) && i < node->num_child_; ++i) { OrderItem order_item; const ParseNode *sort_node = node->children_[i]; if (OB_ISNULL(sort_node) || OB_UNLIKELY(2 != sort_node->num_child_) || OB_ISNULL(sort_node->children_) || OB_ISNULL(sort_node->children_[0]) || OB_ISNULL(sort_node->children_[1])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid sort node", K(ret), K(sort_node)); } else if (OB_FAIL(ObResolverUtils::set_direction_by_mode(*sort_node, order_item))) { LOG_WARN("failed to set direction by mode", K(ret)); } else { // do nothing } if (OB_SUCC(ret)) { if (OB_UNLIKELY(sort_node->children_[0]->type_ == T_INT && sort_node->children_[0]->value_ >= 0)) { // The order-by item is specified using column position // ie. ORDER BY 1 DESC // oracle mode: order by 1 中的1被解释成常量表达式而不是列的位置, 此时需要忽略 if (lib::is_oracle_mode()) { //rank、dense_rank、percent_rank、cume_dist需要这个常量值进行判断,所以需要添加进去 switch (parent_agg_expr->get_expr_type()) { case T_FUN_GROUP_RANK: case T_FUN_GROUP_PERCENT_RANK: case T_FUN_GROUP_DENSE_RANK: case T_FUN_GROUP_CUME_DIST: case T_FUN_GROUP_PERCENTILE_CONT: case T_FUN_GROUP_PERCENTILE_DISC: { if (OB_FAIL(recursive_resolve(sort_node->children_[0], order_item.expr_))) { LOG_WARN("fail to recursive resolve order item expr", K(ret)); } break; } default: continue; } } else { int32_t pos = static_cast(sort_node->children_[0]->value_); if (pos <= 0 || pos > agg_real_param_exprs.count()) { // for SELECT statement, we need to make sure the column positions are valid ret = OB_ERR_BAD_FIELD_ERROR; _LOG_WARN("Unknown column '%d' in 'order by statement'", pos); } else { // create expression order_item.expr_ = agg_real_param_exprs.at(pos - 1); } } } else if (T_QUESTIONMARK == sort_node->children_[0]->type_) { ret = OB_ERR_PARSE_SQL; LOG_WARN("'?' can't after 'order by", K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(sort_node->children_[0], order_item.expr_)))) { LOG_WARN("fail to recursive resolve order item expr", K(ret)); } OZ(not_row_check(order_item.expr_)); if (OB_SUCC(ret) && OB_FAIL(parent_agg_expr->add_order_item(order_item))) { LOG_WARN("fail to add order item to agg expr", K(ret)); } } } // end for } //end else return ret; } int ObRawExprResolverImpl::reset_aggr_sort_nulls_first(ObIArray &aggr_sort_item) { int ret = OB_SUCCESS; for (int64_t i = 0; OB_SUCC(ret) && i < aggr_sort_item.count(); ++i) { switch (aggr_sort_item.at(i).order_type_) { case NULLS_FIRST_ASC: case NULLS_LAST_ASC: aggr_sort_item.at(i).order_type_ = NULLS_FIRST_ASC; break; case NULLS_FIRST_DESC: case NULLS_LAST_DESC: aggr_sort_item.at(i).order_type_ = NULLS_FIRST_DESC; break; default: ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected order type", K(ret), K(aggr_sort_item.at(i).order_type_)); break; } } return ret; } int ObRawExprResolverImpl::reset_keep_aggr_sort_direction(ObIArray &aggr_sort_item) { int ret = OB_SUCCESS; for (int64_t i = 0; OB_SUCC(ret) && i < aggr_sort_item.count(); ++i) { switch (aggr_sort_item.at(i).order_type_) { case NULLS_FIRST_ASC: aggr_sort_item.at(i).order_type_ = NULLS_LAST_DESC; break; case NULLS_LAST_ASC: aggr_sort_item.at(i).order_type_ = NULLS_FIRST_DESC; break; case NULLS_FIRST_DESC: aggr_sort_item.at(i).order_type_ = NULLS_LAST_ASC; break; case NULLS_LAST_DESC: aggr_sort_item.at(i).order_type_ = NULLS_FIRST_ASC; break; default: ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected order type", K(ret), K(aggr_sort_item.at(i).order_type_)); break; } } return ret; } int ObRawExprResolverImpl::process_oracle_timestamp_node(const ParseNode *node, ObRawExpr *&expr, int16_t min_precision, int16_t max_precision, int16_t default_precision) { int ret = OB_SUCCESS; ObSysFunRawExpr *c_expr = NULL; if (OB_ISNULL(node)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node)); } else { if (OB_UNLIKELY(NULL == node->children_ || 1 != node->num_child_)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node)); } else { int16_t scale = 0; //get precision if (NULL != node->children_[0]) { scale = static_cast(node->children_[0]->value_); } else { scale = default_precision; } if (OB_UNLIKELY(scale > max_precision) || OB_UNLIKELY(scale < min_precision)) { ret = OB_ERR_DATETIME_INTERVAL_PRECISION_OUT_OF_RANGE; } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(node->type_, c_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(c_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("c_expr is null"); } else { c_expr->set_scale(scale); expr = c_expr; } } } return ret; } int ObRawExprResolverImpl::process_timestamp_node(const ParseNode *node, ObString &err_info, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObSysFunRawExpr *c_expr = NULL; if (OB_ISNULL(node)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node)); } else { int16_t scale = 0; if (OB_UNLIKELY(NULL == node->children_ || 1 != node->num_child_)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node)); } else { if (NULL != node->children_[0]) { scale = static_cast(node->children_[0]->value_); } else { scale = 0; } if (OB_UNLIKELY(scale > OB_MAX_DATETIME_PRECISION)) { ret = OB_ERR_TOO_BIG_PRECISION; LOG_USER_ERROR(OB_ERR_TOO_BIG_PRECISION, scale, to_cstring(err_info), OB_MAX_DATETIME_PRECISION); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(node->type_, c_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(c_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("c_expr is null"); } else { c_expr->set_scale(scale); expr = c_expr; } } } return ret; } int ObRawExprResolverImpl::process_collation_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; if (OB_ISNULL(node)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node)); } else { ObConstRawExpr *c_expr = NULL; ObString collation(node->str_len_, node->str_value_); ObCollationType collation_type = ObCharset::collation_type(collation); if (CS_TYPE_INVALID == collation_type) { ret = OB_ERR_UNKNOWN_COLLATION; LOG_USER_ERROR(OB_ERR_UNKNOWN_COLLATION, (int)node->str_len_, node->str_value_); } else if (OB_FAIL(sql::ObSQLUtils::is_charset_data_version_valid(common::ObCharset::charset_type_by_coll(collation_type), ctx_.session_info_->get_effective_tenant_id()))) { LOG_WARN("failed to check charset data version valid", K(ret)); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_INT, c_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(c_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("c_expr is null"); } else { ObObj val; val.set_int(static_cast(collation_type)); val.set_collation_type(collation_type); val.set_collation_level(CS_LEVEL_IGNORABLE); c_expr->set_value(val); expr = c_expr; } } return ret; } int ObRawExprResolverImpl::process_if_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObCaseOpRawExpr *case_expr = NULL; if (OB_ISNULL(node) || OB_ISNULL(node->children_)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node)); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_OP_CASE, case_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(case_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("case_expr is null"); } else { const ParseNode *expr_list = node->children_[1]; if (OB_ISNULL(expr_list) || OB_UNLIKELY(T_EXPR_LIST != expr_list->type_) || OB_UNLIKELY(3 != expr_list->num_child_) || OB_ISNULL(expr_list->children_) || OB_ISNULL(expr_list->children_[0]) || OB_ISNULL(expr_list->children_[1]) || OB_ISNULL(expr_list->children_[2])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("parser tree error", K(ret), K(node)); } else { ObRawExpr *when_expr = NULL; ObRawExpr *then_expr = NULL; ObRawExpr *default_expr = NULL; if (OB_FAIL(SMART_CALL(recursive_resolve(expr_list->children_[0], when_expr)))) { LOG_WARN("get when expression failed", K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(expr_list->children_[1], then_expr)))) { LOG_WARN("get then expression failed", K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(expr_list->children_[2], default_expr)))) { LOG_WARN("get default expression failed", K(ret)); } else if (OB_FAIL(case_expr->add_when_param_expr(when_expr))) { LOG_WARN("add when expression failed", K(ret)); } else if (OB_FAIL(case_expr->add_then_param_expr(then_expr))) { LOG_WARN("add then expression failed", K(ret)); } else { case_expr->set_default_param_expr(default_expr); expr = case_expr; } } if (OB_SUCC(ret)) { if (OB_FAIL(ObRawExprUtils::try_add_bool_expr(case_expr, ctx_.expr_factory_))) { LOG_WARN("try_add_bool_expr for case expr failed", K(ret)); } } } return ret; } /* resolve system funciton INTERVAL(param1, param2) or INTERVAL(param1, param2, param3...) * 1.create a fun expr for INTERVAL * 2.check and resolve parameters(node->children_) * 3.add all the param exprs to fun expr * input: node * output: expr */ int ObRawExprResolverImpl::process_fun_interval_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObSysFunRawExpr *fun_expr = NULL; ObRawExpr *para_expr = NULL; if (OB_ISNULL(node)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument 1", K(ret), K(node)); } else if (OB_UNLIKELY(2 > node->num_child_) || OB_ISNULL(node->children_)) { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("invalid node children for interval function 2", K(ret), K(node)); } else if (OB_FAIL( ctx_.expr_factory_.create_raw_expr(T_FUN_SYS_INTERVAL, fun_expr))) { LOG_WARN("create ObOpRawExpr failed 6", K(ret)); } else if (OB_ISNULL(fun_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ObOpRawExpr is null"); } else if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[0], para_expr)))) { LOG_WARN("fail to recursive resolve", K(ret), K(node->children_[0])); } else if (OB_FAIL(fun_expr->add_param_expr(para_expr))) { LOG_WARN("fail to add param expr", K(ret), K(para_expr)); } else { if (OB_UNLIKELY(T_EXPR_LIST != node->children_[1]->type_)) { if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[1], para_expr)))) { LOG_WARN("fail to recursive resolve", K(ret), K(node->children_[1])); } else if (OB_FAIL(fun_expr->add_param_expr(para_expr))) { LOG_WARN("fail to add param expr", K(ret), K(para_expr)); } } else { const ParseNode &expr_list = *(node->children_[1]); for (int32_t i = 0; OB_SUCC(ret) && i < expr_list.num_child_; i++) { if (OB_FAIL(SMART_CALL(recursive_resolve(expr_list.children_[i], para_expr)))) { LOG_WARN("fail to recursive resolve", K(ret), K(expr_list.children_[i])); } else if (OB_FAIL(fun_expr->add_param_expr(para_expr))) { LOG_WARN("fail to add param expr", K(ret), K(para_expr)); } LOG_DEBUG("param info:", K(expr_list.children_[i]), K(expr_list.children_[i]->type_)); } } } if (OB_SUCC(ret)) { expr = fun_expr; } return ret; } int ObRawExprResolverImpl::process_isnull_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; if (OB_ISNULL(node)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node)); } else if (OB_UNLIKELY(2 != node->num_child_) || OB_ISNULL(node->children_) || OB_ISNULL(node->children_[1]) || OB_UNLIKELY(1 > node->children_[1]->num_child_) || OB_ISNULL(node->children_[1]->children_) || OB_ISNULL(node->children_[1]->children_[0])) { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("invalid node children for isnull function", K(ret), K(node)); } else { ObRawExpr *obj_expr = NULL; if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[1]->children_[0], obj_expr)))) { LOG_WARN("resolve child faield", K(ret)); } else if (OB_FAIL(ObRawExprUtils::build_is_not_null_expr(ctx_.expr_factory_, obj_expr, false/*is_not_null*/, expr))) { LOG_WARN("create is null expr failed", K(ret)); } } return ret; } int ObRawExprResolverImpl::process_call_param_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObCallParamRawExpr *call_param_expr = NULL; ObRawExpr* child_expr = NULL; ObString name; CK (OB_NOT_NULL(node)); CK (OB_LIKELY(T_SP_CPARAM == node->type_)); CK (OB_LIKELY(2 == node->num_child_)); CK (OB_NOT_NULL(node->children_[0])); CK (OB_NOT_NULL(node->children_[1])); if (OB_SUCC(ret)) { const ParseNode *name_node = NULL; if (T_OBJ_ACCESS_REF == node->children_[0]->type_) { CK (OB_LIKELY(2 == node->children_[0]->num_child_)); CK (OB_NOT_NULL(node->children_[0]->children_[0])); CK (OB_ISNULL(node->children_[0]->children_[1])); CK (OB_LIKELY(T_IDENT == node->children_[0]->children_[0]->type_)); name_node = node->children_[0]->children_[0]; } else if (T_IDENT == node->children_[0]->type_) { name_node = node->children_[0]; } else if (T_COLUMN_REF == node->children_[0]->type_ && 3 == node->children_[0]->num_child_ && NULL == node->children_[0]->children_[0] && NULL == node->children_[0]->children_[1] && T_IDENT == node->children_[0]->children_[2]->type_) { name_node = node->children_[0]->children_[2]; } else { ret = OB_ERR_CALL_WRONG_ARG; LOG_WARN("PLS-00306: wrong number or types of arguments in call", K(ret)); } OZ (ctx_.expr_factory_.create_raw_expr(T_SP_CPARAM, call_param_expr)); CK (OB_NOT_NULL(call_param_expr)); OX (name = ObString(static_cast(name_node->str_len_), name_node->str_value_)); OX (call_param_expr->set_name(name)); OZ (recursive_resolve(node->children_[1], child_expr)); CK (OB_NOT_NULL(child_expr)); OX (call_param_expr->set_expr(child_expr)); OX (expr = call_param_expr); } return ret; } int ObRawExprResolverImpl::process_sqlerrm_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObPLSQLCodeSQLErrmRawExpr *func_expr = NULL; ObRawExpr *param_expr = NULL; ObString name, func_name; CK (OB_NOT_NULL(node)); OZ (ctx_.expr_factory_.create_raw_expr(T_FUN_PL_SQLCODE_SQLERRM, func_expr)); CK (OB_NOT_NULL(func_expr)); OX (name = ObString(node->children_[0]->str_len_, node->children_[0]->str_value_)); CK (OB_LIKELY(0 == name.case_compare("SQLERRM"))); OZ (ob_write_string(ctx_.expr_factory_.get_allocator(), N_PL_GET_SQLCODE_SQLERRM, func_name)); OX (func_expr->set_func_name(func_name)); OX (func_expr->set_is_sqlcode(false)); if (OB_SUCC(ret) && node->num_child_ > 2) { ret = OB_INVALID_ARGUMENT_NUM; LOG_WARN("invalid argument number for SQLERRM", K(node->num_child_)); } if (OB_SUCC(ret) && 2 == node->num_child_) { if (OB_ISNULL(node->children_[1]) || node->children_[1]->num_child_ != 1) { ret = OB_INVALID_ARGUMENT_NUM; LOG_WARN("invlaid argument number for SQLERRM", K(node->children_[1]->num_child_)); } if (OB_SUCC(ret)) { if (OB_ISNULL(node->children_[1]->children_[0])) { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("invalid parse tree", K(ret)); } else if (T_EXPR_WITH_ALIAS == node->children_[1]->children_[0]->type_) { ret = OB_ERR_FUNCTION_UNKNOWN; LOG_WARN("SQLERRM in argument alias is not supported", K(ret)); } } OZ (SMART_CALL(recursive_resolve(node->children_[1]->children_[0], param_expr))); CK (OB_NOT_NULL(param_expr)); OZ (func_expr->add_param_expr(param_expr)); } OX (expr = func_expr); return ret; } int ObRawExprResolverImpl::process_plsql_var_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObPLSQLVariableRawExpr *plsql_expr = NULL; ObString plsql_variable; CK (OB_NOT_NULL(node)); CK (OB_LIKELY(1 == node->num_child_)); CK (OB_NOT_NULL(node->children_)); CK (OB_NOT_NULL(node->children_[0])); OZ (ctx_.expr_factory_.create_raw_expr(T_FUN_PLSQL_VARIABLE, plsql_expr)); CK (OB_NOT_NULL(plsql_expr)); OX (plsql_expr->set_plsql_line(node->children_[0]->int32_values_[0])); OZ (ob_write_string(ctx_.expr_factory_.get_allocator(), ObString(node->children_[0]->str_len_, node->children_[0]->str_value_), plsql_variable)); OX (plsql_expr->set_plsql_variable(plsql_variable)); OX (expr = plsql_expr); return ret; } int ObRawExprResolverImpl::process_lnnvl_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; CK(T_FUN_SYS_LNNVL == node->type_); CK(1 == node->num_child_); CK(OB_NOT_NULL(node->children_)); CK(OB_NOT_NULL(node->children_[0])); ObItemType param_type = node->children_[0]->type_; switch (param_type) { case T_FUN_SYS_LNNVL: case T_FUN_SYS_REGEXP_LIKE: case T_OP_EXISTS: case T_OP_IS: case T_OP_IS_NOT: case T_OP_LIKE: case T_OP_NOT_LIKE: case T_OP_IN: case T_OP_NOT_IN: case T_OP_LE: case T_OP_LT: case T_OP_EQ: case T_OP_GE: case T_OP_GT: case T_OP_NE: { break; } default: { ret = OB_INCORRECT_USE_OF_OPERATOR; ObString tmp_msg("LNNVL"); LOG_USER_ERROR(OB_INCORRECT_USE_OF_OPERATOR, tmp_msg.length(), tmp_msg.ptr()); break; } } if (OB_SUCC(ret)) { ObSysFunRawExpr *func_expr = NULL; ObRawExpr *param_expr = NULL; OZ(SMART_CALL(recursive_resolve(node->children_[0], param_expr))); CK(OB_NOT_NULL(param_expr)); OZ(ctx_.expr_factory_.create_raw_expr(T_FUN_SYS_LNNVL, func_expr)); CK(OB_NOT_NULL(func_expr)); OZ(func_expr->add_param_expr(param_expr)); OX(func_expr->set_func_name(ObString::make_string(N_LNNVL))); OX(expr = func_expr); } return ret; } int ObRawExprResolverImpl::malloc_new_specified_type_node(common::ObIAllocator &allocator, ObString col_name, ParseNode *col_node, ObItemType type) { INIT_SUCC(ret); memset(col_node, 0, sizeof(ParseNode)); if (type == T_CHAR) { col_node->type_ = T_CHAR; col_node->str_value_ = col_name.ptr(); col_node->raw_text_ = col_name.ptr(); col_node->str_len_ = col_name.length(); col_node->text_len_ = col_name.length(); col_node->num_child_ = 2; ParseNode *key_child_node; if (nullptr == (key_child_node = static_cast(allocator.alloc(sizeof(ParseNode))))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to allocate memory", K(ret), K(sizeof(ParseNode))); } else { key_child_node = new(key_child_node) ParseNode; memset(key_child_node, 0, sizeof(ParseNode)); key_child_node->type_ = T_VARCHAR; key_child_node->str_value_ = col_name.ptr(); key_child_node->raw_text_ = col_name.ptr(); key_child_node->str_len_ = col_name.length(); key_child_node->text_len_ = col_name.length(); int64_t alloc_char_size = sizeof(ParseNode *) * 2; ParseNode **k_t_vec = NULL; if (OB_ISNULL(k_t_vec = static_cast(allocator.alloc(alloc_char_size)))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to allocate memory", K(ret), K(sizeof(ParseNode))); } else { k_t_vec[0] = NULL; k_t_vec[1] = key_child_node; col_node->children_ = k_t_vec; } } } else if (type == T_COLUMN_REF) { col_node->type_ = T_COLUMN_REF; col_node->str_value_ = col_name.ptr(); col_node->raw_text_ = col_name.ptr(); col_node->str_len_ = col_name.length(); col_node->num_child_ = 3; ParseNode *val_node; if (nullptr == (val_node = static_cast(allocator.alloc(sizeof(ParseNode))))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to allocate memory", K(ret), K(sizeof(ParseNode))); } else { val_node = new(val_node) ParseNode; memset(val_node, 0, sizeof(ParseNode)); val_node->type_ = T_VARCHAR; val_node->str_value_ = col_name.ptr(); val_node->raw_text_ = col_name.ptr(); val_node->str_len_ = col_name.length(); val_node->text_len_ = col_name.length(); int64_t alloc_col_size = sizeof(ParseNode *) * 3; ParseNode **t_vec = NULL; if (OB_ISNULL(t_vec = static_cast(allocator.alloc(alloc_col_size)))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to allocate memory", K(ret), K(sizeof(ParseNode))); } else { t_vec[0] = NULL; t_vec[1] = NULL; t_vec[2] = val_node; col_node->children_ = t_vec; } } } else if (type == T_INT) { col_node->type_ = T_INT; col_node->flag_ = 2; col_node->is_hidden_const_ = 1; col_node->int16_values_[0] = 0; col_node->int16_values_[1] = 0; col_node->int16_values_[2] = 0; col_node->int16_values_[3] = 0; col_node->int32_values_[0] = 0; col_node->int32_values_[1] = 0; } else if (type == T_NULL) { col_node->type_ = T_NULL; col_node->num_child_ = 0; } else if (type == T_OBJ_ACCESS_REF) { col_node->type_ = T_OBJ_ACCESS_REF; col_node->num_child_ = 2; col_node->is_hidden_const_ = 1; int64_t alloc_access_size = sizeof(ParseNode *) * 2; ParseNode **t_vec = NULL; if (OB_ISNULL(t_vec = static_cast(allocator.alloc(alloc_access_size)))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to allocate memory", K(ret), K(sizeof(ParseNode))); } else { t_vec[0] = NULL; t_vec[1] = NULL; col_node->children_ = t_vec; } } else { ret = OB_ERR_UNEXPECTED; LOG_WARN("node type not exits"); } return ret; } // use: json value (mismatch ype) ; json object (entry_op) int ObRawExprResolverImpl::expand_node(common::ObIAllocator &allocator, ParseNode *node, int p, ObVector &arr) { int ret = OB_SUCCESS; if (node->type_ == T_LINK_NODE || node->type_ == T_VALUE_VECTOR) { for (int32_t i = 0; OB_SUCC(ret) && i < node->num_child_; i++){ if (OB_ISNULL(node->children_[i])) { } else { ObString rownum_str(6, "rownum"); if (lib::is_oracle_mode() && ctx_.current_scope_ == T_FIELD_LIST_SCOPE && node->children_[i]->type_ == T_FUN_SYS && node->children_[i]->num_child_ == 1 && OB_NOT_NULL(node->children_[i]->children_[0]) && node->children_[i]->children_[0]->type_ == T_IDENT && 0 == rownum_str.case_compare(node->children_[i]->children_[0]->str_value_) && i % 3 == 0 && node->children_[i + 1]->type_ == T_NULL && node->children_[i + 1]->value_ == 2) { ParseNode *fun_key_node; if (OB_ISNULL(fun_key_node = static_cast(allocator.alloc(sizeof(ParseNode))))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to allocate memory", K(ret), K(sizeof(ParseNode))); } else { fun_key_node = new(fun_key_node) ParseNode; if (OB_ISNULL(node->children_[i]->children_[0])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("no legeal fun", K(ret)); } else { ObString str_fun(node->children_[i]->children_[0]->str_len_, node->children_[i]->children_[0]->str_value_); if (OB_FAIL(ObRawExprResolverImpl::malloc_new_specified_type_node(allocator, str_fun, fun_key_node, T_CHAR))) { LOG_WARN("key node create fail", K(ret)); } else { node->children_[i + 1] = node->children_[i]; node->children_[i] = fun_key_node; } } } } else if (node->children_[i]->type_ == T_OBJ_ACCESS_REF && i % 3 == 0 && node->children_[i+1]->type_ == T_NULL && node->children_[i+1]->value_ == 2) { ParseNode *column_ref_node; ParseNode *t_node = node->children_[i]; ParseNode *pre_node = NULL; bool is_fun_sys = false; if (OB_ISNULL(column_ref_node = static_cast(allocator.alloc(sizeof(ParseNode))))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to allocate memory", K(ret), K(sizeof(ParseNode))); } else { column_ref_node = new(column_ref_node) ParseNode; if (OB_FAIL(ObRawExprResolverImpl::malloc_new_specified_type_node(allocator, "", column_ref_node, T_OBJ_ACCESS_REF))) { LOG_WARN("key node create fail", K(ret)); } else { node->children_[i]->value_ = 1; pre_node = column_ref_node; } } while (OB_SUCC(ret) && !is_fun_sys && t_node != NULL && t_node->type_ == T_OBJ_ACCESS_REF) { if (OB_ISNULL(t_node->children_[0]) || t_node->children_[0]->type_ != T_IDENT) { is_fun_sys = true; } else { ParseNode *col_ref_node = NULL; ParseNode *ident_node = NULL; if (OB_ISNULL(ident_node = static_cast(allocator.alloc(sizeof(ParseNode))))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to allocate memory", K(ret), K(sizeof(ParseNode))); } else { ident_node = new(ident_node) ParseNode; memset(ident_node, 0, sizeof(ParseNode)); ident_node->type_ = T_IDENT; ident_node->str_value_ = t_node->children_[0]->str_value_; ident_node->str_len_ = t_node->children_[0]->str_len_; ident_node->raw_text_ = t_node->children_[0]->raw_text_; ident_node->text_len_ = t_node->children_[0]->text_len_; pre_node->children_[0] = ident_node; } if (OB_FAIL(ret) || OB_ISNULL(t_node->children_[1])) { } else if (OB_ISNULL(col_ref_node = static_cast(allocator.alloc(sizeof(ParseNode))))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to allocate memory", K(ret), K(sizeof(ParseNode))); } else { col_ref_node = new(col_ref_node) ParseNode; if (OB_FAIL(ObRawExprResolverImpl::malloc_new_specified_type_node(allocator, "", col_ref_node, T_OBJ_ACCESS_REF))) { LOG_WARN("key node create fail", K(ret)); } else { pre_node->children_[1] = col_ref_node; } } if (OB_SUCC(ret)) { pre_node = col_ref_node; } t_node = t_node->children_[1]; } } if (OB_SUCC(ret) && !is_fun_sys && OB_ISNULL(node->children_[i+1] = column_ref_node)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("column_node copy failed", K(ret)); } } if (OB_SUCC(ret) && OB_FAIL(SMART_CALL(expand_node(allocator, node->children_[i], i, arr)))) { LOG_WARN("node expand fail", K(ret)); } } } } else if (node->type_ == T_STAR) { // do nothing } else if ((node->type_ == T_COLUMN_REF || node->type_ == T_OBJ_ACCESS_REF) && node->value_ == 1 && p % 3 == 0) { ObQualifiedName column_ref; ParseNode *col_node; if (nullptr == (col_node = static_cast(allocator.alloc(sizeof(ParseNode))))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to allocate memory", K(ret), K(sizeof(ParseNode))); } else if (node->type_ == T_COLUMN_REF) { if (OB_FAIL(ObResolverUtils::resolve_column_ref( node, ctx_.case_mode_, column_ref))) { LOG_WARN("fail to resolve column ref", K(ret)); } if (OB_NOT_NULL(node->children_[2]->raw_text_)) { column_ref.col_name_ = node->children_[2]->raw_text_; } } else if (node->type_ == T_OBJ_ACCESS_REF) { while (node->children_[1] != NULL) { node = node->children_[1]; } if (OB_NOT_NULL(node->children_[0]) && node->children_[0]->type_ == T_IDENT) { if (OB_FAIL(ObResolverUtils::resolve_obj_access_ref_node( ctx_.expr_factory_, node->children_[0], column_ref, *ctx_.session_info_))) { LOG_WARN("fail to resolve column ref", K(ret)); } if (OB_NOT_NULL(node->children_[0]->raw_text_)) { column_ref.col_name_ = node->children_[0]->raw_text_; } } else { column_ref.is_star_ = true; const ParseNode* new_node = node; if (OB_FAIL(arr.push_back(node))) { LOG_WARN("node resolver fail", K(ret)); } } } if (OB_SUCC(ret) && !column_ref.is_star_) { col_node = new(col_node) ParseNode; ObString col_name = column_ref.col_name_; if (OB_FAIL(ObRawExprResolverImpl::malloc_new_specified_type_node(allocator, col_name, col_node, T_CHAR))) { LOG_WARN("fail to create column node "); } const ParseNode* new_node = col_node; if (OB_FAIL(arr.push_back(new_node))) { LOG_WARN("node resolver fail", K(ret)); } } } else if (node->type_ == T_COLUMN_REF && node->children_[2]->type_ == T_STAR) { // do nothing } else if (node->type_ == T_NULL && node->value_ == 2) { // do nothing } else { const ParseNode* new_node = node; if (OB_FAIL(arr.push_back(node))) { LOG_WARN("node resolver fail", K(ret)); } } return ret; } int ObRawExprResolverImpl::remove_format_json_opt_in_pl(ParseNode *node, int8_t expr_flag) { INIT_SUCC(ret); int64_t num = node->num_child_; if (expr_flag == OPT_JSON_OBJECT) { for (int64_t i = 2; i < num; i += 3) { if (OB_ISNULL(node->children_[i]) || OB_ISNULL(node->children_[i - 1])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("should not null", K(ret), K(i)); } else if (node->children_[i]->type_ != T_INT) { ret = OB_ERR_UNEXPECTED; LOG_WARN("type is't int", K(ret), K(node->children_[i]->type_)); } else if (node->children_[i - 1]->type_ != T_CHAR) { node->children_[i]->value_ = 0; } } } else if (expr_flag == OPT_JSON_ARRAY) { for (int64_t i = 1; i < num; i += 2) { if (OB_ISNULL(node->children_[i]) || OB_ISNULL(node->children_[i - 1])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("should not null", K(ret), K(i)); } else if (node->children_[i]->type_ != T_INT) { ret = OB_ERR_UNEXPECTED; LOG_WARN("type is't int", K(ret), K(node->children_[i]->type_)); } else if (node->children_[i - 1]->type_ != T_CHAR) { node->children_[i]->value_ = 0; } } } return ret; } int ObRawExprResolverImpl::remove_strict_opt_in_pl(ParseNode *node, int8_t expr_flag) { INIT_SUCC(ret); if (expr_flag == OPT_JSON_OBJECT || expr_flag == OPT_JSON_ARRAY) { if (OB_ISNULL(node)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("should not null"); } else if (node->type_ != T_INT) { ret = OB_ERR_UNEXPECTED; LOG_WARN("type is't int"); } else { node->value_ = 0; } } return ret; } int ObRawExprResolverImpl::process_ora_json_object_node(const ParseNode *node, ObRawExpr *&expr) { INIT_SUCC(ret); CK(OB_NOT_NULL(node)); int32_t num = 0; if (OB_SUCC(ret)) { if (T_FUN_SYS_JSON_OBJECT != node->type_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("node->type_ error"); } else if (node->num_child_ != 5) { ret = OB_ERR_UNEXPECTED; LOG_WARN("num_child_ error"); } num = node->num_child_; } ObSysFunRawExpr *func_expr = NULL; if (OB_SUCC(ret) && OB_SUCC(ctx_.expr_factory_.create_raw_expr(T_FUN_SYS, func_expr))) { CK(OB_NOT_NULL(func_expr)); OX(func_expr->set_func_name(ObString::make_string("json_object"))); } else { LOG_WARN("fail to create func_expr"); } // check pl clause : with unique keys/ returning type if (OB_SUCC(ret) && lib::is_oracle_mode() && ctx_.current_scope_ == T_PL_SCOPE) { if (OB_NOT_NULL(node->children_[0]->children_[0]) && node->children_[0]->children_[0]->type_ == T_COLUMN_REF && OB_NOT_NULL(node->children_[0]->children_[0]->children_[2]) && node->children_[0]->children_[0]->children_[2]->type_ == T_STAR) { ret = OB_ERR_PARSE_PLSQL; LOG_USER_ERROR(OB_ERR_PARSE_PLSQL, "\"*\"", "( ) - + case"); } else if (node->children_[4]->value_ == 1) { ret = OB_ERR_INVALID_ARGUMENT_FOR_JSON_CALL; LOG_USER_ERROR(OB_ERR_INVALID_ARGUMENT_FOR_JSON_CALL, "JSON"); LOG_WARN("invalid argument for json call"); } else if (node->children_[num - 3]->type_ == T_LONGTEXT) { ret = OB_ERR_EXPRESSION_WRONG_TYPE; LOG_WARN("PLS-00382: expression is of wrong type", K(ret)); } else if (OB_FAIL(remove_strict_opt_in_pl(const_cast(node->children_[3]), OPT_JSON_OBJECT))) { LOG_WARN("set format json fail", K(ret)); } else if (OB_FAIL(remove_format_json_opt_in_pl(const_cast(node->children_[0]), OPT_JSON_OBJECT))) { LOG_WARN("set format json fail", K(ret)); } } ObVector key_value_arr; if (OB_SUCC(ret)) { const ParseNode *key_value = node->children_[0]; if (OB_ISNULL(key_value)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("entry node is null"); } else { int d_len = strlen("default"); if (node->children_[3]->value_ == 1 && node->children_[1]->value_ == 0 && OB_NOT_NULL(node->children_[2]->raw_text_) && 0 == strncmp(node->children_[2]->raw_text_,"default", d_len)) { int last_arg_idx = key_value->num_child_ - 3; if (last_arg_idx >= 0 && key_value->children_[last_arg_idx]->type_ == T_OBJ_ACCESS_REF && key_value->children_[last_arg_idx + 1]->type_ == T_NULL && (OB_NOT_NULL(key_value->children_[last_arg_idx + 2]->raw_text_) && 0 == strncmp(key_value->children_[last_arg_idx + 2]->raw_text_, "default", d_len)) && key_value->children_[last_arg_idx + 1]->value_ == 2) { ret = OB_ERR_MISS_VALUE; LOG_WARN("illegal use of 'strcit' clause."); } } ParseNode *cur_node = NULL; if (OB_FAIL(ret) || OB_ISNULL(key_value)) { } else if (OB_NOT_NULL(node->children_[0]) && (node->children_[0]->num_child_ == 0 || (node->children_[0]->num_child_ > 0 && OB_ISNULL(cur_node = node->children_[0]->children_[0])))) { } else if (cur_node->type_ == T_COLUMN_REF && OB_NOT_NULL(cur_node->children_[2]) && cur_node->children_[2]->type_ == T_STAR) { } else if (OB_FAIL(expand_node(ctx_.local_allocator_, const_cast(key_value), 0, key_value_arr))) { LOG_WARN("expand node has error", K(ret), K(key_value_arr.size())); } else if (key_value_arr.size() != key_value->num_child_) { ret = OB_ERR_MISS_VALUE; LOG_WARN("missing value keyword", K(ret), K(key_value_arr.size()), K(key_value->num_child_)); } if (OB_SUCC(ret)) { // [key-value(vector)][null_type][returning_type][strict][unique_keys] for (int32_t i = 0; OB_SUCC(ret) && i < key_value_arr.size(); i++) { if (key_value_arr[i]->type_ == T_LINK_NODE || key_value_arr[i]->type_ == T_VALUE_VECTOR) { } else { ObRawExpr *para_expr = NULL; CK(OB_NOT_NULL(key_value_arr[i])); OZ(SMART_CALL(recursive_resolve(key_value_arr[i], para_expr))); CK(OB_NOT_NULL(para_expr)); OZ(func_expr->add_param_expr(para_expr)); } } //end for // ([on_mismatch][opt_mismatch_types] on oracle) for (int32_t i = 1; OB_SUCC(ret) && i < num; i++) { ObRawExpr *para_expr = NULL; CK(OB_NOT_NULL(node->children_[i])); OZ(SMART_CALL(recursive_resolve(node->children_[i], para_expr))); CK(OB_NOT_NULL(para_expr)); OZ(func_expr->add_param_expr(para_expr)); } //end mismatch for OX(expr = func_expr); } } } return ret; } int ObRawExprResolverImpl::check_first_node(const ParseNode *node) { INIT_SUCC(ret); if (OB_ISNULL(node)) { // do nothing node->num_child_ > 0 && node->type_ != T_COLUMN_REF) } else if (node->type_ == T_LINK_NODE || node->type_ == T_VALUE_VECTOR || node->type_ == T_QUESTIONMARK || node->type_ == T_COLUMN_REF) { for (int32_t i = 0; OB_SUCC(ret) && i < node->num_child_; i++){ if (OB_SUCC(ret)) { if (OB_FAIL(SMART_CALL(check_first_node(node->children_[i])))) { LOG_WARN("first node check is star failed", K(ret)); } } } } else if (node->type_ == T_STAR) { ret = OB_ERR_INVALID_COLUMN_SPE; LOG_WARN("invalid user.table.column, table.column, or column specification", K(ret)); } return ret; } int ObRawExprResolverImpl::process_json_query_node(const ParseNode *node, ObRawExpr *&expr){ INIT_SUCC(ret); CK(OB_NOT_NULL(node)); if(OB_SUCC(ret) && T_FUN_SYS_JSON_QUERY != node->type_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("node->type_ error"); } else if (OB_SUCC(ret) && 10 != node->num_child_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("num_child_ error"); } int32_t num = 0; ObSysFunRawExpr *func_expr = NULL; if (OB_SUCC(ret)) { num = node->num_child_; ctx_.expr_factory_.create_raw_expr(T_FUN_SYS, func_expr); CK(OB_NOT_NULL(func_expr)); OX(func_expr->set_func_name(ObString::make_string("json_query"))); } const ParseNode *path_node = node->children_[1]; // check path if (OB_SUCC(ret) && OB_FAIL(pre_check_json_path_valid(path_node))) { LOG_WARN("pre check path fail", K(ret)); } // check [returning_type] const ParseNode *returning_type = node->children_[2]; if (OB_SUCC(ret)) { const char *input = node->children_[0]->str_value_; ret = cast_accuracy_check(returning_type, input); } // pre check default returning type with item method if (OB_SUCC(ret)) { if (returning_type->type_ == T_NULL) { ObString path_str(node->children_[1]->text_len_, node->children_[1]->raw_text_); if (OB_FAIL(ObJsonPath::change_json_expr_res_type_if_need(ctx_.local_allocator_, path_str, const_cast(*returning_type), OPT_JSON_QUERY))) { LOG_WARN("set return type by path item method fail", K(ret), K(path_str)); } } } if (OB_SUCC(ret) && returning_type->int16_values_[OB_NODE_CAST_TYPE_IDX] != T_VARCHAR && returning_type->int16_values_[OB_NODE_CAST_TYPE_IDX] != T_LONGTEXT && returning_type->int16_values_[OB_NODE_CAST_TYPE_IDX] != T_JSON && returning_type->type_ != T_NULL) { ret = OB_ERR_INVALID_DATA_TYPE_RETURNING; LOG_USER_ERROR(OB_ERR_INVALID_DATA_TYPE_RETURNING); } if (OB_SUCC(ret) && OB_FAIL(check_first_node(node->children_[0]))) { LOG_WARN("invalid user.table.column, table.column, or column specification", K(ret)); } // [json_text][json_path][returning_type][scalars][pretty][ascii][wrapper][error_type][empty_type][mismatch] for (int32_t i = 0; OB_SUCC(ret) && i < num; i++) { ObRawExpr *para_expr = NULL; CK(OB_NOT_NULL(node->children_[i])); OZ(SMART_CALL(recursive_resolve(node->children_[i], para_expr))); CK(OB_NOT_NULL(para_expr)); OZ(func_expr->add_param_expr(para_expr)); } OX(expr = func_expr); return ret; } int ObRawExprResolverImpl::process_json_exists_node(const ParseNode *node, ObRawExpr *&expr) { INIT_SUCC(ret); CK(T_FUN_SYS_JSON_EXISTS == node->type_); CK(5 == node->num_child_); int32_t num = node->num_child_; ObSysFunRawExpr *func_expr = NULL; OZ(ctx_.expr_factory_.create_raw_expr(T_FUN_SYS, func_expr)); CK(OB_NOT_NULL(func_expr)); OX(func_expr->set_func_name(ObString::make_string("json_exists"))); // [json_text][json_path][passing_clause][error_type][empty_type] for (int32_t i = 0; OB_SUCC(ret) && i < num; i++) { // expand [passing_clause] if (i == 2 && node->children_[i]->type_ == T_EXPR_LIST) { int64_t pass_num = node->children_[i]->num_child_; if (pass_num % 2 != 0) { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("num_child_ error"); } else { for (int32_t name_idx = 0; name_idx < pass_num && OB_SUCC(ret); ++name_idx) { if (name_idx % 2 == 1) { if (node->children_[i]->children_[name_idx]->type_ == T_IDENT) { node->children_[i]->children_[name_idx]->type_ = T_CHAR; } else { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("child_type_of_PASSING error"); } } ObRawExpr *para_expr = NULL; CK(OB_NOT_NULL(node->children_[i]->children_[name_idx])); OZ(SMART_CALL(recursive_resolve(node->children_[i]->children_[name_idx], para_expr))); if (OB_NOT_NULL(para_expr) && name_idx % 2 == 0 && para_expr->get_expr_type() == T_REF_QUERY) { ret = OB_ERR_INVALID_VARIABLE_IN_JSON_PATH; LOG_USER_ERROR(OB_ERR_INVALID_VARIABLE_IN_JSON_PATH); } else { OZ(func_expr->add_param_expr(para_expr)); } } } } else { ObRawExpr *para_expr = NULL; CK(OB_NOT_NULL(node->children_[i])); OZ(SMART_CALL(recursive_resolve(node->children_[i], para_expr))); CK(OB_NOT_NULL(para_expr)); OZ(func_expr->add_param_expr(para_expr)); } } OX(expr = func_expr); return ret; } int ObRawExprResolverImpl::pre_check_json_path_valid(const ParseNode *node) { INIT_SUCC(ret); ObString j_path_text(node->str_len_, node->str_value_); ObJsonPath j_path(j_path_text, &ctx_.local_allocator_); if (j_path_text.length() == 0) { } else if (OB_FAIL(j_path.parse_path())) { ret = OB_ERR_JSON_PATH_EXPRESSION_SYNTAX_ERROR; LOG_USER_ERROR(OB_ERR_JSON_PATH_EXPRESSION_SYNTAX_ERROR, j_path_text.length(), j_path_text.ptr()); } return ret; } int ObRawExprResolverImpl::process_json_value_node(const ParseNode *node, ObRawExpr *&expr) { INIT_SUCC(ret); CK(OB_NOT_NULL(node)) CK(T_FUN_SYS_JSON_VALUE == node->type_); // node child_num is nine, CK(9 == node->num_child_); bool mismatch_vec = false; int32_t num = 0; ObSysFunRawExpr *func_expr = NULL; if (OB_SUCC(ret)) { num = node->num_child_; OZ(ctx_.expr_factory_.create_raw_expr(T_FUN_SYS, func_expr)); CK(OB_NOT_NULL(func_expr)); OX(func_expr->set_func_name(ObString::make_string("json_value"))); } // pl mode check whether has mismatch if (lib::is_oracle_mode() && ctx_.current_scope_ == T_PL_SCOPE) { if (node->children_[8]->num_child_ != 2 || node->children_[8]->children_[0]->value_ != 3 || node->children_[8]->children_[1]->value_ != 7) { ret = OB_ERR_PARSE_PLSQL; LOG_USER_ERROR(OB_ERR_PARSE_PLSQL, "\"MISMATCH\"", "error empty"); } } const ParseNode *path_node = node->children_[1]; // check path if (OB_SUCC(ret) && lib::is_oracle_mode() && OB_FAIL(pre_check_json_path_valid(path_node))) { LOG_WARN("pre check path fail", K(ret)); } const ParseNode *returning_type = node->children_[2]; // check [returning_type] if (OB_SUCC(ret)) { const char *input = node->children_[0]->str_value_; ret = cast_accuracy_check(returning_type, input); } // pre check default returning type with item method if (OB_SUCC(ret)) { ObString default_val(7, "default"); if (OB_NOT_NULL(returning_type->raw_text_) && (0 == default_val.case_compare(returning_type->raw_text_)) && node->children_[1]->text_len_ > 0) { ObString path_str(node->children_[1]->text_len_, node->children_[1]->raw_text_); if (OB_FAIL(ObJsonPath::change_json_expr_res_type_if_need(ctx_.local_allocator_, path_str, const_cast(*returning_type), OPT_JSON_VALUE))) { LOG_WARN("set return type by path item method fail", K(ret), K(path_str)); } } } // if use defualt, value should not be null if (OB_SUCC(ret)) { const ParseNode *empty_type = node->children_[4]; if (OB_NOT_NULL(empty_type) && empty_type->value_ == 2) { const ParseNode *empty_default_value = node->children_[5]; if (OB_NOT_NULL(empty_default_value) && empty_default_value->type_ == T_NULL) { if (lib::is_oracle_mode()) { ret = OB_ERR_DEFAULT_VALUE_NOT_LITERAL; } else { ret = OB_ERR_PARSER_SYNTAX; } } } const ParseNode *error_type = node->children_[6]; if (OB_SUCC(ret) && OB_NOT_NULL(error_type) && error_type->value_ == 2) { const ParseNode *error_default_value = node->children_[7]; if (OB_NOT_NULL(error_default_value) && error_default_value->type_ == T_NULL) { if (lib::is_oracle_mode()) { ret = OB_ERR_DEFAULT_VALUE_NOT_LITERAL; } else { ret = OB_ERR_PARSER_SYNTAX; } } } } if (OB_SUCC(ret) && OB_FAIL(check_first_node(node->children_[0]))) { LOG_WARN("invalid db.table.column, table.column, or column specification", K(ret)); } // judge input TODO object type can use ignore and match type ObVector mismatch_arr; if (OB_SUCC(ret)) { const ParseNode *on_mismatch = node->children_[8]; if (OB_ISNULL(on_mismatch)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("mismatch node is null", K(ret)); } else { if (OB_FAIL(expand_node(ctx_.local_allocator_, const_cast(on_mismatch), 0, mismatch_arr))) { LOG_WARN("parse mismatch has error", K(ret), K(mismatch_arr.size())); } else { // [json_text][json_path][returning_type][empty_type][empty_default_value][error_type][error_default_value] for (int32_t i = 0; OB_SUCC(ret) && i < num; i++) { if (node->children_[i]->type_ == T_LINK_NODE || node->children_[i]->type_ == T_VALUE_VECTOR) { } else { ObRawExpr *para_expr = NULL; CK(OB_NOT_NULL(node->children_[i])); OZ(SMART_CALL(recursive_resolve(node->children_[i], para_expr))); CK(OB_NOT_NULL(para_expr)); OZ(func_expr->add_param_expr(para_expr)); } if (OB_SUCC(ret) && (i == 5 || i == 7)) { ObRawExpr *para_expr = NULL; CK(OB_NOT_NULL(node->children_[i])); OZ(SMART_CALL(recursive_resolve(node->children_[i], para_expr))); CK(OB_NOT_NULL(para_expr)); OZ(func_expr->add_param_expr(para_expr)); } } //end for // ([on_mismatch][opt_mismatch_types] on oracle) int8_t mis_check = 0; for (int32_t i = 0; OB_SUCC(ret) && i < mismatch_arr.size(); i++) { ObRawExpr *para_expr = NULL; if (mismatch_arr[i]->value_ >= 0 && mismatch_arr[i]->value_ <= 2) { mis_check = 0; } else if (mismatch_arr[i]->value_ >= 3 && mismatch_arr[i]->value_ <= 5) { switch(mismatch_arr[i]->value_) { case OB_JSON_TYPE_MISSING_DATA :{ if ((mis_check & 1) == 1) { ret = OB_ERR_INVALID_CLAUSE; LOG_USER_ERROR(OB_ERR_INVALID_CLAUSE, "ON ERROR"); } break; } case OB_JSON_TYPE_EXTRA_DATA :{ if ((mis_check & 2) == 2) { ret = OB_ERR_INVALID_CLAUSE; LOG_USER_ERROR(OB_ERR_INVALID_CLAUSE, "ON ERROR"); } break; } case OB_JSON_TYPE_TYPE_ERROR :{ if ((mis_check & 4) == 4) { ret = OB_ERR_INVALID_CLAUSE; LOG_USER_ERROR(OB_ERR_INVALID_CLAUSE, "ON ERROR"); } break; } default :{ break; } } } if (OB_FAIL(ret)) { } else if (i % 2 == 0 && node->value_ == 2) { // TODO json value udt type ret = OB_NOT_SUPPORTED; LOG_WARN("Not support collection and UDT", K(ret)); } else if (i % 2 == 1 && node->value_ <= 2) { ret = OB_NOT_SUPPORTED; LOG_WARN("Not support collection and UDT", K(ret)); } else { CK(OB_NOT_NULL(mismatch_arr[i])); OZ(SMART_CALL(recursive_resolve(mismatch_arr[i], para_expr))); CK(OB_NOT_NULL(para_expr)); OZ(func_expr->add_param_expr(para_expr)); } } //end mismatch for OX(expr = func_expr); } } } return ret; } int ObRawExprResolverImpl::process_json_equal_node(const ParseNode *node, ObRawExpr *&expr) { INIT_SUCC(ret); CK(T_FUN_SYS_JSON_EQUAL == node->type_); CK(3 == node->num_child_); int32_t num = node->num_child_; ObSysFunRawExpr *func_expr = NULL; OZ(ctx_.expr_factory_.create_raw_expr(T_FUN_SYS, func_expr)); CK(OB_NOT_NULL(func_expr)); OX(func_expr->set_func_name(ObString::make_string("json_equal"))); for (int32_t i = 0; OB_SUCC(ret) && i < num; i++) { ObRawExpr *para_expr = NULL; CK(OB_NOT_NULL(node->children_[i])); OZ(SMART_CALL(recursive_resolve(node->children_[i], para_expr))); CK(OB_NOT_NULL(para_expr)); OZ(func_expr->add_param_expr(para_expr)); } OX(expr = func_expr); return ret; } int ObRawExprResolverImpl::process_json_array_node(const ParseNode *node, ObRawExpr *&expr) { INIT_SUCC(ret); CK(T_FUN_SYS_JSON_ARRAY == node->type_); CK(4 == node->num_child_); int32_t num = node->num_child_; ObSysFunRawExpr *func_expr = NULL; OZ(ctx_.expr_factory_.create_raw_expr(T_FUN_SYS, func_expr)); CK(OB_NOT_NULL(func_expr)); OX(func_expr->set_func_name(ObString::make_string("json_array"))); const ParseNode *expr_node = node->children_[0]; CK (OB_NOT_NULL(expr_node)); if (OB_SUCC(ret) && lib::is_oracle_mode() && ctx_.current_scope_ == T_PL_SCOPE) { if (OB_FAIL(remove_strict_opt_in_pl(const_cast(node->children_[3]), OPT_JSON_ARRAY))) { LOG_WARN("set strict fail", K(ret)); } else if (OB_FAIL(remove_format_json_opt_in_pl(const_cast(expr_node), OPT_JSON_ARRAY))) { LOG_WARN("set format json fail", K(ret)); } } for (int i = 0; OB_SUCC(ret) && i < expr_node->num_child_; ++i) { ObRawExpr *para_expr = NULL; CK(OB_NOT_NULL(expr_node->children_[i])); OZ(recursive_resolve(expr_node->children_[i], para_expr)); CK(OB_NOT_NULL(para_expr)); OZ(func_expr->add_param_expr(para_expr)); } for (int32_t i = 1; OB_SUCC(ret) && i < num; i++) { ObRawExpr *para_expr = NULL; CK(OB_NOT_NULL(node->children_[i])); OZ(recursive_resolve(node->children_[i], para_expr)); CK(OB_NOT_NULL(para_expr)); OZ(func_expr->add_param_expr(para_expr)); } OX(expr = func_expr); return ret; } int ObRawExprResolverImpl::process_json_mergepatch_node(const ParseNode *node, ObRawExpr *&expr) { INIT_SUCC(ret); CK(T_FUN_SYS_JSON_MERGE_PATCH == node->type_); CK(7 == node->num_child_); int32_t num = node->num_child_; ObSysFunRawExpr *func_expr = NULL; OZ(ctx_.expr_factory_.create_raw_expr(T_FUN_SYS, func_expr)); CK(OB_NOT_NULL(func_expr)); OX(func_expr->set_func_name(ObString::make_string("json_merge_patch"))); for (int32_t i = 0; OB_SUCC(ret) && i < num; i++) { ObRawExpr *para_expr = NULL; CK(OB_NOT_NULL(node->children_[i])); OZ(SMART_CALL(recursive_resolve(node->children_[i], para_expr))); CK(OB_NOT_NULL(para_expr)); OZ(func_expr->add_param_expr(para_expr)); } OX(expr = func_expr); if (OB_SUCC(ret)) { ParseNode *trunc_node = node->children_[5]; ParseNode *type_node = node->children_[2]; if (trunc_node->value_ && (T_LONGTEXT == type_node->int16_values_[0] || T_JSON == type_node->int16_values_[0])) { ret = OB_ERR_UNSUPPORT_TRUNCATE_TYPE; LOG_USER_ERROR(OB_ERR_UNSUPPORT_TRUNCATE_TYPE); } } return ret; } int ObRawExprResolverImpl::process_is_json_node(const ParseNode *node, ObRawExpr *&expr) { INIT_SUCC(ret); CK(T_FUN_SYS_IS_JSON == node->type_); CK(5 == node->num_child_); int32_t num = node->num_child_; ObSysFunRawExpr *func_expr = NULL; OZ(ctx_.expr_factory_.create_raw_expr(T_FUN_SYS, func_expr)); CK(OB_NOT_NULL(func_expr)); OX(func_expr->set_func_name(ObString::make_string("is_json"))); for (int32_t i = 0; OB_SUCC(ret) && i < num; i++) { ObRawExpr *para_expr = NULL; CK(OB_NOT_NULL(node->children_[i])); OZ(SMART_CALL(recursive_resolve(node->children_[i], para_expr))); CK(OB_NOT_NULL(para_expr)); if (OB_SUCC(ret)) { para_expr->clear_flag(IS_CONST_EXPR); OZ(func_expr->add_param_expr(para_expr)); } } //end for OX(expr = func_expr); return ret; } int ObRawExprResolverImpl::cast_accuracy_check(const ParseNode *node, const char *input) { INIT_SUCC(ret); if (T_NUMBER_FLOAT == node->int16_values_[0]) { int64_t precision = node->int16_values_[2]; if (OB_UNLIKELY(precision < OB_MIN_NUMBER_FLOAT_PRECISION) || OB_UNLIKELY(precision > OB_MAX_NUMBER_FLOAT_PRECISION)) { ret = OB_FLOAT_PRECISION_OUT_RANGE; LOG_WARN("precision of float out of range", K(ret), K(precision)); } } else if (T_FLOAT == node->int16_values_[0] || T_DOUBLE == node->int16_values_[0] || T_NUMBER == node->int16_values_[0]) { const int16_t precision = node->int16_values_[2]; const int16_t scale = node->int16_values_[3]; if (lib::is_oracle_mode()) { if (precision != PRECISION_UNKNOWN_YET && (OB_UNLIKELY(precision < OB_MIN_NUMBER_PRECISION) || OB_UNLIKELY(precision > OB_MAX_NUMBER_PRECISION))) { ret = OB_NUMERIC_PRECISION_OUT_RANGE; LOG_WARN("precision of number overflow", K(ret), K(scale), K(precision)); } else if (scale != ORA_NUMBER_SCALE_UNKNOWN_YET && (OB_UNLIKELY(scale < OB_MIN_NUMBER_SCALE) || OB_UNLIKELY(scale > OB_MAX_NUMBER_SCALE))) { ret = OB_NUMERIC_SCALE_OUT_RANGE; LOG_WARN("scale of number out of range", K(ret), K(scale)); } } else { if (OB_UNLIKELY(precision < scale)) { ret = OB_ERR_M_BIGGER_THAN_D; LOG_USER_ERROR(OB_ERR_M_BIGGER_THAN_D, input); } else if (OB_UNLIKELY(precision > OB_MAX_DECIMAL_PRECISION)) { ret = OB_ERR_TOO_BIG_PRECISION; LOG_USER_ERROR(OB_ERR_TOO_BIG_PRECISION, precision, input, OB_MAX_DECIMAL_PRECISION); } else if (OB_UNLIKELY(scale > OB_MAX_DOUBLE_FLOAT_SCALE)) { ret = OB_ERR_TOO_BIG_SCALE; LOG_USER_ERROR(OB_ERR_TOO_BIG_SCALE, scale, input, OB_MAX_DECIMAL_SCALE); } } } return ret; } int ObRawExprResolverImpl::process_fun_sys_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObSysFunRawExpr *func_expr = NULL; ObString func_name; if (OB_ISNULL(node) || OB_ISNULL(ctx_.session_info_)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node), KP(ctx_.session_info_)); } else if (OB_UNLIKELY(1 > node->num_child_) || OB_ISNULL(node->children_) || OB_ISNULL(node->children_[0])) { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("invalid node children for fun_sys node", K(ret), "node", SJ(ObParserResultPrintWrapper(*node))); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_FUN_SYS, func_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(func_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("func_expr is null"); } else { ObString name(node->children_[0]->str_len_, node->children_[0]->str_value_); if (OB_FAIL(check_internal_function(name))) { LOG_WARN("unexpected internal function", K(ret)); } if (OB_SUCC(ret)) { //oracle和mysql的decode函数含义完全不同 if (lib::is_oracle_mode()) { if (0 == name.case_compare("ora_decode")) { ret = OB_ERR_FUNCTION_UNKNOWN; LOG_WARN("ora_decode cannot be reach in oracle mode", K(ret)); } else if (0 == name.case_compare("decode")) { name = ObString::make_string("ora_decode"); } } } if (OB_SUCC(ret)) { if (0 == name.case_compare("nextval")) { ret = OB_ERR_FUNCTION_UNKNOWN; } } if (OB_FAIL(ret)) { /*^-^*/ } else if (OB_FAIL(ob_write_string(ctx_.expr_factory_.get_allocator(), name, func_name))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("Malloc function name failed", K(ret)); } } if (OB_SUCC(ret) && ObString::make_string("cast") == func_name) { if (OB_ISNULL(node->children_) || OB_ISNULL(node->children_[1]) || OB_ISNULL(node->children_[1]->children_) || OB_ISNULL(node->children_[1]->children_[1]) || OB_ISNULL(node->children_[1]->children_[0])) { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("invalid node children", K(ret), K(node)); } else { const ParseNode *cast_arg = node->children_[1]->children_[1]; const char *input = node->children_[1]->children_[0]->str_value_; ret = cast_accuracy_check(cast_arg, input); } if (OB_SUCC(ret)) { func_expr->set_extra(CM_EXPLICIT_CAST); } } // 在递归解析参数列表之前, 先检查下当前函数是否存在, 这是因为如果该函数报错OB_ERR_FUNCTION_UNKNOWN, 外部会继续尝试是否是UDF // 如果先解析参数列表, 则可能会将错误的column ref加入ctx_.columns_, 外部解析UDF的时候会重复加入导致解析错误 if (OB_SUCC(ret)) { ObExprOperatorType type; type = ObExprOperatorFactory::get_type_by_name(func_name); if (OB_UNLIKELY(T_INVALID == (type))) { ret = OB_ERR_FUNCTION_UNKNOWN; } } if (OB_SUCC(ret)) { func_expr->set_func_name(func_name); if (node->num_child_ > 1) { if (OB_ISNULL(node->children_) || OB_ISNULL(node->children_[1]) || OB_UNLIKELY(T_EXPR_LIST != node->children_[1]->type_)) { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("invalid node children", K(ret), K(node->children_)); } else { ObRawExpr *para_expr = NULL; int32_t num = node->children_[1]->num_child_; int current_columns_count = ctx_.columns_->count(); for (int32_t i = 0; OB_SUCC(ret) && i < num; i++) { if (OB_ISNULL(node->children_[1]->children_[i])) { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("invalid parse tree", K(ret)); } else if (T_EXPR_WITH_ALIAS == node->children_[1]->children_[i]->type_) { // only udf allow the the expr alias. ret = OB_ERR_FUNCTION_UNKNOWN; } else if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[1]->children_[i], para_expr)))) { LOG_WARN("fail to recursive resolve", K(ret), K(node->children_[1]->children_[i])); } else if (OB_FAIL(func_expr->add_param_expr(para_expr))) { LOG_WARN("fail to add param expr", K(ret), K(para_expr)); } } //end for // https://work.aone.alibaba-inc.com/issue/37807086 // check param count if (ret != OB_SUCCESS) { int temp_ret = ret; if (OB_FAIL(ObRawExprUtils::function_alias(ctx_.expr_factory_, func_expr))) { LOG_WARN("failed to do function alias", K(ret), K(func_expr)); } else if (OB_FAIL(func_expr->check_param_num(num))) { if (OB_ERR_FUNCTION_UNKNOWN != ret) { LOG_WARN("failed to check param num", K(func_name), K(num), K(ret)); } } if (ret == OB_SUCCESS) { ret = temp_ret; } } const ObExprOperatorType expr_type = ObExprOperatorFactory::get_type_by_name(func_name); if (OB_SUCC(ret) && T_FUN_SYS_NAME_CONST == expr_type && current_columns_count != ctx_.columns_->count()) { ret = OB_INVALID_ARGUMENT; LOG_USER_ERROR(OB_INVALID_ARGUMENT, N_NAME_CONST); LOG_WARN("params of name_const contain column references", K(ret)); } else if ((T_FUN_SYS_UUID2BIN == expr_type || T_FUN_SYS_BIN2UUID == expr_type) && func_expr->get_param_count() == 2) { //add bool expr for the second param ObRawExpr *param_expr = func_expr->get_param_expr(1); ObRawExpr *new_param_expr = NULL; if (OB_FAIL(ObRawExprUtils::try_create_bool_expr(param_expr, new_param_expr, ctx_.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 { func_expr->replace_param_expr(1, new_param_expr); } } } } //end > 1 } if (OB_SUCC(ret)) { if (OB_FAIL(ObRawExprUtils::function_alias(ctx_.expr_factory_, func_expr))) { LOG_WARN("failed to do function alias", K(ret), K(func_expr)); } else if (OB_FAIL(func_expr->check_param_num())) { if (OB_ERR_FUNCTION_UNKNOWN != ret) { LOG_WARN("failed to check param num", K(func_name), K(ret)); } } else { expr = func_expr; } } // 处理可已共享的表达式rownum if (OB_SUCC(ret)) { if (T_FUN_SYS_ROWNUM == func_expr->get_expr_type() && OB_NOT_NULL(ctx_.stmt_) && ctx_.stmt_->is_dml_stmt()) { ObDMLStmt *stmt = static_cast(ctx_.stmt_); ObRawExpr *rownum_expr = NULL; if (OB_FAIL(stmt->get_rownum_expr(rownum_expr))) { LOG_WARN("failed to get rownum expr", K(ret)); } else if (NULL == rownum_expr) { if (OB_FAIL(stmt->get_pseudo_column_like_exprs().push_back(func_expr))) { LOG_WARN("failed to push back rownum expr", K(ret)); } } else { expr = rownum_expr; } } } //mark expr is deterministic or not(default deterministic) if (OB_SUCC(ret)) { //bug:https://work.aone.alibaba-inc.com/issue/32921493 //maybe have more exprs, can be added below in the future. if (lib::is_oracle_mode() && expr->get_expr_type() == T_FUN_SYS_REGEXP_REPLACE) { expr->set_is_deterministic(false); } } return ret; } int ObRawExprResolverImpl::resolve_udf_info(const ParseNode *node, bool record_udf_info, ObUDFInfo &udf_info, ParseNode *extra_param, ObRawExpr *extra_expr) { int ret = OB_SUCCESS; ObUDFRawExpr *func_expr = NULL; if (OB_ISNULL(node) || T_FUN_UDF != node->type_ || OB_ISNULL(ctx_.udf_info_)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(node), K(ctx_.udf_info_)); } else if (OB_ISNULL(node->children_)) { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("invalid node children", K(ret), K(node->children_)); } else if (4 != node->num_child_) { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("invalid node children number", K(ret), K(node->num_child_)); } else if (OB_ISNULL(node->children_[0])) { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("invalid function name node", K(ret)); } else if (OB_FAIL(ObResolverUtils::resolve_udf(node, ctx_.case_mode_, udf_info))) { LOG_WARN("fail to result udf", K(ret)); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_FUN_UDF, func_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(func_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("null ptr", K(ret)); } else if (OB_NOT_NULL(node->children_[1])) { if (T_EXPR_LIST != node->children_[1]->type_) { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("invalid paramters node", K(ret), K(node->children_[1])); } else { // 先处理udt member function的self参数,self参数是第一个参数 if (OB_SUCC(ret) && OB_NOT_NULL(extra_param)) { ObRawExpr *param_expr = NULL; if (OB_FAIL(recursive_resolve(extra_param, param_expr))) { LOG_WARN("fail to recursive resolve udf parameters", K(ret), K(extra_param)); } else if (OB_FAIL(func_expr->add_param_expr(param_expr))) { LOG_WARN("fail to add param expr", K(ret), K(param_expr)); } else if (OB_FAIL(param_expr->add_flag(IS_UDT_UDF_SELF_PARAM))) { LOG_WARN("fail to add flag", K(ret)); } else { udf_info.udf_param_num_++; udf_info.is_contain_self_param_ = true; } } if (OB_SUCC(ret) && OB_ISNULL(extra_param) && OB_NOT_NULL(extra_expr)) { OZ (func_expr->add_param_expr(extra_expr)); udf_info.udf_param_num_++; udf_info.is_contain_self_param_ = true; } ObRawExpr *param_expr = NULL; int32_t num_child = node->children_[1]->num_child_; bool has_assign_expr = false; for (int32_t i = 0; OB_SUCC(ret) && i < num_child; ++i) { const ParseNode *param_node = node->children_[1]->children_[i]; if (OB_ISNULL(param_node)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("param node is null", K(ret)); } else if (T_SP_CPARAM == param_node->type_) { if (param_node->num_child_ != 2 || OB_ISNULL(param_node->children_[0]) || OB_ISNULL(param_node->children_[1])) { ret = OB_INVALID_ARGUMENT; LOG_WARN("param node is invalid", K(ret)); } else if (T_IDENT != param_node->children_[0]->type_) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid param name node", K(ret), K(param_node->children_[0]->type_)); } else { has_assign_expr = true; ObString param_name(static_cast(param_node->children_[0]->str_len_), param_node->children_[0]->str_value_); if (param_name.empty()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("param node string is empty", K(ret)); } else if (OB_FAIL(udf_info.param_names_.push_back(param_name))) { LOG_WARN("failed to push back", K(ret), K(param_name)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(param_node->children_[1], param_expr)))) { LOG_WARN("failed to recursive resolve", K(ret)); } else if (OB_FAIL(udf_info.param_exprs_.push_back(param_expr))) { LOG_WARN("failed to push back", K(ret)); } } } else if (has_assign_expr) { ret = OB_ERR_UNEXPECTED; LOG_WARN("can not get parameter after assign", K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(param_node, param_expr)))) { LOG_WARN("fail to recursive resolve udf parameters", K(ret), K(param_node)); } else if (OB_FAIL(func_expr->add_param_expr(param_expr))) { LOG_WARN("fail to add param expr", K(ret), K(param_expr)); } else { udf_info.udf_param_num_++; } } } } else { // if param is null, such as routine(), we also have to mock a param if (OB_SUCC(ret) && OB_NOT_NULL(extra_param)) { ObRawExpr *param_expr = NULL; if (OB_FAIL(recursive_resolve(extra_param, param_expr))) { LOG_WARN("fail to recursive resolve udf parameters", K(ret), K(extra_param)); } else if (OB_FAIL(func_expr->add_param_expr(param_expr))) { LOG_WARN("fail to add param expr", K(ret), K(param_expr)); } else if (OB_FAIL(param_expr->add_flag(IS_UDT_UDF_SELF_PARAM))) { LOG_WARN("fail to add flag", K(ret)); } else { udf_info.udf_param_num_++; udf_info.is_contain_self_param_ = true; } } if (OB_SUCC(ret) && OB_ISNULL(extra_param) && OB_NOT_NULL(extra_expr)) { OZ (func_expr->add_param_expr(extra_expr)); udf_info.udf_param_num_++; udf_info.is_contain_self_param_ = true; } } if (OB_SUCC(ret)) { func_expr->set_func_name(udf_info.udf_name_); udf_info.ref_expr_ = func_expr; udf_info.ref_expr_->set_is_udt_udf(udf_info.is_udt_udf_); if (record_udf_info) { if (OB_FAIL(ctx_.udf_info_->push_back(udf_info))) { LOG_WARN("add user defined func failed", K(ret)); } else if (ctx_.query_ctx_ != NULL) { ctx_.query_ctx_->has_udf_ = true; for (int64_t i = 0; OB_SUCC(ret) && i < ctx_.query_ctx_->all_user_variable_.count(); ++i) { if (OB_ISNULL(ctx_.query_ctx_->all_user_variable_.at(i))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get null user var expr", K(ret)); } else { ctx_.query_ctx_->all_user_variable_.at(i)->set_query_has_udf(true); } } } } } return ret; } int ObRawExprResolverImpl::process_udf_node(const ParseNode *node, bool record_udf_info, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObUDFInfo udf_info; if (OB_FAIL(resolve_udf_info(node, record_udf_info, udf_info))) { LOG_WARN("resolve udf info failed", K(ret)); } else { expr = udf_info.ref_expr_; } return ret; } int ObRawExprResolverImpl::not_int_check(const ObRawExpr *expr) { int ret = OB_SUCCESS; if (lib::is_mysql_mode() && NULL != expr && T_INT == expr->get_expr_type()) { ret = OB_ERR_WINDOW_ILLEGAL_ORDER_BY; LOG_WARN("int not expected in window function's orderby ", K(ret)); } return ret; } int ObRawExprResolverImpl::not_row_check(const ObRawExpr *expr) { int ret = OB_SUCCESS; if (NULL != expr && T_OP_ROW == expr->get_expr_type()) { ret = OB_ERR_INVALID_COLUMN_NUM; LOG_USER_ERROR(OB_ERR_INVALID_COLUMN_NUM, (int64_t)1); LOG_WARN("row not expected", K(ret), K(expr->get_param_count())); } return ret; } int ObRawExprResolverImpl::param_not_row_check(const ObRawExpr *expr) { int ret = OB_SUCCESS; for (int64_t i = 0; OB_SUCC(ret) && NULL != expr && i < expr->get_param_count(); i++) { OZ(not_row_check(expr->get_param_expr(i))); } return ret; } int ObRawExprResolverImpl::process_window_function_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObWinFunRawExpr *win_func = NULL; ParseNode *func_node = NULL; const static int win_function_num_child = 2; if (!is_win_expr_valid_scope(ctx_.current_scope_) || ctx_.parents_expr_info_.has_member(IS_AGG) || ctx_.parents_expr_info_.has_member(IS_WINDOW_FUNC)) { ret = OB_ERR_INVALID_WINDOW_FUNCTION_PLACE; LOG_WARN("window function is not allowed here", K(ret), K(ctx_.current_scope_), K(ctx_.parents_expr_info_)); } else if (OB_ISNULL(node)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(node)); } else if (OB_ISNULL(node->children_) || node->num_child_ != win_function_num_child) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(node->children_), K(node->num_child_)); } else if (OB_ISNULL(func_node = node->children_[0])) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(func_node)); } else if (T_WIN_FUN_RATIO_TO_REPORT == func_node->type_) { ParseNode *div_node = NULL; if (OB_FAIL(transform_ratio_afun_to_arg_div_sum(node, div_node))) { LOG_WARN("transform ratio_to_report node to div(arg, sum) failed", K(ret)); } else if (OB_ISNULL(div_node)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("div node is null", K(ret), K(div_node)); } else if (OB_FAIL(process_operator_node(div_node, expr))) { LOG_WARN("process div node failed", K(ret)); } } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_WINDOW_FUNCTION, win_func))) { LOG_WARN("create window function expr failed", K(ret)); } else { ObItemType func_type = func_node->type_; ObRawExpr *agg_node_expr = NULL; ObArray func_params; ObRawExpr *func_param = NULL; if (T_FUN_COUNT == func_type || T_FUN_AVG == func_type || T_FUN_MIN == func_type || T_FUN_MAX == func_type || T_FUN_SUM == func_type || T_FUN_MEDIAN == func_type || T_FUN_STDDEV == func_type || T_FUN_STDDEV_SAMP == func_type || T_FUN_VARIANCE == func_type || T_FUN_STDDEV_POP == func_type || T_FUN_APPROX_COUNT_DISTINCT == func_type || T_FUN_APPROX_COUNT_DISTINCT_SYNOPSIS == func_type || T_FUN_APPROX_COUNT_DISTINCT_SYNOPSIS_MERGE == func_type || T_FUN_GROUP_CONCAT == func_type || T_FUN_GROUP_PERCENTILE_CONT == func_type || T_FUN_GROUP_PERCENTILE_DISC == func_type || T_FUN_CORR == func_type || T_FUN_COVAR_POP == func_type || T_FUN_COVAR_SAMP == func_type || T_FUN_VAR_POP == func_type || T_FUN_VAR_SAMP == func_type || T_FUN_REGR_SLOPE == func_type || T_FUN_REGR_INTERCEPT == func_type || T_FUN_REGR_R2 == func_type || T_FUN_REGR_COUNT == func_type || T_FUN_REGR_AVGX == func_type || T_FUN_REGR_AVGY == func_type || T_FUN_REGR_SXX == func_type || T_FUN_REGR_SYY == func_type || T_FUN_REGR_SXY == func_type || T_FUN_KEEP_MAX == func_type || T_FUN_KEEP_MIN == func_type || T_FUN_KEEP_SUM == func_type || T_FUN_KEEP_COUNT == func_type || T_FUN_KEEP_AVG == func_type || T_FUN_KEEP_STDDEV == func_type || T_FUN_KEEP_VARIANCE == func_type || T_FUN_KEEP_WM_CONCAT == func_type || T_FUN_WM_CONCAT == func_type || T_FUN_TOP_FRE_HIST == func_type || T_FUN_PL_AGG_UDF == func_type || T_FUN_HYBRID_HIST == func_type || T_FUN_SYS_BIT_AND == func_type || T_FUN_SYS_BIT_OR == func_type || T_FUN_SYS_BIT_XOR == func_type || T_FUN_JSON_ARRAYAGG == func_type || T_FUN_JSON_OBJECTAGG == func_type) { ctx_.is_win_agg_ = true; if (T_FUN_PL_AGG_UDF == func_type) { ParseNode *agg_udf_node = NULL; ParseNode *obj_access_node = NULL; if (OB_UNLIKELY(func_node->num_child_ != 3)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected error", K(func_node->num_child_)); } else if (OB_FAIL(ObRawExprUtils::new_parse_node(agg_udf_node, ctx_.expr_factory_, T_FUN_SYS, 3))) { LOG_WARN("failed to new parse node", K(ret), K(agg_udf_node)); } else if (OB_FAIL(ObRawExprUtils::new_parse_node(obj_access_node, ctx_.expr_factory_, T_OBJ_ACCESS_REF, 2))) { LOG_WARN("failed to new parse node", K(ret), K(obj_access_node)); } else { agg_udf_node->children_[0] = func_node->children_[0]; agg_udf_node->children_[1] = func_node->children_[1]; agg_udf_node->children_[2] = func_node->children_[2]; obj_access_node->children_[0] = agg_udf_node; obj_access_node->children_[1] = NULL; func_node = obj_access_node; } } if (OB_FAIL(ret)) { } else if (OB_FAIL(ctx_.parents_expr_info_.add_member(IS_WINDOW_FUNC))) { LOG_WARN("failed to add member to parent exprs info.", K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(func_node, agg_node_expr)))) { LOG_WARN("resolve agg failed", K(ret)); } else if (OB_FAIL(ctx_.parents_expr_info_.del_member(IS_WINDOW_FUNC))) { LOG_WARN("failed to delete member from parent exprs info.", K(ret)); } else { /*do nothing.*/ } } else if (T_WIN_FUN_NTILE == func_type) { if (OB_FAIL(ctx_.parents_expr_info_.add_member(IS_WINDOW_FUNC))) { LOG_WARN("failed to add member to parents epxrs info.", K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(func_node->children_[0], func_param)))) { LOG_WARN("recursive resolve node failed", K(ret)); } else if (OB_FAIL(ctx_.parents_expr_info_.del_member(IS_WINDOW_FUNC))) { LOG_WARN("failed to delete member to parents epxrs info.", K(ret)); } else if (OB_ISNULL(func_param)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("func_param is null", K(func_param), K(ret)); } else { ObSysFunRawExpr *floor_expr = NULL; //we create a floor expr to deal with ntile(1 + 1.1) if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_FUN_SYS_FLOOR, floor_expr))) { LOG_WARN("create floor function expr failed", K(ret)); } else if (OB_ISNULL(floor_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("sys_floor_expr is null", K(ret)); } else if (OB_FAIL(floor_expr->add_param_expr(func_param))) { LOG_WARN("failed to add param expr", K(ret)); } else if (OB_FAIL(func_params.push_back(floor_expr))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("push back func_param failed", K(floor_expr), K(ret)); } } } else if (T_WIN_FUN_NTH_VALUE == func_type) { ParseNode *measure_expr_node = NULL; ParseNode *n_expr_node = NULL; ObRawExpr *measure_expr = NULL; ObRawExpr *n_expr = NULL; if (OB_UNLIKELY(func_node->num_child_ != 4) || OB_ISNULL(measure_expr_node = func_node->children_[0]) || OB_ISNULL(n_expr_node = func_node->children_[1])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("function node is invalid", K(ret)); } else if (OB_FAIL(ctx_.parents_expr_info_.add_member(IS_WINDOW_FUNC))) { LOG_WARN("failed to add member to parents epxrs info.", K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(measure_expr_node, measure_expr)))) { LOG_WARN("fail to recursive resolve measure_expr", K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(n_expr_node, n_expr)))) { LOG_WARN("fail to recursive resolve measure_expr", K(ret)); } else if (OB_FAIL(ctx_.parents_expr_info_.del_member(IS_WINDOW_FUNC))) { LOG_WARN("failed to delete member to parents epxrs info.", K(ret)); } else if (OB_FAIL(func_params.push_back(measure_expr))) { LOG_WARN("fail to add param expr", K(ret)); } else if (OB_FAIL(func_params.push_back(n_expr))) { LOG_WARN("fail to add param expr", K(ret)); } else { win_func->set_is_from_first(NULL == func_node->children_[2] || T_FIRST == func_node->children_[2]->type_); win_func->set_is_ignore_null(!(NULL == func_node->children_[3] || T_RESPECT == func_node->children_[3]->type_)); } } else if (T_WIN_FUN_LEAD == func_type || T_WIN_FUN_LAG == func_type) { ParseNode *expr_list_node = NULL; ObRawExpr *sub_expr = NULL; if (OB_UNLIKELY(func_node->num_child_ != 2) || OB_ISNULL(expr_list_node = func_node->children_[0])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("function node is invalid", K(ret)); } else if (OB_UNLIKELY(T_EXPR_LIST != expr_list_node->type_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr list node type is invalid", K(ret)); } else if (OB_UNLIKELY(expr_list_node->num_child_ < 1 || expr_list_node->num_child_ > 3)) { // LEAD and LAG should have at least 1 argument and at most 3 arguments. ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument number", K(ret)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < expr_list_node->num_child_; ++i) { if (OB_ISNULL(expr_list_node->children_[i])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid expr list node children", K(ret), K(i), K(expr_list_node->children_[i])); } else if (OB_FAIL(ctx_.parents_expr_info_.add_member(IS_WINDOW_FUNC))) { LOG_WARN("failed to add member to parents epxrs info.", K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(expr_list_node->children_[i], sub_expr)))) { LOG_WARN("fail to recursive resolve expr list item", K(ret)); } else if (OB_FAIL(ctx_.parents_expr_info_.del_member(IS_WINDOW_FUNC))) { LOG_WARN("failed to delete member to parents epxrs info.", K(ret)); } else if (OB_FAIL(func_params.push_back(sub_expr))) { LOG_WARN("fail to add param expr to agg expr", K(ret)); } } if (OB_SUCC(ret)) { if (NULL == func_node->children_[1] || T_RESPECT == func_node->children_[1]->type_) { win_func->set_is_ignore_null(false); } else { win_func->set_is_ignore_null(true); } } } } else if (T_WIN_FUN_FIRST_VALUE == func_type || T_WIN_FUN_LAST_VALUE == func_type) { ParseNode *measure_expr_node = NULL; ObRawExpr *measure_expr = NULL; if (OB_UNLIKELY(func_node->num_child_ != 2)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("function node is invalid", K(ret)); } else if (OB_ISNULL(measure_expr_node = func_node->children_[0])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid node children", K(ret)); } else if (OB_FAIL(ctx_.parents_expr_info_.add_member(IS_WINDOW_FUNC))) { LOG_WARN("failed to add member to parents epxrs info.", K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(measure_expr_node, measure_expr)))) { LOG_WARN("fail to recursive resolve expr", K(ret)); } else if (OB_FAIL(ctx_.parents_expr_info_.del_member(IS_WINDOW_FUNC))) { LOG_WARN("failed to delete member to parents epxrs info.", K(ret)); } else if (OB_FAIL(func_params.push_back(measure_expr))) { LOG_WARN("fail to add param expr", K(ret)); } else { win_func->set_is_ignore_null(!(NULL == func_node->children_[1] || T_RESPECT == func_node->children_[1]->type_)); } // convert to nth_value if (OB_SUCC(ret)) { win_func->set_is_from_first(T_WIN_FUN_FIRST_VALUE == func_type); func_type = T_WIN_FUN_NTH_VALUE; ObConstRawExpr *c_expr = NULL; if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_INT, c_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(c_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("const expr is null"); } else { ObObj val; val.set_int(1); c_expr->set_value(val); c_expr->set_param(val); if (OB_FAIL(func_params.push_back(c_expr))) { LOG_WARN("fail to add param expr", K(ret)); } } } } ParseNode *name_node = NULL; ParseNode *win_node = NULL; if (T_WIN_NEW_GENERALIZED_WINDOW == node->children_[1]->type_) { name_node = node->children_[1]->children_[0]; win_node = node->children_[1]->children_[1]; } else { win_node = node->children_[1]; } // window_function -> node -> count(*) over (w order by c) // count -> node->child[0] -> count(*) // new_generalized_window -> node->child[1] -> (w order by c) // name_ob -> node->child[1]->child[0] -> w // generalized_window -> node->child[1]->child[1] -> order by c if(OB_SUCC(ret)) { if (OB_ISNULL(name_node) && OB_ISNULL(win_node)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("NULL ptr", K(name_node), K(win_node), K(ret)); } } ObWinFunRawExpr *named_win = NULL; if (OB_SUCC(ret) && name_node) { ObString name(static_cast(name_node->str_len_), name_node->str_value_); if (!ctx_.stmt_->is_select_stmt()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected stmt", K(ret)); } else { ObSelectStmt *select_stmt = static_cast(ctx_.stmt_); ObIArray &named_windows = select_stmt->get_window_func_exprs(); for (int64_t i = 0; OB_SUCC(ret) && i < named_windows.count(); ++i) { if (ObCharset::case_insensitive_equal(name, named_windows.at(i)->get_win_name())) { named_win = named_windows.at(i); break; } } if(OB_SUCC(ret) && NULL == named_win) { ret = OB_ERR_WINDOW_NAME_IS_NOT_DEFINE; LOG_WARN("name win not exist", K(name), K(ret), K(named_windows)); LOG_USER_ERROR(OB_ERR_WINDOW_NAME_IS_NOT_DEFINE, name.length(), name.ptr()); } } } ParseNode *partition_by_node = win_node ? win_node->children_[0] : NULL; ParseNode *order_by_node = win_node ? win_node->children_[1] : NULL; ParseNode *frame_node = win_node ? win_node->children_[2] : NULL; int8_t win_seg = 0; int8_t r_win_seg = 0; const static int8_t p_pos = 1 << 0; // partition const static int8_t o_pos = 1 << 1; // order const static int8_t f_pos = 1 << 2; // frame if (OB_SUCC(ret)) { if (named_win) { win_seg |= p_pos; } if (named_win && named_win->get_order_items().count() != 0) { win_seg |= o_pos; } if (named_win && named_win->has_frame_orig()) { win_seg |= f_pos; } if (partition_by_node) { r_win_seg |= p_pos; } if (order_by_node) { r_win_seg |= o_pos; } if (frame_node) { r_win_seg |= f_pos; } if (OB_UNLIKELY(win_seg & r_win_seg)) { // verification sequence : frame > partition > order if (f_pos & (win_seg & r_win_seg)) { ret = OB_EER_WINDOW_NO_INHERIT_FRAME; LOG_USER_ERROR(OB_EER_WINDOW_NO_INHERIT_FRAME, named_win->get_win_name().length(), named_win->get_win_name().ptr()); } else if (p_pos & (win_seg & r_win_seg)) { ret = OB_EER_WINDOW_NO_CHILD_PARTITIONING; LOG_USER_ERROR(OB_EER_WINDOW_NO_CHILD_PARTITIONING); } else if (o_pos & (win_seg & r_win_seg)) { ret = OB_EER_WINDOW_NO_REDEFINE_ORDER_BY; // LOG_USER_ERROR in upper level function } else { ret = OB_ERR_UNEXPECTED; } LOG_WARN("Named window modified by another framing, partitioning or ordering property", K(ret), K(win_seg), K(r_win_seg), K(win_seg & r_win_seg)); } } if (OB_SUCC(ret) && lib::is_oracle_mode() && (T_FUN_GROUP_CONCAT == func_type || T_FUN_KEEP_MAX == func_type || T_FUN_KEEP_MIN == func_type || T_FUN_KEEP_COUNT == func_type || T_FUN_KEEP_SUM == func_type || T_FUN_KEEP_STDDEV == func_type || T_FUN_KEEP_VARIANCE == func_type || T_FUN_MEDIAN == func_type || T_FUN_GROUP_PERCENTILE_CONT == func_type || T_FUN_GROUP_PERCENTILE_DISC == func_type || T_FUN_KEEP_WM_CONCAT == func_type) && (OB_NOT_NULL(order_by_node) || OB_NOT_NULL(frame_node))) { ret = OB_ORDERBY_CLAUSE_NOT_ALLOWED; LOG_WARN("ORDER BY not allowed here", K(ret)); } if (OB_SUCC(ret) && lib::is_oracle_mode() && OB_NOT_NULL(frame_node) && OB_ISNULL(order_by_node)) { ret = OB_ERR_MISS_ORDER_BY_EXPR; LOG_WARN("missing ORDER BY expression in the window specification", K(ret)); } if (OB_SUCC(ret)) { ObArray partition_exprs; ObArray order_items; ObFrame frame; ObString sort_str; if (win_seg & p_pos) { partition_by_node = NULL; ret = partition_exprs.assign(named_win->get_partition_exprs()); } if (OB_SUCC(ret) && (win_seg & o_pos)) { order_by_node = NULL; sort_str = named_win->sort_str_; ret = order_items.assign(named_win->get_order_items()); } if (OB_SUCC(ret) && (win_seg & f_pos)) { frame_node = NULL; ret = frame.assign(*named_win); } #define RESOLVE_EXPR_LIST(expr_list_node, exprs) \ if (OB_UNLIKELY(T_EXPR_LIST != expr_list_node->type_) \ || OB_ISNULL(expr_list_node->children_)) { \ ret = OB_ERR_UNEXPECTED; \ LOG_WARN("invalid children", K(ret), K(expr_list_node->type_), \ K(expr_list_node->children_)); \ } \ for (int64_t i = 0; OB_SUCC(ret) && i < expr_list_node->num_child_; ++i) { \ ObRawExpr *sub_expr = NULL; \ if (OB_ISNULL(expr_list_node->children_[i])) { \ ret = OB_ERR_UNEXPECTED; \ LOG_WARN("invalid expr list node children", K(ret), K(i), K(expr_list_node->children_[i])); \ } else if (OB_FAIL(SMART_CALL(recursive_resolve(expr_list_node->children_[i], sub_expr)))) { \ LOG_WARN("fail to recursive resolve expr list item", K(ret)); \ } else { \ OZ(not_row_check(sub_expr)); \ OZ(exprs.push_back(sub_expr)); \ } \ } if (OB_SUCC(ret) && NULL != partition_by_node) { RESOLVE_EXPR_LIST(partition_by_node, partition_exprs); } if (OB_SUCC(ret) && NULL != order_by_node) { if (OB_UNLIKELY(order_by_node->type_ != T_ORDER_BY) || OB_UNLIKELY(order_by_node->num_child_ != 2) || OB_ISNULL(order_by_node->children_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("order by node is null or invalid", K(order_by_node)); } else if (OB_UNLIKELY(NULL != order_by_node->children_[1])) { ret = OB_ERR_CBY_OREDER_SIBLINGS_BY_NOT_ALLOWED; LOG_WARN("ORDER SIBLINGS BY clause not allowed here"); } else if (OB_FAIL(process_sort_list_node(order_by_node->children_[0], order_items))) { LOG_WARN("process sort list failed", K(ret)); } else { ParseNode *sort_node = order_by_node->children_[0]->children_[0]; if (sort_node) { ParseNode *sort_expr_node = sort_node->children_[0]; if (sort_expr_node) { sort_str.assign_ptr(const_cast(sort_expr_node->str_value_), static_cast(sort_expr_node->str_len_)); } } } } if (OB_SUCC(ret) && NULL != frame_node) { if (OB_FAIL(process_frame_node(frame_node, frame))) { LOG_WARN("process window node failed", K(ret)); } } if (OB_SUCC(ret)) { win_func->set_func_type(func_type); win_func->set_has_frame_orig(frame_node != NULL); if (OB_FAIL(win_func->set_func_params(func_params))) { LOG_WARN("set function parameters failed", K(ret)); } else if (OB_FAIL(win_func->set_partition_exprs(partition_exprs))) { LOG_WARN("set partition_by exprs failed", K(ret)); } else if (OB_FAIL(win_func->set_order_items(order_items))) { LOG_WARN("set order_by exprs failed", K(ret)); } else if (OB_FAIL(win_func->ObFrame::assign(frame))) { LOG_WARN("assign frame failed", K(ret)); } else { win_func->sort_str_ = sort_str; expr = win_func; //for T_FUN_PL_AGG_UDF, we will deal with expr together later. if (agg_node_expr != NULL && func_type != T_FUN_PL_AGG_UDF) { if (OB_FAIL(process_window_agg_node(func_type, win_func, agg_node_expr, expr))) { LOG_WARN("process window agg node failed", K(ret)); } } else { expr = win_func; ret = ctx_.win_exprs_->push_back(win_func); if (func_type == T_FUN_PL_AGG_UDF) { win_func->set_pl_agg_udf_expr(agg_node_expr); } } } } } } OZ(param_not_row_check(expr)); return ret; } int ObRawExprResolverImpl::process_window_agg_node(const ObItemType func_type, ObWinFunRawExpr *win_func, ObRawExpr *agg_node_expr, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObAggFunRawExpr *agg_expr = static_cast(agg_node_expr); if (OB_ISNULL(agg_expr)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("unexpected null pointer.", K(ret)); } else if ((T_FUN_SUM == func_type || T_FUN_COUNT == func_type || T_FUN_AVG == func_type || T_FUN_VARIANCE == func_type || T_FUN_STDDEV == func_type) && (agg_expr->is_param_distinct() && (win_func->has_order_items() || win_func->has_frame_orig()))) { ret = OB_ORDERBY_CLAUSE_NOT_ALLOWED; } else if (FALSE_IT(win_func->set_agg_expr(agg_expr))) { } else if (OB_FAIL(ctx_.win_exprs_->push_back(win_func))) { LOG_WARN("failed to push back into win exprs.", K(ret)); } else { expr = win_func; } return ret; } int ObRawExprResolverImpl::process_sort_list_node(const ParseNode *node, ObIArray &order_items) { int ret = OB_SUCCESS; order_items.reset(); if (OB_ISNULL(node)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node)); } else if (NULL == node->children_) { // do-nothing } else { for (int64_t i = 0; OB_SUCC(ret) && i < node->num_child_; ++i) { OrderItem order_item; const ParseNode *sort_node = node->children_[i]; if (OB_ISNULL(sort_node) || OB_UNLIKELY(2 != sort_node->num_child_) || OB_ISNULL(sort_node->children_) || OB_ISNULL(sort_node->children_[0]) || OB_ISNULL(sort_node->children_[1])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid sort node", K(ret), K(sort_node)); } else if (OB_FAIL(ObResolverUtils::set_direction_by_mode(*sort_node, order_item))) { LOG_WARN("failed to set direction by mode", K(ret)); } if (OB_SUCC(ret)) { if (OB_FAIL(SMART_CALL(recursive_resolve(sort_node->children_[0], order_item.expr_)))) { LOG_WARN("fail to recursive resolve order item expr", K(ret)); } else { /* check order_item.expr_: * 1. shouldn't be int, * 2. if is number, ignore the order_item.(all group are in same group); * shouldn't check int in deduce_type, because stmt like "select rank() over(order by c1) from t1 where c1=1;" * the stmt would be rewritten to "select rank() over(order by 1) from t1;". * if we check int type while deducing type, the above stmt will raise error, however, it should succeed in mysql. */ OZ(not_int_check(order_item.expr_)); OZ(not_row_check(order_item.expr_)); OZ(order_items.push_back(order_item)); } } } // end for } //end else return ret; } int ObRawExprResolverImpl::process_frame_node(const ParseNode *node, ObFrame &frame) { int ret = OB_SUCCESS; frame.win_type_ = WINDOW_MAX; frame.is_between_ = false; if (OB_ISNULL(node)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node)); } else if (node->type_ != T_WIN_WINDOW) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node->type_)); } else { ParseNode *win_type_node = node->children_[0]; frame.is_between_ = 1 == node->value_; if (1 == win_type_node->value_) { frame.win_type_ = WINDOW_ROWS; } else if (2 == win_type_node->value_) { frame.win_type_ = WINDOW_RANGE; } else { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(win_type_node->value_)); } if (OB_SUCC(ret)) { ParseNode *upper_bound_node = node->children_[1]; if (OB_FAIL(process_bound_node(upper_bound_node, true, frame.get_upper()))) { LOG_WARN("process upper bound node failed", K(ret)); } else if (frame.is_between_) { ParseNode *lower_bound_node = node->children_[2]; if (OB_FAIL(process_bound_node(lower_bound_node, false, frame.get_lower()))) { LOG_WARN("process lower bound node failed", K(ret)); } } /* check the frame * In mysql, ROWS can't coexists with (INTERVAL expr unit). * mysql: select c1, sum(c1) over(order by c1 rows interval 5 day preceding) from t1; * mysql will raise error: ERROR 3596 (HY000): INTERVAL can only be used with RANGE frames. */ if (OB_SUCC(ret) && lib::is_mysql_mode() && frame.win_type_ == WINDOW_ROWS) { if (frame.get_upper().type_ == BOUND_INTERVAL && !frame.get_upper().is_nmb_literal_) { // upper is a (INTERVAL expr unit) ret = OB_ERR_WINDOW_ROWS_INTERVAL_USE; LOG_WARN("INTERVAL can only be used with RANGE frames.", K(ret)); } else if (frame.get_lower().type_ == BOUND_INTERVAL && !frame.get_lower().is_nmb_literal_) { ret = OB_ERR_WINDOW_ROWS_INTERVAL_USE; LOG_WARN("INTERVAL can only be used with RANGE frames.", K(ret)); } } } } return ret; } int ObRawExprResolverImpl::process_bound_node(const ParseNode *node, const bool is_upper, Bound &bound) { int ret = OB_SUCCESS; bound.type_ = BOUND_UNBOUNDED; bound.is_preceding_ = false; if (OB_ISNULL(node)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node)); } else if (node->type_ != T_WIN_BOUND) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node->type_)); } else { if (1 == node->value_) { bound.type_ = BOUND_CURRENT_ROW; bound.is_preceding_ = is_upper; } else if (2 == node->value_) { bound.is_preceding_ = 1 == node->children_[1]->value_; // we distinguish unbounded and expr interval by string_value ObString expr_str(static_cast(node->children_[0]->str_len_), const_cast(node->children_[0]->str_value_)); if (ObCharset::case_insensitive_equal(expr_str, "UNBOUNDED")) { bound.type_ = BOUND_UNBOUNDED; } else { bound.type_ = BOUND_INTERVAL; if (OB_FAIL(process_interval_node(node->children_[0], bound.is_nmb_literal_, bound.interval_expr_, bound.date_unit_expr_))) { LOG_WARN("process interval node failed", K(ret)); } } } else { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node->value_)); } } return ret; } int ObRawExprResolverImpl::process_interval_node(const ParseNode *node, bool &is_nmb_literal, ObRawExpr *&interval_expr, ObRawExpr *&date_unit_expr) { int ret = OB_SUCCESS; is_nmb_literal = false; interval_expr = NULL; date_unit_expr = NULL; if (OB_ISNULL(node)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node)); } else if (node->type_ != T_WIN_INTERVAL) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node->type_)); } else { is_nmb_literal = 1 == node->value_; ParseNode *interval_node = node->children_[0]; if (OB_ISNULL(interval_node)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("NULL ptr", K(interval_node), K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(interval_node, interval_expr)))) { SQL_RESV_LOG(WARN, "resolve failed", K(ret)); } else if (OB_ISNULL(interval_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("NULL ptr", K(ret), K(interval_expr)); } else if (!is_nmb_literal) { // date type ParseNode *date_unit_node = node->children_[1]; if (OB_FAIL(SMART_CALL(recursive_resolve(date_unit_node, date_unit_expr)))) { SQL_RESV_LOG(WARN, "resolve failed", K(ret)); } else if (OB_ISNULL(date_unit_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("NULL ptr", K(ret), K(date_unit_expr)); } else if (!date_unit_expr->is_const_raw_expr()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("not const expr error", K(ret), K(date_unit_expr->get_expr_type())); } else {/*do nothing*/} } } return ret; } /** * window function which can't not specified windowing_clause */ bool ObRawExprResolverImpl::should_not_contain_window_clause(const ObItemType func_type) { //https://docs.oracle.com/cd/E11882_01/server.112/e41084/functions004.htm#SQLRF06174 /** * Some analytic functions allow the windowing_clause. */ return T_WIN_FUN_ROW_NUMBER == func_type || T_WIN_FUN_NTILE == func_type || T_WIN_FUN_CUME_DIST == func_type || T_WIN_FUN_LAG == func_type || T_WIN_FUN_LEAD == func_type || T_WIN_FUN_RANK == func_type || T_WIN_FUN_DENSE_RANK == func_type || T_WIN_FUN_PERCENT_RANK == func_type; } /** * window function which should contain order_by clause */ bool ObRawExprResolverImpl::should_contain_order_by_clause(const ObItemType func_type) { return T_WIN_FUN_ROW_NUMBER == func_type || T_WIN_FUN_NTILE == func_type || T_WIN_FUN_RANK == func_type || T_WIN_FUN_DENSE_RANK == func_type || T_WIN_FUN_PERCENT_RANK == func_type || T_WIN_FUN_CUME_DIST == func_type || T_WIN_FUN_LAG == func_type || T_WIN_FUN_LEAD == func_type; } //同oracle一样, 当first_value, last_value指定了窗口时必须有order by; //之前解析时会转换为nth_value bool ObRawExprResolverImpl::check_frame_and_order_by_valid(const ObItemType func_type, const bool has_order_by, const bool has_frame) { bool is_valid = true; if (T_WIN_FUN_NTH_VALUE == func_type) { if (!has_order_by && has_frame) { is_valid = false; } } return is_valid; } int ObRawExprResolverImpl::check_and_canonicalize_window_expr(ObRawExpr *expr) { int ret = OB_SUCCESS; if (OB_ISNULL(expr)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(expr)); } else if (!expr->is_win_func_expr()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(expr->get_expr_type())); } else { ObWinFunRawExpr *w_expr = static_cast(expr); WindowType win_type = w_expr->get_window_type(); bool is_between = w_expr->is_between(); Bound upper = w_expr->get_upper(); Bound lower = w_expr->get_lower(); ObItemType func_type = w_expr->get_func_type(); const ObIArray &order_items = w_expr->get_order_items(); // @note: 做一些语义检查, 这一步没有在parser做是为了保持语法树的简单清晰 bool parse_error = false; if (win_type != WINDOW_MAX) { if (BOUND_UNBOUNDED == upper.type_ && !upper.is_preceding_) { parse_error = true; } if (!parse_error && is_between) { if (BOUND_UNBOUNDED == lower.type_ && lower.is_preceding_) { parse_error = true; } } } if (!parse_error && win_type != WINDOW_MAX && !is_between && BOUND_INTERVAL == upper.type_ && !upper.is_preceding_) { parse_error = true; } if (parse_error) { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("parse error", K(ret), K(upper), K(lower), K(win_type)); } // 关于是否需要指定order by以及能否指定frame问题, 请见文档: // oracle https://docs.oracle.com/en/database/oracle/oracle-database/18/sqlrf/Analytic-Functions.html#GUID-527832F7-63C0-4445-8C16-307FA5084056 // 目前来看可以选择兼容mysql来做, 这两点的处理上mysql算是超集 if (OB_SUCC(ret) && lib::is_oracle_mode()) { if (should_contain_order_by_clause(func_type) && 0 == order_items.count()) { ret = OB_ERR_MISS_ORDER_BY_EXPR; LOG_WARN("missing ORDER BY expression in the window specification", K(ret)); } else if (!check_frame_and_order_by_valid(func_type, 0 != order_items.count(), w_expr->has_frame_orig())) { ret = OB_ERR_INVALID_WINDOW_FUNC_USE; LOG_WARN("frame clause must be specified for certain window function", K(ret), K(func_type)); } } if (OB_SUCC(ret) && lib::is_mysql_mode() && w_expr->has_frame_orig() && WINDOW_RANGE == win_type && 0 == order_items.count() && (w_expr->get_upper().type_ == BOUND_INTERVAL || w_expr->get_lower().type_ == BOUND_INTERVAL)) { /* if preceding or following has a specific value (not the default unbounded) * in mysql: * @OK: select c1, sum(c1) over(range between current row and current row) from t1; * @OK: select c1, sum(c1) over(range unbounded preceding) from t1; * @error: select c1, sum(c1) over(range 1 preceding) from t1; --error 3587 */ ret = OB_ERR_WINDOW_RANGE_FRAME_ORDER_TYPE; LOG_WARN("missing ORDER BY expression in the window specification", K(ret)); } // reset frame if (OB_SUCC(ret) && win_type != WINDOW_MAX && should_not_contain_window_clause(func_type)) { win_type = WINDOW_MAX; upper = Bound(); lower = Bound(); } if (OB_SUCC(ret)) { // @note: 得到一个between形式的标准窗口 // 1. 如果未定义窗口, 自定义一个range between (unbounded preceding) and (unbounded following or current row) // 2. 将非between的窗口转成between if (WINDOW_MAX == win_type) { win_type = WINDOW_RANGE; is_between = true; if (0 == order_items.count()) { upper.type_ = BOUND_UNBOUNDED; lower.type_ = BOUND_UNBOUNDED; } else { upper.type_ = BOUND_UNBOUNDED; lower.type_ = BOUND_CURRENT_ROW; } } else { if (!is_between) { is_between = true; // 走到这里, 必然定义了order by lower.type_ = BOUND_CURRENT_ROW; lower.is_preceding_ = false; } } } if (OB_SUCC(ret)) { //special case if (should_not_contain_window_clause(func_type)) { lower.type_ = BOUND_UNBOUNDED; if (lib::is_oracle_mode() && w_expr->has_frame_orig()) { ret = OB_ERR_INVALID_WINDOW_FUNC_USE; LOG_WARN("invalid window specification", K(ret), K(upper), K(lower)); } } } // 修正unbounded的is_preceding_ // unbounded语义下is_preceding_没有意义, 这里作修正仅仅是为了explain显示用 if (OB_SUCC(ret)) { if (BOUND_UNBOUNDED == upper.type_) { upper.is_preceding_ = true; } if (BOUND_UNBOUNDED == lower.type_) { lower.is_preceding_ = false; } } // oracle compatible, 解析阶段能够识别的无效窗口直接抛错 if (OB_SUCC(ret)) { if ((BOUND_CURRENT_ROW == upper.type_ && BOUND_INTERVAL == lower.type_ && lower.is_preceding_) || (BOUND_CURRENT_ROW == lower.type_ && BOUND_INTERVAL == upper.type_ && !upper.is_preceding_) || (BOUND_INTERVAL == upper.type_ && !upper.is_preceding_ && BOUND_INTERVAL == lower.type_ && lower.is_preceding_)) { ret = OB_ERR_INVALID_WINDOW_FUNC_USE; LOG_WARN("invalid window specification", K(ret), K(upper), K(lower)); } } // oracle compatible, 排序列为向量时, range窗口不能为表达式, 只能是unbounded or current row if (OB_SUCC(ret)) { if (order_items.count() > 1 && WINDOW_RANGE == win_type && (upper.interval_expr_ != NULL || lower.interval_expr_ != NULL)) { ret = OB_ERR_INVALID_WINDOW_FUNC_USE; LOG_WARN("invalid window specification", K(ret), K(win_type), K(upper), K(lower)); } else if (WINDOW_RANGE == win_type) { Bound *bs[2] = { &upper, &lower }; for (int i = 0; i < 2 && OB_SUCC(ret); i++) { Bound *bound = bs[i]; if (bound->interval_expr_ != NULL) { for (int j = 0; j < 2 && OB_SUCC(ret); j++) { if (bound->is_nmb_literal_) {//普通数值类型范围加减 ObOpRawExpr *op_expr = NULL; if (j == 0 && OB_FAIL(ObRawExprUtils::build_add_expr(ctx_.expr_factory_, order_items.at(0).expr_, bound->interval_expr_, op_expr))) { LOG_WARN("failed to build add expr", K(ret)); } else if (j == 1 && OB_FAIL(ObRawExprUtils::build_minus_expr(ctx_.expr_factory_, order_items.at(0).expr_, bound->interval_expr_, op_expr))) { LOG_WARN("failed to build minus expr", K(ret)); } else if (OB_ISNULL(op_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("NULL ptr", K(ret), K(op_expr)); } else { bound->exprs_[j] = op_expr; } } else if (!bound->is_nmb_literal_) {//date类型范围加减 ObSysFunRawExpr *sys_expr = NULL; if (j == 0 && OB_FAIL(ObRawExprUtils::build_date_add_expr(ctx_.expr_factory_, order_items.at(0).expr_, bound->interval_expr_, bound->date_unit_expr_, sys_expr))) { LOG_WARN("failed to build add expr", K(ret)); } else if (j == 1 && OB_FAIL(ObRawExprUtils::build_date_sub_expr(ctx_.expr_factory_, order_items.at(0).expr_, bound->interval_expr_, bound->date_unit_expr_, sys_expr))) { LOG_WARN("failed to build minus expr", K(ret)); } else if (OB_ISNULL(sys_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("NULL ptr", K(ret), K(sys_expr)); } else { bound->exprs_[j] = sys_expr; } } } } } } } if (OB_SUCC(ret)) { w_expr->set_window_type(win_type); w_expr->set_is_between(is_between); w_expr->set_upper(upper); w_expr->set_lower(lower); } } return ret; } //查询改写 ratio_to_report(c1) over (partition by c2) ==> // c1 / case sum(c1) over (partition by c2) when 0 then null else sum(c1) over (partition by c2) end int ObRawExprResolverImpl::transform_ratio_afun_to_arg_div_sum(const ParseNode *ratio_fun_node, ParseNode *&div_node) //out, 最终的 c1 / simple_case { int ret = OB_SUCCESS; const ParseNode *func_node = NULL; ParseNode *when_list_node = NULL; ParseNode *merge_when_list_node = NULL; ParseNode *when_node = NULL; ParseNode *then_node = NULL; ParseNode *divisor_node = NULL; div_node = NULL; if (OB_ISNULL(ratio_fun_node) || 2 != ratio_fun_node->num_child_ || OB_ISNULL(ratio_fun_node->children_[0]) || OB_ISNULL(ratio_fun_node->children_[1])) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ratio_fun_node)); } else if (OB_NOT_NULL(ratio_fun_node->children_[0]->children_[0]) || OB_ISNULL(ratio_fun_node->children_[0]->children_[1]) || OB_NOT_NULL(ratio_fun_node->children_[1]->children_[1]) || OB_NOT_NULL(ratio_fun_node->children_[1]->children_[2]) ) { ret = OB_ERR_INVALID_WINDOW_FUNC_USE; LOG_WARN("order by/frame clause not allowed for RATIO_TO_REPORT", K(ret)); //"the node", SJ(ObParserResultPrintWrapper(*ratio_fun_node))); } else { func_node = ratio_fun_node->children_[0]; const_cast(func_node)->type_ = T_FUN_SUM; //1, 构造when 0 then null的when_list if (OB_FAIL(ObRawExprUtils::new_parse_node(when_node, ctx_.expr_factory_, T_INT, 0)) || OB_FAIL(ObRawExprUtils::new_parse_node(then_node, ctx_.expr_factory_, T_NULL, 0))) { LOG_WARN("allocate when/then node failed", K(ret)); } else if (OB_FAIL(ObRawExprUtils::new_parse_node(when_list_node, ctx_.expr_factory_, T_WHEN, 2))) { LOG_WARN("allocate when list failed", K(ret)); } else if (OB_FAIL(ObRawExprUtils::new_parse_node(merge_when_list_node, ctx_.expr_factory_, T_WHEN_LIST, 1))) { LOG_WARN("allocate when list failed", K(ret)); } else if (OB_FAIL(ObRawExprUtils::new_parse_node(divisor_node, ctx_.expr_factory_, T_CASE, 3))) { LOG_WARN("allocate divisor failed", K(ret)); } else if (OB_FAIL(ObRawExprUtils::new_parse_node(div_node, ctx_.expr_factory_, T_OP_DIV, 2))) { LOG_WARN("allocate result node failed", K(ret)); } else { when_node->value_ = 0; when_list_node->children_[0] = when_node; when_list_node->children_[1] = then_node; merge_when_list_node->children_[0] = when_list_node; divisor_node->children_[0] = const_cast(ratio_fun_node); divisor_node->children_[1] = merge_when_list_node; divisor_node->children_[2] = const_cast(ratio_fun_node); div_node->children_[0] = func_node->children_[1]; div_node->children_[1] = divisor_node; } } return ret; } int ObRawExprResolverImpl::process_dll_udf_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; const share::schema::ObUDF *udf_info = nullptr; bool exist = false; ObString udf_name; ObCollationType cs_type; if (OB_ISNULL(ctx_.session_info_) || OB_ISNULL(ctx_.schema_checker_)) { //PL resolver don't have schema checker and session info ret = OB_ERR_FUNCTION_UNKNOWN; } else if (OB_ISNULL(node)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node)); } else if (OB_UNLIKELY(1 > node->num_child_) || OB_ISNULL(node->children_) || OB_ISNULL(node->children_[0])) { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("invalid node children for fun_sys node", K(ret), K(node->num_child_), "node", SJ(ObParserResultPrintWrapper(*node))); } else if (OB_FAIL(ctx_.session_info_->get_collation_connection(cs_type))) { LOG_WARN("failed to get collation", K(ret)); } else { ObString name(node->children_[0]->str_len_, node->children_[0]->str_value_); if (OB_FAIL(ob_write_string(ctx_.expr_factory_.get_allocator(), name, udf_name))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("Malloc function name failed", K(ret)); } else if (FALSE_IT(IGNORE_RETURN ObCharset::casedn(CS_TYPE_UTF8MB4_GENERAL_CI, udf_name))) { } else if (OB_FAIL(ctx_.schema_checker_->get_udf_info(ctx_.session_info_->get_effective_tenant_id(), udf_name, udf_info, exist))) { LOG_WARN("failed to resolve udf", K(ret)); } else if (!exist) { //we can not find this function in udf ret = OB_ERR_FUNCTION_UNKNOWN; //do not throw this error to user, just let it go. //the pl function will deal with it. } else if (OB_ISNULL(udf_info)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("the udf info is null", K(ret)); } else if (!(udf_info->is_normal_udf() || udf_info->is_agg_udf())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("the udf schame is error", K(ret), K(udf_info->get_type())); } else if (udf_info->is_normal_udf()) { ObSysFunRawExpr *func_expr = NULL; ObCharset::casedn(CS_TYPE_UTF8MB4_GENERAL_CI, udf_name); if (OB_FAIL(process_normal_udf_node(node, udf_name, *udf_info, func_expr))) { LOG_WARN("failed to process normal user define function", K(ret)); } else { expr = func_expr; } } else if (udf_info->is_agg_udf()) { ObAggFunRawExpr *func_expr = NULL; ObCharset::casedn(CS_TYPE_UTF8MB4_GENERAL_CI, udf_name); if (OB_FAIL(process_agg_udf_node(node, *udf_info, func_expr))) { LOG_WARN("failed to process agg user define function", K(ret)); } else { expr = func_expr; } } } return ret; } int ObRawExprResolverImpl::process_normal_udf_node(const ParseNode *node, const ObString &udf_name, const share::schema::ObUDF &udf_info, ObSysFunRawExpr *&expr) { int ret = OB_SUCCESS; ObNormalDllUdfRawExpr *func_expr = nullptr; if (OB_ISNULL(node)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("normal udf is null", K(ret), K(node)); } else if (node->num_child_ < 1) { ret = OB_ERR_UNEXPECTED; LOG_WARN("normal udf is null", K(ret), K(node->num_child_)); } else if (node->num_child_ > 1 &&(OB_ISNULL(node->children_) || OB_ISNULL(node->children_[1]) || OB_UNLIKELY(T_EXPR_LIST != node->children_[1]->type_))) { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("invalid node children", K(ret), K(node->children_)); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_FUN_NORMAL_UDF, func_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_FAIL(func_expr->set_udf_meta(udf_info))) { LOG_WARN("set udf info failed", K(ret)); } else { func_expr->set_func_name(udf_name); ObSEArray param_exprs; if (OB_FAIL(resolve_udf_param_expr(node, func_expr->get_param_exprs()))) { set_udf_param_syntax_err(true); LOG_WARN("failed to resolve udf param exprs", K(ret)); } } if (OB_SUCC(ret)) { ObSysFunRawExpr *tmp_expr = func_expr; if (OB_FAIL(ObRawExprUtils::function_alias(ctx_.expr_factory_, tmp_expr))) { LOG_WARN("failed to do funcion alias", K(ret), K(func_expr)); } else { expr = tmp_expr; } } return ret; } int ObRawExprResolverImpl::process_agg_udf_node(const ParseNode *node, const share::schema::ObUDF &udf_info, ObAggFunRawExpr *&expr) { int ret = OB_SUCCESS; ObAggFunRawExpr *agg_expr = nullptr; bool need_add_flag = !ctx_.parents_expr_info_.has_member(IS_AGG); if (need_add_flag && OB_FAIL(ctx_.parents_expr_info_.add_member(IS_AGG))) { LOG_WARN("failed to add member", K(ret)); } else if (OB_ISNULL(ctx_.aggr_exprs_) || OB_ISNULL(node)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("aggr exprs or node is null", K(ret), K(node)); } else if (node->num_child_ < 1) { ret = OB_ERR_UNEXPECTED; LOG_WARN("aggr exprs or node is null", K(ret), K(node->num_child_)); } else if (node->num_child_ > 1 && (OB_ISNULL(node->children_) || OB_ISNULL(node->children_[1]) || OB_UNLIKELY(T_EXPR_LIST != node->children_[1]->type_))) { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("invalid node children", K(ret), K(node->children_)); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_FUN_AGG_UDF, agg_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_FAIL(ctx_.aggr_exprs_->push_back(agg_expr))) { LOG_WARN("store aggr expr failed", K(ret)); } else if (OB_FAIL(agg_expr->set_udf_meta(udf_info))) { LOG_WARN("set udf info failed", K(ret)); } else { ObSEArray param_exprs; if (OB_FAIL(resolve_udf_param_expr(node, agg_expr->get_real_param_exprs_for_update()))) { LOG_WARN("failed to resolve udf param exprs", K(ret)); } } if (OB_SUCC(ret)) { // add invalid table bit index, avoid aggregate function expressions are used as filters if (OB_FAIL(agg_expr->get_relation_ids().add_member(0))) { LOG_WARN("failed to add member", K(ret)); } else if (need_add_flag && (ctx_.parents_expr_info_.del_member(IS_AGG))) { LOG_WARN("failed to del member", K(ret)); } else { expr = agg_expr; } } return ret; } int ObRawExprResolverImpl::resolve_udf_param_expr(const ParseNode *node, common::ObIArray ¶m_exprs) { int ret = OB_SUCCESS; ObRawExpr *param_expr = nullptr; // if the func do not have any param, without_param will be set to true. const bool without_param = node->num_child_ == 1; int32_t num = without_param ? 0 : node->children_[1]->num_child_; const ParseNode *child_node = without_param ? nullptr : node->children_[1]; for (int32_t i = 0; OB_SUCC(ret) && i < num; i++) { bool has_alias = false; const ParseNode *expr_parse_node = child_node->children_[i]; const ParseNode *expr_alias_node = nullptr; if (OB_ISNULL(expr_parse_node)) { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("parser error", K(ret)); } else if (expr_parse_node->type_ == T_EXPR_WITH_ALIAS) { if (expr_parse_node->num_child_ != 1 || OB_ISNULL(expr_parse_node->children_[0]) || expr_parse_node->children_[0]->type_ != T_ALIAS || expr_parse_node->children_[0]->num_child_ != 2 || OB_ISNULL(expr_parse_node->children_[0]->children_[0]) || OB_ISNULL(expr_parse_node->children_[0]->children_[1])) { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("parser error", K(ret)); } else { expr_alias_node = expr_parse_node->children_[0]->children_[1]; expr_parse_node = expr_parse_node->children_[0]->children_[0]; has_alias = true; } } if (OB_FAIL(ret)) { } else if (OB_FAIL(SMART_CALL(recursive_resolve(expr_parse_node, param_expr)))) { LOG_WARN("fail to recursive resolve", K(ret), K(expr_parse_node)); } else if (OB_FAIL(param_exprs.push_back(param_expr))) { LOG_WARN("fail to add param expr", K(ret), K(param_expr)); } else if (has_alias) { ObString alias_name(expr_alias_node->str_len_, expr_alias_node->str_value_); param_expr->set_alias_column_name(alias_name); } if (OB_SUCC(ret)) { ObString expr_name(expr_parse_node->str_len_, expr_parse_node->str_value_); if(OB_FAIL(param_expr->set_expr_name(expr_name))) { LOG_WARN("set expr name failed", K(ret)); } } } //end for return ret; } int ObRawExprResolverImpl::process_dml_event_node(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; ObSysFunRawExpr *f_expr = NULL; ObConstRawExpr *c_expr = NULL; ObRawExpr *col_expr = NULL; OV (OB_NOT_NULL(node), OB_INVALID_ARGUMENT); OV (OB_LIKELY(1 == node->num_child_)); if (OB_SUCC(ret)) { OZ (ctx_.expr_factory_.create_raw_expr(node->type_, f_expr)); OZ (ctx_.expr_factory_.create_raw_expr(T_INT, c_expr)); CK (OB_NOT_NULL(f_expr) && OB_NOT_NULL(c_expr)); if (OB_SUCC(ret)) { ObObjParam val; if (T_DML_EVENT_UPDATING == node->value_) { val.set_int(static_cast(ObDmlEventType::DE_UPDATING)); if (NULL != node->children_[0]) { OZ (SMART_CALL(recursive_resolve(node->children_[0], col_expr))); } } else { T_DML_EVENT_INSERTING == node->value_ ? val.set_int(static_cast(ObDmlEventType::DE_INSERTING)) : val.set_int(static_cast(ObDmlEventType::DE_DELETING)); } if (OB_SUCC(ret)) { val.set_param_meta(); c_expr->set_param(val); c_expr->set_value(val); } OZ (f_expr->add_param_expr(c_expr)); if (NULL != col_expr) { OZ (f_expr->add_param_expr(col_expr)); } OX (expr = f_expr); } } return ret; } int ObRawExprResolverImpl::process_internal_sys_function_node(const ParseNode *node, ObRawExpr *&expr, ObItemType node_type) { int ret = OB_SUCCESS; CK(2 == node->num_child_); CK(OB_NOT_NULL(node->children_)); CK(OB_NOT_NULL(node->children_[0]) && OB_NOT_NULL(node->children_[1])); ObSysFunRawExpr *func_expr = NULL; ObString func_name; if (OB_ISNULL(node) || OB_ISNULL(ctx_.session_info_)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node), KP(ctx_.session_info_)); } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(node_type, func_expr))) { LOG_WARN("fail to create raw expr", K(ret)); } else if (OB_ISNULL(func_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("func_expr is null"); } else { ObString name(node->children_[0]->str_len_, node->children_[0]->str_value_); if (OB_FAIL(ret)) { /*^-^*/ } else if (OB_FAIL(ob_write_string(ctx_.expr_factory_.get_allocator(), name, func_name))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("Malloc function name failed", K(ret)); } } if (OB_SUCC(ret)) { func_expr->set_func_name(func_name); if (OB_ISNULL(node->children_) || OB_ISNULL(node->children_[1]) || OB_UNLIKELY(T_EXPR_LIST != node->children_[1]->type_)) { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("invalid node children", K(ret), K(node->children_)); } else { ObRawExpr *para_expr = NULL; int32_t num = node->children_[1]->num_child_; for (int32_t i = 0; OB_SUCC(ret) && i < num; i++) { if (OB_ISNULL(node->children_[1]->children_[i])) { ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("invalid parse tree", K(ret)); } else if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[1]->children_[i], para_expr)))) { LOG_WARN("fail to recursive resolve", K(ret), K(node->children_[1]->children_[i])); } else if (OB_FAIL(func_expr->add_param_expr(para_expr))) { LOG_WARN("fail to add param expr", K(ret), K(para_expr)); } } //end for OX (expr = func_expr); } } return ret; } int ObRawExprResolverImpl::check_internal_function(const ObString &name) { int ret = OB_SUCCESS; CK (OB_NOT_NULL(ctx_.session_info_)); bool exist = false; bool is_internal = false; if (OB_FAIL(ret)) { } else if (ctx_.session_info_->is_inner()) { // ignore } else if (FALSE_IT(ObExprOperatorFactory::get_internal_info_by_name(name, exist, is_internal))) { } else if (exist && is_internal) { if (lib::is_mysql_mode()) { ret = OB_ERR_SP_DOES_NOT_EXIST; LOG_USER_ERROR(OB_ERR_SP_DOES_NOT_EXIST, "FUNCTION", ctx_.session_info_->get_database_name().length(), ctx_.session_info_->get_database_name().ptr(), name.length(), name.ptr()); } else { ret = OB_ERR_KEY_COLUMN_DOES_NOT_EXITS; LOG_USER_ERROR(OB_ERR_KEY_COLUMN_DOES_NOT_EXITS, name.length(), name.ptr()); } } return ret; } int ObRawExprResolverImpl::process_odbc_escape_sequences(const ParseNode *node, ObRawExpr *&expr) { int ret = OB_SUCCESS; const ParseNode *action_node = NULL; const ParseNode *expr_node = NULL; expr = NULL; if (OB_ISNULL(node) || OB_UNLIKELY(node->num_child_ != 2) || OB_ISNULL(action_node = node->children_[0]) || OB_ISNULL(expr_node = node->children_[1]) || OB_UNLIKELY(T_IDENT != action_node->type_ || action_node->str_value_ == NULL || action_node->str_len_ <= 0)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected error", K(ret), K(node), K(action_node), K(expr_node)); } else { ObString action_str = ObString(action_node->str_len_, action_node->str_value_); if (0 == action_str.case_compare("d") || 0 == action_str.case_compare("t") || 0 == action_str.case_compare("ts")) {//Date/Time/TimeStamp Type, Try to convert ObItemType dst_time_type = (0 == action_str.case_compare("d") ? T_DATE : (0 == action_str.case_compare("t") ? T_TIME : T_TIMESTAMP)); if (OB_FAIL(process_odbc_time_literals(dst_time_type, expr_node, expr))) { LOG_WARN("failed to process odbc time literals", K(ret)); } else {/*do nothing*/} //fn scalar function action and other invalid action, just ignore action } else if (OB_FAIL(SMART_CALL(recursive_resolve(expr_node, expr)))) { LOG_WARN("failed to recursive resolve", K(ret)); } } return ret; } int ObRawExprResolverImpl::process_odbc_time_literals(const ObItemType dst_time_type, const ParseNode *expr_node, ObRawExpr *&expr) { int ret = OB_SUCCESS; expr = NULL; bool is_valid_time_str = false; if (OB_ISNULL(expr_node)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret), K(expr_node)); } else if (T_VARCHAR != expr_node->type_ && T_QUESTIONMARK != expr_node->type_) { //do nothing } else { ObString time_str; if (T_VARCHAR == expr_node->type_) { is_valid_time_str = true; time_str.assign_ptr(expr_node->str_value_, static_cast(expr_node->str_len_)); } else if (OB_ISNULL(ctx_.param_list_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("param_list_ is null", K(ret), K(ctx_.param_list_)); } else if (ctx_.param_list_->count() == 0) { //prepare phase of ps protocol, do nothing } else if (OB_UNLIKELY(expr_node->value_ < 0 || expr_node->value_ >= ctx_.param_list_->count())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("index is out of range", K(expr_node->value_), K(ctx_.param_list_->count())); } else if (!ctx_.param_list_->at(expr_node->value_).is_varchar()) { //do nothing } else { is_valid_time_str = true; time_str = ctx_.param_list_->at(expr_node->value_).get_varchar(); } if (OB_SUCC(ret) && is_valid_time_str) { ParseNode tmp_node; tmp_node.type_ = dst_time_type; tmp_node.num_child_ = 0; tmp_node.str_len_ = time_str.length(); tmp_node.str_value_ = time_str.ptr(); tmp_node.is_date_unit_ = false; if (OB_FAIL(process_datatype_or_questionmark(tmp_node, expr))) { if (ret == OB_ERR_WRONG_VALUE) {//invalid time str, go back default way like Mysql. ret = OB_SUCCESS; is_valid_time_str = false; LOG_TRACE("is invalid time string", K(time_str)); } else { LOG_WARN("fail to process datatype or questionmark", K(ret)); } } else if (T_QUESTIONMARK == expr_node->type_) {//questionmark need add const constaint. ObPCConstParamInfo const_param_info; if (OB_ISNULL(ctx_.query_ctx_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("query context have not been initialized.", K(ret)); } else if (OB_FAIL(const_param_info.const_idx_.push_back(expr_node->value_))) { LOG_WARN("failed to push back param idx", K(ret)); } else if (OB_FAIL(const_param_info.const_params_.push_back(ctx_.param_list_->at(expr_node->value_)))) { LOG_WARN("failed to push back value", K(ret)); } else if (OB_FAIL(ctx_.query_ctx_->all_plan_const_param_constraints_.push_back(const_param_info))) { LOG_WARN("failed to push back const param info", K(ret)); } else {/* do nothing */} } } } if (OB_SUCC(ret) && !is_valid_time_str) { if (OB_FAIL(SMART_CALL(recursive_resolve(expr_node, expr)))) { LOG_WARN("failed to recursive resolve", K(ret)); } } return ret; } } //namespace sql } //namespace oceabase