Repository: risingwavelabs/risingwave
File: src/expr/impl/src/scalar/arithmetic_op.rs (Rust)

Code before:
/// ----
/// 24
///
/// statement error
/// SELECT gamma('-1'::float8);
///
/// statement error
/// SELECT gamma('-1000.5'::float8);
///
/// statement error
/// SELECT gamma('0'::float8);
///
/// statement error
/// SELECT gamma('1000'::float8);
/// ```
#[function("gamma(float8) -> float8")]
pub fn gamma_f64(input: F64) -> Result<F64> {
    let mut result = input;
    if input.is_nan() {
        return Ok(result);
    } else if input.is_infinite() {
        if input.is_negative() {
            return Err(ExprError::InvalidParam {
                name: "gamma",
                reason: "value out of range: overflow".into(),
            });
        }
    } else {
        result = F64::from(Gamma::gamma(input.0));
        if result.is_nan() || result.is_infinite() {
            if !result.is_zero() {
                return Err(ExprError::InvalidParam {
                    name: "gamma",
                    reason: "value out of range: overflow".into(),
                });
            } else {
                return Err(ExprError::InvalidParam {
                    name: "gamma",
                    reason: "value out of range: underflow".into(),
                });
            }
        } else if result.is_zero() {
            return Err(ExprError::InvalidParam {
                name: "gamma",
                reason: "value out of range: underflow".into(),
            });
        }
    }
    Ok(result)
}


Review comment (bug):
Shall we use `NumericOverflow` and `NumericUnderflow` instead?

Code after:
            general_add::<_, _, Decimal>(Decimal::from_str("1").unwrap(), 1i32).unwrap(),
            Decimal::from_str("2").unwrap()
        );
    }

    #[test]
    fn test_arithmetic() {
        assert_eq!(
            general_add::<Decimal, i32, Decimal>(dec("1.0"), 1).unwrap(),
            dec("2.0")
        );
        assert_eq!(
            general_sub::<Decimal, i32, Decimal>(dec("1.0"), 2).unwrap(),
            dec("-1.0")
        );
        assert_eq!(
            general_mul::<Decimal, i32, Decimal>(dec("1.0"), 2).unwrap(),
            dec("2.0")
        );
        assert_eq!(
            general_div::<Decimal, i32, Decimal>(dec("2.0"), 2).unwrap(),
            dec("1.0")
        );
        assert_eq!(
            general_mod::<Decimal, i32, Decimal>(dec("2.0"), 2).unwrap(),
            dec("0")
        );
        assert_eq!(general_neg::<Decimal>(dec("1.0")).unwrap(), dec("-1.0"));
        assert_eq!(general_add::<i16, i32, i32>(1i16, 1i32).unwrap(), 2i32);
        assert_eq!(general_sub::<i16, i32, i32>(1i16, 1i32).unwrap(), 0i32);
        assert_eq!(general_mul::<i16, i32, i32>(1i16, 1i32).unwrap(), 1i32);
        assert_eq!(general_div::<i16, i32, i32>(1i16, 1i32).unwrap(), 1i32);
        assert_eq!(general_mod::<i16, i32, i32>(1i16, 1i32).unwrap(), 0i32);
        assert_eq!(general_neg::<i16>(1i16).unwrap(), -1i16);

        assert!(
            general_add::<i32, F32, F64>(-1i32, 1f32.into())
                .unwrap()
                .is_zero()
        );
        assert!(
            general_sub::<i32, F32, F64>(1i32, 1f32.into())
                .unwrap()
                .is_zero()
        );
        assert!(
            general_mul::<i32, F32, F64>(0i32, 1f32.into())
                .unwrap()
                .is_zero()
        );
        assert!(