mod test_helpers {
include!("../common/test_helpers.rs");
}
use test_helpers::run_with_both_backends;
use tegdb::{Database, MathFunctionsExtension, Result, SqlValue};
#[test]
fn test_abs_function() -> Result<()> {
run_with_both_backends("test_abs_function", |db_path| {
let mut db = Database::open(db_path)?;
db.register_extension(Box::new(MathFunctionsExtension))?;
let result = db.query("SELECT ABS(5)")?;
assert_eq!(result.rows()[0][0], SqlValue::Integer(5));
let result = db.query("SELECT ABS(-5)")?;
assert_eq!(result.rows()[0][0], SqlValue::Integer(5));
let result = db.query("SELECT ABS(0)")?;
assert_eq!(result.rows()[0][0], SqlValue::Integer(0));
let result = db.query("SELECT ABS(2.5)")?;
assert_eq!(result.rows()[0][0], SqlValue::Real(2.5));
let result = db.query("SELECT ABS(-2.5)")?;
assert_eq!(result.rows()[0][0], SqlValue::Real(2.5));
let result = db.query("SELECT ABS(NULL)")?;
assert_eq!(result.rows()[0][0], SqlValue::Null);
Ok(())
})
}
#[test]
fn test_ceil_function() -> Result<()> {
run_with_both_backends("test_ceil_function", |db_path| {
let mut db = Database::open(db_path)?;
db.register_extension(Box::new(MathFunctionsExtension))?;
let result = db.query("SELECT CEIL(3.7)")?;
assert_eq!(result.rows()[0][0], SqlValue::Integer(4));
let result = db.query("SELECT CEIL(-3.7)")?;
assert_eq!(result.rows()[0][0], SqlValue::Integer(-3));
let result = db.query("SELECT CEIL(5)")?;
assert_eq!(result.rows()[0][0], SqlValue::Integer(5));
let result = db.query("SELECT CEIL(0.0)")?;
assert_eq!(result.rows()[0][0], SqlValue::Integer(0));
let result = db.query("SELECT CEIL(NULL)")?;
assert_eq!(result.rows()[0][0], SqlValue::Null);
Ok(())
})
}
#[test]
fn test_floor_function() -> Result<()> {
run_with_both_backends("test_floor_function", |db_path| {
let mut db = Database::open(db_path)?;
db.register_extension(Box::new(MathFunctionsExtension))?;
let result = db.query("SELECT FLOOR(3.7)")?;
assert_eq!(result.rows()[0][0], SqlValue::Integer(3));
let result = db.query("SELECT FLOOR(-3.7)")?;
assert_eq!(result.rows()[0][0], SqlValue::Integer(-4));
let result = db.query("SELECT FLOOR(5)")?;
assert_eq!(result.rows()[0][0], SqlValue::Integer(5));
let result = db.query("SELECT FLOOR(0.0)")?;
assert_eq!(result.rows()[0][0], SqlValue::Integer(0));
let result = db.query("SELECT FLOOR(NULL)")?;
assert_eq!(result.rows()[0][0], SqlValue::Null);
Ok(())
})
}
#[test]
fn test_round_function() -> Result<()> {
run_with_both_backends("test_round_function", |db_path| {
let mut db = Database::open(db_path)?;
db.register_extension(Box::new(MathFunctionsExtension))?;
let result = db.query("SELECT ROUND(3.7, 0)")?;
assert_eq!(result.rows()[0][0], SqlValue::Real(4.0));
let result = db.query("SELECT ROUND(3.75, 1)")?;
assert_eq!(result.rows()[0][0], SqlValue::Real(3.8));
let result = db.query("SELECT ROUND(2.34567, 2)")?;
if let SqlValue::Real(rounded) = result.rows()[0][0] {
assert!((rounded - 2.35).abs() < 0.001);
} else {
panic!("Expected Real result");
}
let result = db.query("SELECT ROUND(3.5, 0)")?;
assert_eq!(result.rows()[0][0], SqlValue::Real(4.0));
let result = db.query("SELECT ROUND(3.4, 0)")?;
assert_eq!(result.rows()[0][0], SqlValue::Real(3.0));
let result = db.query("SELECT ROUND(-3.5, 0)")?;
assert_eq!(result.rows()[0][0], SqlValue::Real(-4.0));
let result = db.query("SELECT ROUND(NULL, 2)")?;
assert_eq!(result.rows()[0][0], SqlValue::Null);
Ok(())
})
}
#[test]
fn test_sqrt_function() -> Result<()> {
run_with_both_backends("test_sqrt_function", |db_path| {
let mut db = Database::open(db_path)?;
db.register_extension(Box::new(MathFunctionsExtension))?;
let result = db.query("SELECT SQRT(16)")?;
assert_eq!(result.rows()[0][0], SqlValue::Real(4.0));
let result = db.query("SELECT SQRT(144)")?;
assert_eq!(result.rows()[0][0], SqlValue::Real(12.0));
let result = db.query("SELECT SQRT(2.25)")?;
assert_eq!(result.rows()[0][0], SqlValue::Real(1.5));
let result = db.query("SELECT SQRT(0)")?;
assert_eq!(result.rows()[0][0], SqlValue::Real(0.0));
let result = db.query("SELECT SQRT(1)")?;
assert_eq!(result.rows()[0][0], SqlValue::Real(1.0));
let result = db.query("SELECT SQRT(-1)");
assert!(result.is_err());
let result = db.query("SELECT SQRT(NULL)")?;
assert_eq!(result.rows()[0][0], SqlValue::Null);
Ok(())
})
}
#[test]
fn test_pow_function() -> Result<()> {
run_with_both_backends("test_pow_function", |db_path| {
let mut db = Database::open(db_path)?;
db.register_extension(Box::new(MathFunctionsExtension))?;
let result = db.query("SELECT POW(2, 3)")?;
assert_eq!(result.rows()[0][0], SqlValue::Real(8.0));
let result = db.query("SELECT POW(5, 0)")?;
assert_eq!(result.rows()[0][0], SqlValue::Real(1.0));
let result = db.query("SELECT POW(5, 1)")?;
assert_eq!(result.rows()[0][0], SqlValue::Real(5.0));
let result = db.query("SELECT POW(2, -2)")?;
assert_eq!(result.rows()[0][0], SqlValue::Real(0.25));
let result = db.query("SELECT POW(0, 5)")?;
assert_eq!(result.rows()[0][0], SqlValue::Real(0.0));
let result = db.query("SELECT POW(2.5, 2)")?;
assert_eq!(result.rows()[0][0], SqlValue::Real(6.25));
let result = db.query("SELECT POW(NULL, 2)")?;
assert_eq!(result.rows()[0][0], SqlValue::Null);
Ok(())
})
}
#[test]
fn test_mod_function() -> Result<()> {
run_with_both_backends("test_mod_function", |db_path| {
let mut db = Database::open(db_path)?;
db.register_extension(Box::new(MathFunctionsExtension))?;
let result = db.query("SELECT MOD(10, 3)")?;
assert_eq!(result.rows()[0][0], SqlValue::Integer(1));
let result = db.query("SELECT MOD(10, 5)")?;
assert_eq!(result.rows()[0][0], SqlValue::Integer(0));
let result = db.query("SELECT MOD(17, 5)")?;
assert_eq!(result.rows()[0][0], SqlValue::Integer(2));
let result = db.query("SELECT MOD(-10, 3)")?;
assert_eq!(result.rows()[0][0], SqlValue::Integer(-1));
let result = db.query("SELECT MOD(10.5, 3.2)")?;
if let SqlValue::Real(r) = result.rows()[0][0] {
assert!(r > 0.8 && r < 1.0);
} else {
panic!("Expected Real result");
}
let result = db.query("SELECT MOD(10, 0)");
assert!(result.is_err());
let result = db.query("SELECT MOD(NULL, 3)")?;
assert_eq!(result.rows()[0][0], SqlValue::Null);
Ok(())
})
}
#[test]
fn test_sign_function() -> Result<()> {
run_with_both_backends("test_sign_function", |db_path| {
let mut db = Database::open(db_path)?;
db.register_extension(Box::new(MathFunctionsExtension))?;
let result = db.query("SELECT SIGN(5)")?;
assert_eq!(result.rows()[0][0], SqlValue::Integer(1));
let result = db.query("SELECT SIGN(-5)")?;
assert_eq!(result.rows()[0][0], SqlValue::Integer(-1));
let result = db.query("SELECT SIGN(0)")?;
assert_eq!(result.rows()[0][0], SqlValue::Integer(0));
let result = db.query("SELECT SIGN(3.7)")?;
assert_eq!(result.rows()[0][0], SqlValue::Integer(1));
let result = db.query("SELECT SIGN(-3.7)")?;
assert_eq!(result.rows()[0][0], SqlValue::Integer(-1));
let result = db.query("SELECT SIGN(0.0)")?;
assert_eq!(result.rows()[0][0], SqlValue::Integer(0));
let result = db.query("SELECT SIGN(NULL)")?;
assert_eq!(result.rows()[0][0], SqlValue::Null);
Ok(())
})
}
#[test]
fn test_math_functions_in_table_queries() -> Result<()> {
run_with_both_backends("test_math_functions_in_table_queries", |db_path| {
let mut db = Database::open(db_path)?;
db.register_extension(Box::new(MathFunctionsExtension))?;
db.execute("CREATE TABLE products (id INTEGER PRIMARY KEY, price REAL, quantity INTEGER)")?;
db.execute("INSERT INTO products (id, price, quantity) VALUES (1, 19.99, 5), (2, -10.50, 3), (3, 0.0, 0)")?;
let result = db.query("SELECT ABS(price) FROM products WHERE id = 2")?;
assert_eq!(result.rows()[0][0], SqlValue::Real(10.50));
let result = db.query("SELECT id FROM products WHERE ABS(price) > 10")?;
assert_eq!(result.len(), 2);
let result = db.query("SELECT CEIL(price) FROM products WHERE id = 1")?;
assert_eq!(result.rows()[0][0], SqlValue::Integer(20));
let result = db.query("SELECT FLOOR(price) FROM products WHERE id = 1")?;
assert_eq!(result.rows()[0][0], SqlValue::Integer(19));
let result = db.query("SELECT ROUND(price, 1) FROM products WHERE id = 1")?;
assert_eq!(result.rows()[0][0], SqlValue::Real(20.0));
let result = db.query("SELECT SIGN(price) FROM products WHERE id = 2")?;
assert_eq!(result.rows()[0][0], SqlValue::Integer(-1));
Ok(())
})
}