diff --git a/source/libs/function/src/detail/tavgfunction.c b/source/libs/function/src/detail/tavgfunction.c index adc7aae559..b124678559 100644 --- a/source/libs/function/src/detail/tavgfunction.c +++ b/source/libs/function/src/detail/tavgfunction.c @@ -54,6 +54,20 @@ out->sum.isum += val; \ } +// val is big than INT64_MAX, val come from merge +#define CHECK_OVERFLOW_SUM_SIGNED_BIG(out, val, big) \ + if (out->sum.overflow) { \ + out->sum.dsum += val; \ + } else if (out->sum.isum > 0 && val > 0 && INT64_MAX - out->sum.isum <= val || \ + out->sum.isum < 0 && val < 0 && INT64_MIN - out->sum.isum >= val || \ + big) { \ + double dsum = (double)out->sum.isum; \ + out->sum.overflow = true; \ + out->sum.dsum = dsum + val; \ + } else { \ + out->sum.isum += val; \ + } + // define unsigned number sum with check overflow #define CHECK_OVERFLOW_SUM_UNSIGNED(out, val) \ if (out->sum.overflow) { \ @@ -66,6 +80,18 @@ out->sum.usum += val; \ } +// val is big than UINT64_MAX, val come from merge +#define CHECK_OVERFLOW_SUM_UNSIGNED_BIG(out, val, big) \ + if (out->sum.overflow) { \ + out->sum.dsum += val; \ + } else if (UINT64_MAX - out->sum.usum <= val || big) { \ + double dsum = (double)out->sum.usum; \ + out->sum.overflow = true; \ + out->sum.dsum = dsum + val; \ + } else { \ + out->sum.usum += val; \ + } + typedef struct SAvgRes { double result; SSumRes sum; @@ -658,8 +684,6 @@ _over: return TSDB_CODE_SUCCESS; } - - static void avgTransferInfo(SAvgRes* pInput, SAvgRes* pOutput) { if (IS_NULL_TYPE(pInput->type)) { return; @@ -667,9 +691,11 @@ static void avgTransferInfo(SAvgRes* pInput, SAvgRes* pOutput) { pOutput->type = pInput->type; if (IS_SIGNED_NUMERIC_TYPE(pOutput->type)) { - CHECK_OVERFLOW_SUM_SIGNED(pOutput, (pInput->sum.overflow ? pInput->sum.dsum : pInput->sum.isum)) + bool overflow = pInput->sum.overflow; + CHECK_OVERFLOW_SUM_SIGNED_BIG(pOutput, overflow ? pInput->sum.dsum : pInput->sum.isum, overflow); } else if (IS_UNSIGNED_NUMERIC_TYPE(pOutput->type)) { - CHECK_OVERFLOW_SUM_UNSIGNED(pOutput, (pInput->sum.overflow ? pInput->sum.dsum : pInput->sum.usum)) + bool overflow = pInput->sum.overflow; + CHECK_OVERFLOW_SUM_UNSIGNED_BIG(pOutput, overflow ? pInput->sum.dsum : pInput->sum.usum, overflow); } else { pOutput->sum.dsum += pInput->sum.dsum; }