From 72fddccca757c670cdb038c73cb0c01503e5e4e4 Mon Sep 17 00:00:00 2001 From: "Levy A." Date: Thu, 11 Sep 2025 12:24:34 -0300 Subject: [PATCH] fix: use sqlite compatible math functions --- core/vdbe/execute.rs | 66 ++++++++++++++++++++++++--------- fuzz/Cargo.lock | 10 ++--- fuzz/fuzz_targets/expression.rs | 26 +++++++++++++ 3 files changed, 79 insertions(+), 23 deletions(-) diff --git a/core/vdbe/execute.rs b/core/vdbe/execute.rs index 11257211a..a3108e157 100644 --- a/core/vdbe/execute.rs +++ b/core/vdbe/execute.rs @@ -7646,6 +7646,32 @@ pub fn op_if_neg( Ok(InsnFunctionStepResult::Step) } +mod cmath { + extern "C" { + pub fn exp(x: f64) -> f64; + pub fn log(x: f64) -> f64; + pub fn log10(x: f64) -> f64; + pub fn log2(x: f64) -> f64; + pub fn pow(x: f64, y: f64) -> f64; + + pub fn sin(x: f64) -> f64; + pub fn sinh(x: f64) -> f64; + pub fn asin(x: f64) -> f64; + pub fn asinh(x: f64) -> f64; + + pub fn cos(x: f64) -> f64; + pub fn cosh(x: f64) -> f64; + pub fn acos(x: f64) -> f64; + pub fn acosh(x: f64) -> f64; + + pub fn tan(x: f64) -> f64; + pub fn tanh(x: f64) -> f64; + pub fn atan(x: f64) -> f64; + pub fn atanh(x: f64) -> f64; + pub fn atan2(x: f64, y: f64) -> f64; + } +} + impl Value { pub fn exec_lower(&self) -> Option { match self { @@ -8233,28 +8259,32 @@ impl Value { return Value::Null; }; + if matches! { function, MathFunc::Ln | MathFunc::Log10 | MathFunc::Log2 } && f <= 0.0 { + return Value::Null; + } + let result = match function { - MathFunc::Acos => libm::acos(f), - MathFunc::Acosh => libm::acosh(f), - MathFunc::Asin => libm::asin(f), - MathFunc::Asinh => libm::asinh(f), - MathFunc::Atan => libm::atan(f), - MathFunc::Atanh => libm::atanh(f), + MathFunc::Acos => unsafe { cmath::acos(f) }, + MathFunc::Acosh => unsafe { cmath::acosh(f) }, + MathFunc::Asin => unsafe { cmath::asin(f) }, + MathFunc::Asinh => unsafe { cmath::asinh(f) }, + MathFunc::Atan => unsafe { cmath::atan(f) }, + MathFunc::Atanh => unsafe { cmath::atanh(f) }, MathFunc::Ceil | MathFunc::Ceiling => libm::ceil(f), - MathFunc::Cos => libm::cos(f), - MathFunc::Cosh => libm::cosh(f), + MathFunc::Cos => unsafe { cmath::cos(f) }, + MathFunc::Cosh => unsafe { cmath::cosh(f) }, MathFunc::Degrees => f.to_degrees(), - MathFunc::Exp => libm::exp(f), + MathFunc::Exp => unsafe { cmath::exp(f) }, MathFunc::Floor => libm::floor(f), - MathFunc::Ln => libm::log(f), - MathFunc::Log10 => libm::log10(f), - MathFunc::Log2 => libm::log2(f), + MathFunc::Ln => unsafe { cmath::log(f) }, + MathFunc::Log10 => unsafe { cmath::log10(f) }, + MathFunc::Log2 => unsafe { cmath::log2(f) }, MathFunc::Radians => f.to_radians(), - MathFunc::Sin => libm::sin(f), - MathFunc::Sinh => libm::sinh(f), + MathFunc::Sin => unsafe { cmath::sin(f) }, + MathFunc::Sinh => unsafe { cmath::sinh(f) }, MathFunc::Sqrt => libm::sqrt(f), - MathFunc::Tan => libm::tan(f), - MathFunc::Tanh => libm::tanh(f), + MathFunc::Tan => unsafe { cmath::tan(f) }, + MathFunc::Tanh => unsafe { cmath::tanh(f) }, MathFunc::Trunc => libm::trunc(f), _ => unreachable!("Unexpected mathematical unary function {:?}", function), }; @@ -8276,9 +8306,9 @@ impl Value { }; let result = match function { - MathFunc::Atan2 => libm::atan2(lhs, rhs), + MathFunc::Atan2 => unsafe { cmath::atan2(lhs, rhs) }, MathFunc::Mod => libm::fmod(lhs, rhs), - MathFunc::Pow | MathFunc::Power => libm::pow(lhs, rhs), + MathFunc::Pow | MathFunc::Power => unsafe { cmath::pow(lhs, rhs) }, _ => unreachable!("Unexpected mathematical binary function {:?}", function), }; diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index 12f1409ac..ca6e559f0 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -1182,7 +1182,7 @@ dependencies = [ [[package]] name = "turso_core" -version = "0.1.5" +version = "0.2.0-pre.1" dependencies = [ "aegis", "aes", @@ -1225,7 +1225,7 @@ dependencies = [ [[package]] name = "turso_ext" -version = "0.1.5" +version = "0.2.0-pre.1" dependencies = [ "chrono", "getrandom 0.3.1", @@ -1234,7 +1234,7 @@ dependencies = [ [[package]] name = "turso_macros" -version = "0.1.5" +version = "0.2.0-pre.1" dependencies = [ "proc-macro2", "quote", @@ -1243,7 +1243,7 @@ dependencies = [ [[package]] name = "turso_parser" -version = "0.1.5" +version = "0.2.0-pre.1" dependencies = [ "bitflags", "miette", @@ -1255,7 +1255,7 @@ dependencies = [ [[package]] name = "turso_sqlite3_parser" -version = "0.1.5" +version = "0.2.0-pre.1" dependencies = [ "bitflags", "cc", diff --git a/fuzz/fuzz_targets/expression.rs b/fuzz/fuzz_targets/expression.rs index 289d93d15..f5cd80a38 100644 --- a/fuzz/fuzz_targets/expression.rs +++ b/fuzz/fuzz_targets/expression.rs @@ -120,12 +120,38 @@ str_enum! { enum UnaryFunc { Ceil => "ceil", Floor => "floor", + Trunc => "trunc", + Radians => "radians", + Degrees => "degrees", + + Sqrt => "sqrt", + Exp => "exp", + Ln => "ln", + Log10 => "log10", + Log2 => "log2", + + Sin => "sin", + Sinh => "sinh", + Asin => "asin", + Asinh => "asinh", + + Cos => "cos", + Cosh => "cosh", + Acos => "acos", + Acosh => "acosh", + + Tan => "tan", + Tanh => "tanh", + Atan => "atan", + Atanh => "atanh", } } str_enum! { enum BinaryFunc { Power => "pow", + Mod => "mod", + Atan2 => "atan2", } }