vibesql-executor 0.2.0

Query execution engine for vibesql SQL database
Documentation
//! Tests for advanced math functions (EXP, LN, LOG, SIGN, PI)

use crate::common::create_test_evaluator;

#[test]
fn test_exp_function() {
    let (evaluator, row) = create_test_evaluator();

    let expr = vibesql_ast::Expression::Function {
        name: vibesql_ast::FunctionIdentifier::new("EXP"),
        args: vec![vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Integer(1))],
        character_unit: None,
    };
    let result = evaluator.eval(&expr, &row).unwrap();

    // e^1 ≈ 2.718281828
    if let vibesql_types::SqlValue::Double(val) = result {
        assert!((val - 2.718281828).abs() < 0.0001);
    } else {
        panic!("Expected Double value");
    }
}

#[test]
fn test_ln_function() {
    let (evaluator, row) = create_test_evaluator();

    let expr = vibesql_ast::Expression::Function {
        name: vibesql_ast::FunctionIdentifier::new("LN"),
        args: vec![vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Double(2.718281828))],
        character_unit: None,
    };
    let result = evaluator.eval(&expr, &row).unwrap();

    // ln(e) ≈ 1.0
    if let vibesql_types::SqlValue::Double(val) = result {
        assert!((val - 1.0).abs() < 0.0001);
    } else {
        panic!("Expected Double value");
    }
}

#[test]
fn test_log_alias() {
    let (evaluator, row) = create_test_evaluator();

    // SQLite: LOG(x) is log base 10 (same as LOG10)
    let expr = vibesql_ast::Expression::Function {
        name: vibesql_ast::FunctionIdentifier::new("LOG"),
        args: vec![vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Double(10.0))],
        character_unit: None,
    };
    let result = evaluator.eval(&expr, &row).unwrap();

    // LOG(10) = 1.0 for log base 10
    if let vibesql_types::SqlValue::Double(val) = result {
        assert!((val - 1.0).abs() < 0.0001);
    } else {
        panic!("Expected Double value");
    }
}

#[test]
fn test_log10_function() {
    let (evaluator, row) = create_test_evaluator();

    let expr = vibesql_ast::Expression::Function {
        name: vibesql_ast::FunctionIdentifier::new("LOG10"),
        args: vec![vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Integer(100))],
        character_unit: None,
    };
    let result = evaluator.eval(&expr, &row).unwrap();
    assert_eq!(result, vibesql_types::SqlValue::Double(2.0)); // log10(100) = 2
}

#[test]
fn test_sign_positive() {
    let (evaluator, row) = create_test_evaluator();

    let expr = vibesql_ast::Expression::Function {
        name: vibesql_ast::FunctionIdentifier::new("SIGN"),
        args: vec![vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Integer(42))],
        character_unit: None,
    };
    let result = evaluator.eval(&expr, &row).unwrap();
    assert_eq!(result, vibesql_types::SqlValue::Integer(1));
}

#[test]
fn test_sign_negative() {
    let (evaluator, row) = create_test_evaluator();

    let expr = vibesql_ast::Expression::Function {
        name: vibesql_ast::FunctionIdentifier::new("SIGN"),
        args: vec![vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Integer(-42))],
        character_unit: None,
    };
    let result = evaluator.eval(&expr, &row).unwrap();
    assert_eq!(result, vibesql_types::SqlValue::Integer(-1));
}

#[test]
fn test_sign_zero() {
    let (evaluator, row) = create_test_evaluator();

    let expr = vibesql_ast::Expression::Function {
        name: vibesql_ast::FunctionIdentifier::new("SIGN"),
        args: vec![vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Integer(0))],
        character_unit: None,
    };
    let result = evaluator.eval(&expr, &row).unwrap();
    assert_eq!(result, vibesql_types::SqlValue::Integer(0));
}

#[test]
fn test_pi_function() {
    let (evaluator, row) = create_test_evaluator();

    let expr = vibesql_ast::Expression::Function {
        name: vibesql_ast::FunctionIdentifier::new("PI"),
        args: vec![],
        character_unit: None,
    };
    let result = evaluator.eval(&expr, &row).unwrap();

    if let vibesql_types::SqlValue::Double(val) = result {
        assert!((val - 3.14159265).abs() < 0.0001);
    } else {
        panic!("Expected Double value");
    }
}