From db82be8c7e98d39398e4ea473826aa45826aeffa Mon Sep 17 00:00:00 2001 From: hezuojiao Date: Tue, 28 May 2024 13:54:12 +0000 Subject: [PATCH] Fix decimal sum precision deduce not idempotent --- src/sql/code_generator/ob_static_engine_cg.cpp | 5 +++++ src/sql/resolver/expr/ob_raw_expr_deduce_type.cpp | 3 ++- src/sql/resolver/expr/ob_raw_expr_info_extractor.cpp | 5 ++++- src/sql/resolver/expr/ob_raw_expr_util.cpp | 2 ++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/sql/code_generator/ob_static_engine_cg.cpp b/src/sql/code_generator/ob_static_engine_cg.cpp index 63825d84ca..eec6ccd0dc 100644 --- a/src/sql/code_generator/ob_static_engine_cg.cpp +++ b/src/sql/code_generator/ob_static_engine_cg.cpp @@ -6265,6 +6265,11 @@ int ObStaticEngineCG::generate_spec( ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected output type of subplan scan", K(ret), K(from->get_result_type()), K(col_expr->get_result_type())); + } else if (ob_is_decimal_int_tc(from_type) && + ObRawExprUtils::decimal_int_need_cast(from->get_accuracy(), col_expr->get_accuracy())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("decimal int datum meta is not match", K(ret), K(from->get_accuracy()), + K(col_expr->get_accuracy())); } OZ(generate_rt_expr(*from, rt_expr)); OZ(spec.projector_.push_back(rt_expr)); diff --git a/src/sql/resolver/expr/ob_raw_expr_deduce_type.cpp b/src/sql/resolver/expr/ob_raw_expr_deduce_type.cpp index b3e3da4ebd..20b98e6a22 100644 --- a/src/sql/resolver/expr/ob_raw_expr_deduce_type.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_deduce_type.cpp @@ -1701,7 +1701,8 @@ int ObRawExprDeduceType::visit(ObAggFunRawExpr &expr) // In mysql mode, the precision of sum() will increase by OB_DECIMAL_LONGLONG_DIGITS. // But for expression like sum(sum()), the outer sum() is generated by // aggregation pushdown, so we don't need to accumulate precision for the outer expr. - if (T_FUN_SUM == expr.get_expr_type() && T_FUN_SUM != child_expr->get_expr_type()) { + if (T_FUN_SUM == expr.get_expr_type() && (T_FUN_SUM != child_expr->get_expr_type() || + !expr.has_flag(IS_INNER_ADDED_EXPR))) { if (ob_is_integer_type(obj_type)) { const int16_t int_max_prec = ObAccuracy::MAX_ACCURACY2[0/*mysql mode*/][obj_type].get_precision(); result_precision = MAX(result_precision, int_max_prec) + OB_DECIMAL_LONGLONG_DIGITS; diff --git a/src/sql/resolver/expr/ob_raw_expr_info_extractor.cpp b/src/sql/resolver/expr/ob_raw_expr_info_extractor.cpp index 369ececd36..f3643454e4 100644 --- a/src/sql/resolver/expr/ob_raw_expr_info_extractor.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_info_extractor.cpp @@ -441,12 +441,15 @@ int ObRawExprInfoExtractor::visit(ObCaseOpRawExpr &expr) int ObRawExprInfoExtractor::visit(ObAggFunRawExpr &expr) { int ret = OB_SUCCESS; + const bool is_inner_added = expr.has_flag(IS_INNER_ADDED_EXPR); if (OB_FAIL(clear_info(expr))) { LOG_WARN("fail to clear info", K(ret)); } else if (OB_FAIL(pull_info(expr))) { LOG_WARN("fail to add pull info", K(ret)); } else if (OB_FAIL(expr.add_flag(IS_AGG))) { - LOG_WARN("failed to add flag IS_AGG", K(ret)); + LOG_WARN("failed to add flag IS_AGG", K(ret)); + } else if (is_inner_added && OB_FAIL(expr.add_flag(IS_INNER_ADDED_EXPR))) { + LOG_WARN("failed to add inner added expr flag", K(ret)); } else { } return ret; } diff --git a/src/sql/resolver/expr/ob_raw_expr_util.cpp b/src/sql/resolver/expr/ob_raw_expr_util.cpp index 2c2bf6198f..3a50778064 100644 --- a/src/sql/resolver/expr/ob_raw_expr_util.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_util.cpp @@ -8507,6 +8507,8 @@ int ObRawExprUtils::build_common_aggr_expr(ObRawExprFactory &expr_factory, } else if (OB_ISNULL(aggr_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("agg_expr is null", K(ret), K(aggr_expr)); + } else if (OB_FAIL(aggr_expr->add_flag(IS_INNER_ADDED_EXPR))) { + LOG_WARN("failed to add flag", K(ret)); } else if (OB_FAIL(aggr_expr->add_real_param_expr(param_expr))) { LOG_WARN("failed to add param expr to agg expr", K(ret)); } else if (OB_FAIL(aggr_expr->formalize(session_info))) {