From 0ae4fbf820f18b19ea69fec997b5edcb2e6c3799 Mon Sep 17 00:00:00 2001 From: guoxu <13910754971@163.com> Date: Thu, 25 Dec 2025 18:26:36 +0800 Subject: [PATCH] [fix][libexpr] Fix bigint int overflow issue. --- src/expr/calc/arithmetic.cc | 40 ++++++++++++++++++++++++++++++++++++- src/expr/calc/arithmetic.h | 9 +++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/expr/calc/arithmetic.cc b/src/expr/calc/arithmetic.cc index 9c91954..08157cd 100644 --- a/src/expr/calc/arithmetic.cc +++ b/src/expr/calc/arithmetic.cc @@ -15,9 +15,14 @@ #include #include "arithmetic.h" +#include "../exception.h" -namespace dingodb::expr::calc { +typedef __int128 int128; +#define INT64CONST(x) (x##L) +#define EXPR_INT64_MIN (-INT64CONST(0x7FFFFFFFFFFFFFFF) - 1) +#define EXPR_INT64_MAX INT64CONST(0x7FFFFFFFFFFFFFFF) +namespace dingodb::expr::calc { template <> Operand Div(int v0, int v1) { if (v1 != 0) { @@ -44,4 +49,37 @@ Operand Div<::dingodb::types::DecimalP>( return nullptr; } +template <> +long Add(long v0, long v1) { + int128 result = (int128)v0 + (int128)v1; + + if (result > EXPR_INT64_MAX || result < EXPR_INT64_MIN) { + throw ExceedsLimits(); + } + + return (long)result; +} + +template <> +long Sub(long v0, long v1) { + int128 result = (int128)v0 - (int128)v1; + + if (result > EXPR_INT64_MAX || result < EXPR_INT64_MIN) { + throw ExceedsLimits(); + } + + return (long)result; +} + +template <> +long Mul(long v0, long v1) { + int128 result = (int128)v0 * (int128)v1; + + if (result > EXPR_INT64_MAX || result < EXPR_INT64_MIN) { + throw ExceedsLimits(); + } + + return (long)result; +} + } // namespace dingodb::expr::calc \ No newline at end of file diff --git a/src/expr/calc/arithmetic.h b/src/expr/calc/arithmetic.h index fd7e289..43ee3a8 100644 --- a/src/expr/calc/arithmetic.h +++ b/src/expr/calc/arithmetic.h @@ -34,16 +34,25 @@ T Add(T v0, T v1) { return v0 + v1; } +template <> +long Add(long v0, long v1); + template T Sub(T v0, T v1) { return v0 - v1; } +template <> +long Sub(long v0, long v1); + template T Mul(T v0, T v1) { return v0 * v1; } +template <> +long Mul(long v0, long v1); + template Operand Div(T v0, T v1) { if (v1 != 0) {