fix nullif/least calc_resultN bug in static engine
This commit is contained in:
		| @ -972,47 +972,21 @@ int ObStaticEngineExprCG::add_so_check_expr_above(ObIArray<ObExpr>& exprs, ObExp | |||||||
|   return ret; |   return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
| int ObStaticEngineExprCG::replace_var_rt_expr(ObExpr* origin_expr, const ObRawExpr *origin_raw_expr, | int ObStaticEngineExprCG::replace_var_rt_expr(ObExpr* origin_expr, | ||||||
|     ObExpr* var_expr, ObExpr* parent_expr, int32_t var_idx)  // child pos of parent_expr |     ObExpr* var_expr, ObExpr* parent_expr, int32_t var_idx)  // child pos of parent_expr | ||||||
| { | { | ||||||
|   int ret = OB_SUCCESS; |   int ret = OB_SUCCESS; | ||||||
|   if (OB_ISNULL(origin_expr)) { |   if (OB_ISNULL(origin_expr)) { | ||||||
|     ret = OB_ERR_UNEXPECTED; |     ret = OB_ERR_UNEXPECTED; | ||||||
|     LOG_WARN("expr is null", K(ret), K(origin_expr)); |     LOG_WARN("expr is null", K(ret), K(origin_expr)); | ||||||
|   } else { |  | ||||||
|     while (OB_SUCC(ret)) { |  | ||||||
|       if (OB_ISNULL(origin_raw_expr)) { |  | ||||||
|         ret = OB_ERR_UNEXPECTED; |  | ||||||
|         LOG_WARN("origin raw expr is null", K(ret)); |  | ||||||
|         // from_unixtime may add implicit cast above origin param expr, find origin param. |  | ||||||
|       } else if (T_FUN_SYS_CAST == origin_expr->type_ |  | ||||||
|                  && CM_IS_IMPLICIT_CAST(origin_raw_expr->get_extra())) { |  | ||||||
|         if (OB_UNLIKELY(origin_expr->arg_cnt_ < 1) || OB_ISNULL(origin_expr->args_[0])) { |  | ||||||
|           ret = OB_ERR_UNEXPECTED; |  | ||||||
|           LOG_WARN("invalid param", KPC(origin_expr)); |  | ||||||
|         } else { |  | ||||||
|           origin_expr = origin_expr->args_[0]; |  | ||||||
|           origin_raw_expr = origin_raw_expr->get_param_expr(0); |  | ||||||
|         } |  | ||||||
|       } else if (T_FUN_ENUM_TO_STR == origin_expr->type_ || T_FUN_SET_TO_STR == origin_expr->type_) { |  | ||||||
|         if (OB_UNLIKELY(origin_expr->arg_cnt_ < 2) || OB_ISNULL(origin_expr->args_[1])) { |  | ||||||
|           ret = OB_ERR_UNEXPECTED; |  | ||||||
|           LOG_WARN("invalid param", K(ret), KPC(origin_expr)); |  | ||||||
|         } else { |  | ||||||
|           origin_expr = origin_expr->args_[1]; |  | ||||||
|           origin_raw_expr = origin_raw_expr->get_param_expr(1); |  | ||||||
|         } |  | ||||||
|       } else { |  | ||||||
|         break; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (OB_FAIL(ret)) { |  | ||||||
|   } else if (T_EXEC_VAR == var_expr->type_) { |   } else if (T_EXEC_VAR == var_expr->type_) { | ||||||
|     if (OB_ISNULL(parent_expr) || OB_UNLIKELY(parent_expr->arg_cnt_ < var_idx + 1)) { |     if (OB_ISNULL(parent_expr) || OB_UNLIKELY(parent_expr->arg_cnt_ < var_idx + 1)) { | ||||||
|       ret = OB_ERR_UNEXPECTED; |       ret = OB_ERR_UNEXPECTED; | ||||||
|       LOG_WARN("invalid param", KPC(parent_expr)); |       LOG_WARN("invalid param", KPC(parent_expr)); | ||||||
|  | 	  } else if (OB_UNLIKELY(var_expr->datum_meta_.type_ != origin_expr->datum_meta_.type_ | ||||||
|  |                 || var_expr->datum_meta_.cs_type_ != origin_expr->datum_meta_.cs_type_)) { | ||||||
|  |       ret = OB_ERR_UNEXPECTED; | ||||||
|  |       LOG_WARN("exec var meta diff from origin expr meta", K(ret), KPC(origin_expr), KPC(var_expr)); | ||||||
|     } else { |     } else { | ||||||
|       parent_expr->args_[var_idx] = origin_expr; |       parent_expr->args_[var_idx] = origin_expr; | ||||||
|     } |     } | ||||||
| @ -1022,13 +996,15 @@ int ObStaticEngineExprCG::replace_var_rt_expr(ObExpr* origin_expr, const ObRawEx | |||||||
|       // May two exprs above ObVarRawExpr: |       // May two exprs above ObVarRawExpr: | ||||||
|       // 1. implicit cast add in type deduce |       // 1. implicit cast add in type deduce | ||||||
|       // 2. ENUM_TO_STR/SET_TO_STR for enum/set |       // 2. ENUM_TO_STR/SET_TO_STR for enum/set | ||||||
|       if (T_FUN_ENUM_TO_STR == parent_expr->type_ || T_FUN_SET_TO_STR == parent_expr->type_) { | 	    if (T_FUN_ENUM_TO_STR == parent_expr->type_ | ||||||
|  |           || T_FUN_SET_TO_STR == parent_expr->type_ | ||||||
|  |           || T_FUN_ENUM_TO_INNER_TYPE == parent_expr->type_ | ||||||
|  |           || T_FUN_SET_TO_INNER_TYPE == parent_expr->type_) { | ||||||
|         var_idx = 1; |         var_idx = 1; | ||||||
|       } else if (T_FUN_SYS_CAST == parent_expr->type_) { |       } else if (T_FUN_SYS_CAST == parent_expr->type_) { | ||||||
|         var_idx = 0; |         var_idx = 0; | ||||||
|       } else { |       } else { | ||||||
|         ret = OB_ERR_UNEXPECTED; |         break; | ||||||
|         LOG_WARN("unexpected expr added above var expr", K(ret), K(parent_expr->type_)); |  | ||||||
|       } |       } | ||||||
|       if (OB_FAIL(ret)) { |       if (OB_FAIL(ret)) { | ||||||
|       } else if (OB_UNLIKELY(parent_expr->arg_cnt_ < var_idx + 1) || |       } else if (OB_UNLIKELY(parent_expr->arg_cnt_ < var_idx + 1) || | ||||||
| @ -1036,7 +1012,13 @@ int ObStaticEngineExprCG::replace_var_rt_expr(ObExpr* origin_expr, const ObRawEx | |||||||
|         ret = OB_ERR_UNEXPECTED; |         ret = OB_ERR_UNEXPECTED; | ||||||
|         LOG_WARN("expr is null", K(ret), KPC(parent_expr)); |         LOG_WARN("expr is null", K(ret), KPC(parent_expr)); | ||||||
|       } else if (T_EXEC_VAR == var_expr->type_) { |       } else if (T_EXEC_VAR == var_expr->type_) { | ||||||
|         parent_expr->args_[var_idx] = origin_expr; | 		    if (OB_UNLIKELY(var_expr->datum_meta_.type_ != origin_expr->datum_meta_.type_ | ||||||
|  |                 || var_expr->datum_meta_.cs_type_ != origin_expr->datum_meta_.cs_type_)) { | ||||||
|  |           ret = OB_ERR_UNEXPECTED; | ||||||
|  |           LOG_WARN("exec var meta diff from origin expr meta", K(ret), KPC(origin_expr), KPC(var_expr)); | ||||||
|  |         } else { | ||||||
|  |           parent_expr->args_[var_idx] = origin_expr; | ||||||
|  |         } | ||||||
|         break; |         break; | ||||||
|       } else { |       } else { | ||||||
|         parent_expr = var_expr; |         parent_expr = var_expr; | ||||||
|  | |||||||
| @ -63,7 +63,7 @@ public: | |||||||
|  |  | ||||||
|   static int generate_rt_expr(const ObRawExpr& src, common::ObIArray<ObRawExpr*>& exprs, ObExpr*& dst); |   static int generate_rt_expr(const ObRawExpr& src, common::ObIArray<ObRawExpr*>& exprs, ObExpr*& dst); | ||||||
|  |  | ||||||
|   static int replace_var_rt_expr(ObExpr* origin_expr, const ObRawExpr *origin_raw_expr, ObExpr* var_expr, |   static int replace_var_rt_expr(ObExpr* origin_expr, ObExpr* var_expr, | ||||||
|       ObExpr* parent_expr, int32_t var_idx); |       ObExpr* parent_expr, int32_t var_idx); | ||||||
|  |  | ||||||
|   // Attention : Please think over before you have to use this function. |   // Attention : Please think over before you have to use this function. | ||||||
|  | |||||||
| @ -212,9 +212,6 @@ int ObExprFromUnixTime::cg_expr(ObExprCGCtx& op_cg_ctx, const ObRawExpr& raw_exp | |||||||
|     if (OB_ISNULL(rt_expr.args_[0]) || OB_ISNULL(rt_expr.args_[1]) || OB_ISNULL(rt_expr.args_[2])) { |     if (OB_ISNULL(rt_expr.args_[0]) || OB_ISNULL(rt_expr.args_[1]) || OB_ISNULL(rt_expr.args_[2])) { | ||||||
|       ret = OB_INVALID_ARGUMENT; |       ret = OB_INVALID_ARGUMENT; | ||||||
|       LOG_WARN("invalid null args", K(ret), K(rt_expr.args_[0]), K(rt_expr.args_[1]), K(rt_expr.args_[2])); |       LOG_WARN("invalid null args", K(ret), K(rt_expr.args_[0]), K(rt_expr.args_[1]), K(rt_expr.args_[2])); | ||||||
|     } else if (OB_FAIL(ObStaticEngineExprCG::replace_var_rt_expr(rt_expr.args_[1], raw_expr.get_param_expr(1), |  | ||||||
|           rt_expr.args_[2], &rt_expr, 2))) { |  | ||||||
|       LOG_WARN("replace var rt expr failed", K(ret), K(rt_expr)); |  | ||||||
|     } else if (ob_is_string_tc(rt_expr.args_[2]->datum_meta_.type_)) { |     } else if (ob_is_string_tc(rt_expr.args_[2]->datum_meta_.type_)) { | ||||||
|       rt_expr.eval_func_ = &eval_fromtime_normal; |       rt_expr.eval_func_ = &eval_fromtime_normal; | ||||||
|     } else { |     } else { | ||||||
|  | |||||||
| @ -47,13 +47,7 @@ int ObExprBaseGreatest::calc_result_typeN( | |||||||
| int ObExprBaseGreatest::calc_resultN( | int ObExprBaseGreatest::calc_resultN( | ||||||
|     ObObj& result, const ObObj* objs_stack, int64_t param_num, ObExprCtx& expr_ctx) const |     ObObj& result, const ObObj* objs_stack, int64_t param_num, ObExprCtx& expr_ctx) const | ||||||
| { | { | ||||||
|   return ObMinMaxExprOperator::calc_(result, objs_stack, param_num, result_type_, expr_ctx, CO_GT, need_cast_); |   return ObMinMaxExprOperator::calc_(result, objs_stack, param_num, result_type_, expr_ctx, CO_GT, need_cast_, get_type()); | ||||||
| } |  | ||||||
|  |  | ||||||
| int ObExprBaseGreatest::calc( |  | ||||||
|     ObObj& result, const ObObj* objs_stack, int64_t param_num, const ObExprResType& result_type, ObExprCtx& expr_ctx) |  | ||||||
| { |  | ||||||
|   return ObMinMaxExprOperator::calc_(result, objs_stack, param_num, result_type, expr_ctx, CO_GT, true); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| ObExprGreatestMySQL::ObExprGreatestMySQL(ObIAllocator& alloc) : ObExprBaseGreatest(alloc, MORE_THAN_ONE) | ObExprGreatestMySQL::ObExprGreatestMySQL(ObIAllocator& alloc) : ObExprBaseGreatest(alloc, MORE_THAN_ONE) | ||||||
| @ -124,11 +118,11 @@ int ObExprBaseGreatest::cg_expr(ObExprCGCtx& op_cg_ctx, const ObRawExpr& raw_exp | |||||||
|       const uint32_t real_param_num = param_num / 3; |       const uint32_t real_param_num = param_num / 3; | ||||||
|       for (int64_t i = 0; OB_SUCC(ret) && i < real_param_num; i++) { |       for (int64_t i = 0; OB_SUCC(ret) && i < real_param_num; i++) { | ||||||
|         if (OB_FAIL(ObStaticEngineExprCG::replace_var_rt_expr( |         if (OB_FAIL(ObStaticEngineExprCG::replace_var_rt_expr( | ||||||
|                 rt_expr.args_[i], raw_expr.get_param_expr(i), rt_expr.args_[i + real_param_num], |                 rt_expr.args_[i], rt_expr.args_[i + real_param_num], | ||||||
|                 &rt_expr, i + real_param_num))) { |                 &rt_expr, i + real_param_num))) { | ||||||
|           LOG_WARN("replace var rt expr failed", K(ret)); |           LOG_WARN("replace var rt expr failed", K(ret)); | ||||||
|       } else if (OB_FAIL(ObStaticEngineExprCG::replace_var_rt_expr( |       } else if (OB_FAIL(ObStaticEngineExprCG::replace_var_rt_expr( | ||||||
|                        rt_expr.args_[i], raw_expr.get_param_expr(i), rt_expr.args_[i + 2 * real_param_num], |                        rt_expr.args_[i], rt_expr.args_[i + 2 * real_param_num], | ||||||
|                        &rt_expr, i + 2 * real_param_num))) { |                        &rt_expr, i + 2 * real_param_num))) { | ||||||
|           LOG_WARN("replace var rt expr failed", K(ret)); |           LOG_WARN("replace var rt expr failed", K(ret)); | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -27,8 +27,6 @@ public: | |||||||
|       ObExprResType& type, ObExprResType* types_stack, int64_t param_num, common::ObExprTypeCtx& type_ctx) const; |       ObExprResType& type, ObExprResType* types_stack, int64_t param_num, common::ObExprTypeCtx& type_ctx) const; | ||||||
|   virtual int calc_resultN( |   virtual int calc_resultN( | ||||||
|       common::ObObj& result, const common::ObObj* objs_stack, int64_t param_num, common::ObExprCtx& expr_ctx) const; |       common::ObObj& result, const common::ObObj* objs_stack, int64_t param_num, common::ObExprCtx& expr_ctx) const; | ||||||
|   static int calc(common::ObObj& result, const common::ObObj* objs_stack, int64_t param_num, |  | ||||||
|       const ObExprResType& expected_type, common::ObExprCtx& expr_ctx); |  | ||||||
|   virtual int cg_expr(ObExprCGCtx& op_cg_ctx, const ObRawExpr& raw_expr, ObExpr& rt_expr) const override; |   virtual int cg_expr(ObExprCGCtx& op_cg_ctx, const ObRawExpr& raw_expr, ObExpr& rt_expr) const override; | ||||||
|   static int calc_greatest(const ObExpr& expr, ObEvalCtx& ctx, ObDatum& expr_datum); |   static int calc_greatest(const ObExpr& expr, ObEvalCtx& ctx, ObDatum& expr_datum); | ||||||
|  |  | ||||||
|  | |||||||
| @ -150,6 +150,10 @@ int ObExprBaseLeastGreatest::calc_result_typeN_mysql( | |||||||
|     if (OB_FAIL(calc_result_meta_for_comparison( |     if (OB_FAIL(calc_result_meta_for_comparison( | ||||||
|             type, types, real_param_num, type_ctx.get_coll_type(), default_length_semantics))) { |             type, types, real_param_num, type_ctx.get_coll_type(), default_length_semantics))) { | ||||||
|       LOG_WARN("calc result meta for comparison failed"); |       LOG_WARN("calc result meta for comparison failed"); | ||||||
|  |     } | ||||||
|  | 		// can't cast origin parameters. | ||||||
|  |     for (int64_t i = 0; i < real_param_num; i++) { | ||||||
|  |       types[i].set_calc_meta(types[i].get_obj_meta()); | ||||||
|     } |     } | ||||||
|     if (!all_integer || !type.is_integer_type()) { |     if (!all_integer || !type.is_integer_type()) { | ||||||
|       // compatible with MySQL. compare type and result type may be different. |       // compatible with MySQL. compare type and result type may be different. | ||||||
| @ -284,13 +288,7 @@ int ObExprBaseLeast::calc_result_typeN( | |||||||
|  |  | ||||||
| int ObExprBaseLeast::calc_resultN(ObObj& result, const ObObj* objs_stack, int64_t param_num, ObExprCtx& expr_ctx) const | int ObExprBaseLeast::calc_resultN(ObObj& result, const ObObj* objs_stack, int64_t param_num, ObExprCtx& expr_ctx) const | ||||||
| { | { | ||||||
|   return ObMinMaxExprOperator::calc_(result, objs_stack, param_num, result_type_, expr_ctx, CO_LT, need_cast_); |   return ObMinMaxExprOperator::calc_(result, objs_stack, param_num, result_type_, expr_ctx, CO_LT, need_cast_, get_type()); | ||||||
| } |  | ||||||
|  |  | ||||||
| int ObExprBaseLeast::calc( |  | ||||||
|     ObObj& result, const ObObj* objs_stack, int64_t param_num, const ObExprResType& expected_type, ObExprCtx& expr_ctx) |  | ||||||
| { |  | ||||||
|   return ObMinMaxExprOperator::calc_(result, objs_stack, param_num, expected_type, expr_ctx, CO_LT, true); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| ObExprLeastMySQL::ObExprLeastMySQL(ObIAllocator& alloc) : ObExprBaseLeast(alloc, MORE_THAN_ONE) | ObExprLeastMySQL::ObExprLeastMySQL(ObIAllocator& alloc) : ObExprBaseLeast(alloc, MORE_THAN_ONE) | ||||||
| @ -350,10 +348,10 @@ int ObExprBaseLeast::cg_expr(ObExprCGCtx& op_cg_ctx, const ObRawExpr& raw_expr, | |||||||
|       const uint32_t real_param_num = param_num / 3; |       const uint32_t real_param_num = param_num / 3; | ||||||
|       for (int64_t i = 0; OB_SUCC(ret) && i < real_param_num; i++) { |       for (int64_t i = 0; OB_SUCC(ret) && i < real_param_num; i++) { | ||||||
|         if (OB_FAIL(ObStaticEngineExprCG::replace_var_rt_expr( |         if (OB_FAIL(ObStaticEngineExprCG::replace_var_rt_expr( | ||||||
|                 rt_expr.args_[i], raw_expr.get_param_expr(i), rt_expr.args_[i + real_param_num], &rt_expr, i + real_param_num))) { |                 rt_expr.args_[i], rt_expr.args_[i + real_param_num], &rt_expr, i + real_param_num))) { | ||||||
|           LOG_WARN("replace var rt expr failed", K(ret)); |           LOG_WARN("replace var rt expr failed", K(ret)); | ||||||
|         } else if (OB_FAIL(ObStaticEngineExprCG::replace_var_rt_expr( |         } else if (OB_FAIL(ObStaticEngineExprCG::replace_var_rt_expr( | ||||||
|                        rt_expr.args_[i], raw_expr.get_param_expr(i), rt_expr.args_[i + 2 * real_param_num], &rt_expr, i + 2 * real_param_num))) { |                        rt_expr.args_[i], rt_expr.args_[i + 2 * real_param_num], &rt_expr, i + 2 * real_param_num))) { | ||||||
|           LOG_WARN("replace var rt expr failed", K(ret)); |           LOG_WARN("replace var rt expr failed", K(ret)); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|  | |||||||
| @ -64,8 +64,6 @@ public: | |||||||
|       ObExprResType& type, ObExprResType* types_stack, int64_t param_num, common::ObExprTypeCtx& type_ctx) const override; |       ObExprResType& type, ObExprResType* types_stack, int64_t param_num, common::ObExprTypeCtx& type_ctx) const override; | ||||||
|   virtual int calc_resultN( |   virtual int calc_resultN( | ||||||
|       common::ObObj& result, const common::ObObj* objs_stack, int64_t param_num, common::ObExprCtx& expr_ctx) const override; |       common::ObObj& result, const common::ObObj* objs_stack, int64_t param_num, common::ObExprCtx& expr_ctx) const override; | ||||||
|   static int calc(common::ObObj& result, const common::ObObj* objs_stack, int64_t param_num, |  | ||||||
|       const ObExprResType& expected_type, common::ObExprCtx& expr_ctx); |  | ||||||
|   virtual int cg_expr(ObExprCGCtx& op_cg_ctx, const ObRawExpr& raw_expr, ObExpr& rt_expr) const override; |   virtual int cg_expr(ObExprCGCtx& op_cg_ctx, const ObRawExpr& raw_expr, ObExpr& rt_expr) const override; | ||||||
|   static int calc_least(const ObExpr& expr, ObEvalCtx& ctx, ObDatum& expr_datum); |   static int calc_least(const ObExpr& expr, ObEvalCtx& ctx, ObDatum& expr_datum); | ||||||
|  |  | ||||||
|  | |||||||
| @ -149,7 +149,7 @@ int ObExprNullif::calc_resultN(ObObj& result, const ObObj* objs_stack, int64_t p | |||||||
|   EXPR_DEFINE_CMP_CTX(result_type_.get_calc_meta(), true, expr_ctx); |   EXPR_DEFINE_CMP_CTX(result_type_.get_calc_meta(), true, expr_ctx); | ||||||
|   EXPR_DEFINE_CAST_CTX(expr_ctx, CM_NONE); |   EXPR_DEFINE_CAST_CTX(expr_ctx, CM_NONE); | ||||||
|   ObObj cmp; |   ObObj cmp; | ||||||
|   if (OB_UNLIKELY(2 != param_num) || OB_ISNULL(objs_stack)) { |   if (OB_UNLIKELY(2 != param_num && 6 != param_num) || OB_ISNULL(objs_stack)) { | ||||||
|     ret = OB_INVALID_ARGUMENT; |     ret = OB_INVALID_ARGUMENT; | ||||||
|     LOG_WARN("invalid argument", K(ret), K(param_num), K(objs_stack)); |     LOG_WARN("invalid argument", K(ret), K(param_num), K(objs_stack)); | ||||||
|   } else { |   } else { | ||||||
| @ -229,10 +229,10 @@ int ObExprNullif::cg_expr(ObExprCGCtx& expr_cg_ctx, const ObRawExpr& raw_expr, O | |||||||
|   const uint32_t real_param_num = param_num / 3; |   const uint32_t real_param_num = param_num / 3; | ||||||
|   for (int64_t i = 0; OB_SUCC(ret) && i < real_param_num; i++) { |   for (int64_t i = 0; OB_SUCC(ret) && i < real_param_num; i++) { | ||||||
|     if (OB_FAIL(ObStaticEngineExprCG::replace_var_rt_expr( |     if (OB_FAIL(ObStaticEngineExprCG::replace_var_rt_expr( | ||||||
|             rt_expr.args_[i], raw_expr.get_param_expr(i), rt_expr.args_[i + real_param_num], &rt_expr, i + real_param_num))) { |             rt_expr.args_[i], rt_expr.args_[i + real_param_num], &rt_expr, i + real_param_num))) { | ||||||
|       LOG_WARN("replace var rt expr failed", K(ret)); |       LOG_WARN("replace var rt expr failed", K(ret)); | ||||||
|     } else if (OB_FAIL(ObStaticEngineExprCG::replace_var_rt_expr( |     } else if (OB_FAIL(ObStaticEngineExprCG::replace_var_rt_expr( | ||||||
|                    rt_expr.args_[i], raw_expr.get_param_expr(i), rt_expr.args_[i + 2 * real_param_num], &rt_expr, i + 2 * real_param_num))) { |                    rt_expr.args_[i], rt_expr.args_[i + 2 * real_param_num], &rt_expr, i + 2 * real_param_num))) { | ||||||
|       LOG_WARN("replace var rt expr failed", K(ret)); |       LOG_WARN("replace var rt expr failed", K(ret)); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -3812,13 +3812,22 @@ int ObMinMaxExprOperator::calc_result_meta_for_comparison(ObExprResType& type, O | |||||||
| } | } | ||||||
|  |  | ||||||
| int ObMinMaxExprOperator::calc_(ObObj& result, const ObObj* objs_stack, int64_t param_num, | int ObMinMaxExprOperator::calc_(ObObj& result, const ObObj* objs_stack, int64_t param_num, | ||||||
|     const ObExprResType& result_type, ObExprCtx& expr_ctx, ObCmpOp cmp_op, bool need_cast) |     const ObExprResType& result_type, ObExprCtx& expr_ctx, ObCmpOp cmp_op, bool need_cast, ObExprOperatorType expr_type) | ||||||
| { | { | ||||||
|   // todo: |   // todo: | ||||||
|   // we assume that result type / result collation / compare type / compare collation are CORRECT. |   // we assume that result type / result collation / compare type / compare collation are CORRECT. | ||||||
|   // but who knowns? we should check it ASAP. |   // but who knowns? we should check it ASAP. | ||||||
|   int ret = OB_SUCCESS; |   int ret = OB_SUCCESS; | ||||||
|   if (OB_UNLIKELY(need_cast)) { |   if (T_FUN_SYS_LEAST_INNER == expr_type || T_FUN_SYS_GREATEST_INNER == expr_type) { | ||||||
|  |     if (0 != param_num % 3) { | ||||||
|  |       ret = OB_ERR_UNEXPECTED; | ||||||
|  |       LOG_WARN("unexpected param num", K(ret), K(param_num)); | ||||||
|  |     } else { | ||||||
|  |       param_num = param_num / 3; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   if (OB_FAIL(ret)) { | ||||||
|  |   } else if (OB_UNLIKELY(need_cast)) { | ||||||
|     ret = calc_with_cast(result, objs_stack, param_num, result_type, expr_ctx, cmp_op); |     ret = calc_with_cast(result, objs_stack, param_num, result_type, expr_ctx, cmp_op); | ||||||
|   } else { |   } else { | ||||||
|     ret = calc_without_cast(result, objs_stack, param_num, result_type, expr_ctx, cmp_op); |     ret = calc_without_cast(result, objs_stack, param_num, result_type, expr_ctx, cmp_op); | ||||||
|  | |||||||
| @ -1554,7 +1554,8 @@ protected: | |||||||
|   // least should set cmp_op to CO_LT. |   // least should set cmp_op to CO_LT. | ||||||
|   // greatest should set cmp_op to CO_GT. |   // greatest should set cmp_op to CO_GT. | ||||||
|   static int calc_(common::ObObj& result, const common::ObObj* objs_stack, int64_t param_num, |   static int calc_(common::ObObj& result, const common::ObObj* objs_stack, int64_t param_num, | ||||||
|       const ObExprResType& result_type, common::ObExprCtx& expr_ctx, common::ObCmpOp cmp_op, bool need_cast); |       const ObExprResType& result_type, common::ObExprCtx& expr_ctx, common::ObCmpOp cmp_op, bool need_cast, | ||||||
|  |       ObExprOperatorType expr_type); | ||||||
|   OB_INLINE static int calc_without_cast(common::ObObj& result, const common::ObObj* objs_stack, int64_t param_num, |   OB_INLINE static int calc_without_cast(common::ObObj& result, const common::ObObj* objs_stack, int64_t param_num, | ||||||
|       const ObExprResType& result_type, common::ObExprCtx& expr_ctx, common::ObCmpOp cmp_op); |       const ObExprResType& result_type, common::ObExprCtx& expr_ctx, common::ObCmpOp cmp_op); | ||||||
|   OB_INLINE static int calc_with_cast(common::ObObj& result, const common::ObObj* objs_stack, int64_t param_num, |   OB_INLINE static int calc_with_cast(common::ObObj& result, const common::ObObj* objs_stack, int64_t param_num, | ||||||
|  | |||||||
| @ -767,14 +767,16 @@ int ObRawExprWrapEnumSet::wrap_nullif_expr(ObSysFunRawExpr& expr) | |||||||
|   int ret = OB_SUCCESS; |   int ret = OB_SUCCESS; | ||||||
|   int64_t param_count = expr.get_param_count(); |   int64_t param_count = expr.get_param_count(); | ||||||
|   int64_t input_types_count = expr.get_input_types().count(); |   int64_t input_types_count = expr.get_input_types().count(); | ||||||
|  |   bool param_copied = false; | ||||||
|   if (OB_UNLIKELY(OB_ISNULL(my_session_))) { |   if (OB_UNLIKELY(OB_ISNULL(my_session_))) { | ||||||
|     ret = OB_NOT_INIT; |     ret = OB_NOT_INIT; | ||||||
|     LOG_WARN("session is null", K(ret)); |     LOG_WARN("session is null", K(ret)); | ||||||
|   } else if (OB_UNLIKELY(T_FUN_SYS_NULLIF != expr.get_expr_type())) { |   } else if (OB_UNLIKELY(T_FUN_SYS_NULLIF != expr.get_expr_type())) { | ||||||
|     ret = OB_INVALID_ARGUMENT; |     ret = OB_INVALID_ARGUMENT; | ||||||
|     LOG_WARN("invalid argument", K(expr), K(ret)); |     LOG_WARN("invalid argument", K(expr), K(ret)); | ||||||
|   } else if (OB_UNLIKELY((my_session_->use_static_typing_engine() && 6 != param_count) || | 	} else if (FALSE_IT(param_copied = my_session_->use_static_typing_engine() && !is_oracle_mode())) { | ||||||
|                          (!my_session_->use_static_typing_engine() && 2 != param_count))) { |   } else if (OB_UNLIKELY((param_copied && 6 != param_count) | ||||||
|  |              || (!param_copied && 2 != param_count))) { | ||||||
|     // For the new engine, due to the copy of the nullif parameter, |     // For the new engine, due to the copy of the nullif parameter, | ||||||
|     // there are actually 3 sets of parameters: the original input parameter, |     // there are actually 3 sets of parameters: the original input parameter, | ||||||
|     // the calc type parameter and the result parameter, so there are 6 in total |     // the calc type parameter and the result parameter, so there are 6 in total | ||||||
| @ -784,7 +786,7 @@ int ObRawExprWrapEnumSet::wrap_nullif_expr(ObSysFunRawExpr& expr) | |||||||
|     ret = OB_ERR_UNEXPECTED; |     ret = OB_ERR_UNEXPECTED; | ||||||
|     LOG_WARN("param_count is not equal to input_types_count", K(param_count), K(input_types_count), K(ret)); |     LOG_WARN("param_count is not equal to input_types_count", K(param_count), K(input_types_count), K(ret)); | ||||||
|   } else { |   } else { | ||||||
|     for (int i = 0; i < param_count / 2; ++i) { |     for (int i = 0; i < param_count && OB_SUCC(ret); i += 2) { | ||||||
|       ObRawExpr* left_param = expr.get_param_expr(i); |       ObRawExpr* left_param = expr.get_param_expr(i); | ||||||
|       ObRawExpr* right_param = expr.get_param_expr(i + 1); |       ObRawExpr* right_param = expr.get_param_expr(i + 1); | ||||||
|       if (OB_ISNULL(left_param) || OB_ISNULL(right_param)) { |       if (OB_ISNULL(left_param) || OB_ISNULL(right_param)) { | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 st0
					st0