Skip to content

Commit

Permalink
Merge pull request #196 from Qrlew/impl_log
Browse files Browse the repository at this point in the history
Implement new math functions
  • Loading branch information
ngrislain authored Nov 27, 2023
2 parents 0ad6eae + 5db4372 commit 28688c2
Show file tree
Hide file tree
Showing 7 changed files with 208 additions and 5 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]
## Added
- Implemented math functions: `PI`, `DEGREES`, `TAN`, `RANDOM`, `LOG10`, `LOG2`, `SQUARE` [#196](https://github.com/Qrlew/qrlew/issues/196)

## [0.5.2] - 2023-11-19
## Added
- `CEIL`, `ROUND`, `FLOOR`and `TRUNC` funtions [#192](https://github.com/Qrlew/qrlew/issues/192)
- `SIGN` funtion [#194](https://github.com/Qrlew/qrlew/issues/194)
- `SIGN` funtion [#195](https://github.com/Qrlew/qrlew/issues/195)
- SD is acceptable as DP compilation

## [0.5.1] - 2023-11-19
Expand Down
8 changes: 8 additions & 0 deletions src/data_type/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1458,6 +1458,14 @@ pub fn random<R: rand::Rng + Send + 'static>(mut rng: Mutex<R>) -> impl Function
)
}

pub fn pi() -> impl Function {
Stateful::new(
DataType::unit(),
DataType::float_value(3.141592653589793),
Arc::new(Mutex::new(RefCell::new(move |_| 3.141592653589793.into()))),
)
}

pub fn gt() -> impl Function {
Polymorphic::default()
.with(PartitionnedMonotonic::bivariate(
Expand Down
5 changes: 4 additions & 1 deletion src/expr/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub enum Function {
Md5,
Position,
Random(usize),
Pi,
CastAsText,
CastAsFloat,
CastAsInteger,
Expand Down Expand Up @@ -112,6 +113,7 @@ impl Function {
| Function::InList => Style::BinaryOperator,
// Zero arg Functions
Function::Random(_)
| Function::Pi
// Unary Functions
| Function::Exp
| Function::Ln
Expand Down Expand Up @@ -179,7 +181,7 @@ impl Function {
| Function::BitwiseXor
| Function::InList => Arity::Nary(2),
// Zero arg Functions
Function::Random(_) => Arity::Nary(0),
Function::Random(_) | Function::Pi => Arity::Nary(0),
// Unary Functions
Function::Exp
| Function::Ln
Expand Down Expand Up @@ -271,6 +273,7 @@ impl fmt::Display for Function {
Function::InList => "in",
// Zero arg Functions
Function::Random(_) => "random",
Function::Pi => "pi",
// Unary Functions
Function::Exp => "exp",
Function::Ln => "ln",
Expand Down
1 change: 1 addition & 0 deletions src/expr/implementation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ function_implementations!(
Function::CastAsTime => Arc::new(Optional::new(function::cast(DataType::time()))),
Function::Concat(n) => Arc::new(function::concat(n)),
Function::Random(n) => Arc::new(function::random(Mutex::new(OsRng))), //TODO change this initialization
Function::Pi => Arc::new(function::pi()),
Function::Coalesce => Arc::new(function::coalesce()),
_ => unreachable!(),
}
Expand Down
58 changes: 56 additions & 2 deletions src/expr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,19 +168,29 @@ impl fmt::Display for Function {

impl Variant for Function {}

/// Implemant random function constructor (same thing but no macro here)
/// Implement random function constructor (same thing but no macro here)
impl Function {
pub fn random(n: usize) -> Function {
Function::new(function::Function::Random(n), vec![])
}
}

/// Implemant random expression constructor (same thing but no macro here)
impl Function {
pub fn pi() -> Function {
Function::new(function::Function::Pi, vec![])
}
}

/// Implement random expression constructor (same thing but no macro here)
impl Expr {
pub fn random(n: usize) -> Expr {
Expr::from(Function::random(n))
}

pub fn pi() -> Expr {
Expr::from(Function::pi())
}

pub fn filter_column(
name: &str,
min: Option<data_type::value::Value>,
Expand Down Expand Up @@ -3047,4 +3057,48 @@ mod tests {
DataType::integer_value(1)
);
}

#[test]
fn test_random() {
println!("random");
let expression = Expr::random(2);
println!("expression = {}", expression);
println!("expression domain = {}", expression.domain());
println!("expression co domain = {}", expression.co_domain());
println!("expression data type = {}", expression.data_type());

let set = DataType::structured([
("col1", DataType::float()),
]);
println!(
"expression super image = {}",
expression.super_image(&set).unwrap()
);
assert_eq!(
expression.super_image(&set).unwrap(),
DataType::float_interval(0., 1.)
);
}

#[test]
fn test_pi() {
println!("pi");
let expression = Expr::pi();
println!("expression = {}", expression);
println!("expression domain = {}", expression.domain());
println!("expression co domain = {}", expression.co_domain());
println!("expression data type = {}", expression.data_type());

let set = DataType::structured([
("col1", DataType::float()),
]);
println!(
"expression super image = {}",
expression.super_image(&set).unwrap()
);
assert_eq!(
expression.super_image(&set).unwrap(),
DataType::float_value(3.141592653589793)
);
}
}
119 changes: 119 additions & 0 deletions src/expr/sql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ impl<'a> expr::Visitor<'a, ast::Expr> for FromExprVisitor {
| expr::function::Function::Lower
| expr::function::Function::Upper
| expr::function::Function::Random(_)
| expr::function::Function::Pi
| expr::function::Function::Least
| expr::function::Function::Greatest
| expr::function::Function::Coalesce
Expand Down Expand Up @@ -663,4 +664,122 @@ mod tests {
println!("ast::expr = {gen_expr}");
assert_eq!(ast_expr, gen_expr);
}

#[test]
fn test_square() {
let str_expr = "square(x)";
let ast_expr: ast::Expr = parse_expr(str_expr).unwrap();
let expr = Expr::try_from(&ast_expr).unwrap();
println!("expr = {}", expr);
let gen_expr = ast::Expr::from(&expr);
let true_expr = parse_expr("pow(x, 2)").unwrap();
assert_eq!(gen_expr, true_expr);
}

#[test]
fn test_log() {
let str_expr = "ln(x)";
let ast_expr: ast::Expr = parse_expr(str_expr).unwrap();
let expr = Expr::try_from(&ast_expr).unwrap();
println!("expr = {}", expr);
let gen_expr = ast::Expr::from(&expr);
println!("ast::expr = {gen_expr}");
assert_eq!(ast_expr, gen_expr);

let str_expr = "log(x)";
let ast_expr: ast::Expr = parse_expr(str_expr).unwrap();
let expr = Expr::try_from(&ast_expr).unwrap();
println!("expr = {}", expr);
let gen_expr = ast::Expr::from(&expr);
println!("ast::expr = {gen_expr}");
assert_eq!(ast_expr, gen_expr);

let str_expr = "log(b, x)";
let ast_expr: ast::Expr = parse_expr(str_expr).unwrap();
let expr = Expr::try_from(&ast_expr).unwrap();
println!("expr = {}", expr);
let gen_expr = ast::Expr::from(&expr);
println!("ast::expr = {gen_expr}");
let true_expr = parse_expr("(log(x)) / ((log(b)))").unwrap();
assert_eq!(gen_expr, true_expr);

let str_expr = "log10(x)";
let ast_expr: ast::Expr = parse_expr(str_expr).unwrap();
let expr = Expr::try_from(&ast_expr).unwrap();
println!("expr = {}", expr);
let gen_expr = ast::Expr::from(&expr);
let true_expr = parse_expr("(log(10)) / ((log(x)))").unwrap();
assert_eq!(gen_expr, true_expr);

let str_expr = "log2(x)";
let ast_expr: ast::Expr = parse_expr(str_expr).unwrap();
let expr = Expr::try_from(&ast_expr).unwrap();
println!("expr = {}", expr);
let gen_expr = ast::Expr::from(&expr);
println!("ast::expr = {gen_expr}");
let true_expr = parse_expr("(log(2)) / ((log(x)))").unwrap();
assert_eq!(gen_expr, true_expr);
}

#[test]
fn test_trigo() {
let str_expr = "sin(x)";
let ast_expr: ast::Expr = parse_expr(str_expr).unwrap();
let expr = Expr::try_from(&ast_expr).unwrap();
println!("expr = {}", expr);
let gen_expr = ast::Expr::from(&expr);
println!("ast::expr = {gen_expr}");
assert_eq!(ast_expr, gen_expr);

let str_expr = "cos(x)";
let ast_expr: ast::Expr = parse_expr(str_expr).unwrap();
let expr = Expr::try_from(&ast_expr).unwrap();
println!("expr = {}", expr);
let gen_expr = ast::Expr::from(&expr);
println!("ast::expr = {gen_expr}");
assert_eq!(ast_expr, gen_expr);

let str_expr = "tan(x)";
let ast_expr: ast::Expr = parse_expr(str_expr).unwrap();
let expr = Expr::try_from(&ast_expr).unwrap();
println!("expr = {}", expr);
let gen_expr = ast::Expr::from(&expr);
println!("ast::expr = {gen_expr}");
let true_expr = parse_expr("(sin(x)) / ((cos(x)))").unwrap();
assert_eq!(gen_expr, true_expr);
}

#[test]
fn test_random() {
let str_expr = "random()";
let ast_expr: ast::Expr = parse_expr(str_expr).unwrap();
let expr = Expr::try_from(&ast_expr).unwrap();
println!("expr = {}", expr);
let gen_expr = ast::Expr::from(&expr);
println!("ast::expr = {gen_expr}");
assert_eq!(ast_expr, gen_expr);
}

#[test]
fn test_pi() {
let str_expr = "pi()";
let ast_expr: ast::Expr = parse_expr(str_expr).unwrap();
let expr = Expr::try_from(&ast_expr).unwrap();
println!("expr = {}", expr);
let gen_expr = ast::Expr::from(&expr);
println!("ast::expr = {gen_expr}");
assert_eq!(ast_expr, gen_expr);
}

#[test]
fn test_degrees() {
let str_expr = "degrees(100)";
let ast_expr: ast::Expr = parse_expr(str_expr).unwrap();
let expr = Expr::try_from(&ast_expr).unwrap();
println!("expr = {}", expr);
let gen_expr = ast::Expr::from(&expr);
println!("ast::expr = {gen_expr}");
let true_expr = parse_expr("(100) * (((180) / ((pi()))))").unwrap();
assert_eq!(gen_expr, true_expr);
}
}
19 changes: 18 additions & 1 deletion src/sql/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::{
expr::{identifier::Identifier, Expr, Value},
hierarchy::{Hierarchy, Path},
visitor::{self, Acceptor, Dependencies, Visited},
namer
};
use itertools::Itertools;
use sqlparser::{
Expand Down Expand Up @@ -914,13 +915,23 @@ impl<'a> Visitor<'a, Result<Expr>> for TryIntoExprVisitor<'a> {
"not" => Expr::not(flat_args[0].clone()),
"exp" => Expr::exp(flat_args[0].clone()),
"ln" => Expr::ln(flat_args[0].clone()),
"log" => Expr::log(flat_args[0].clone()),
"log" => {
if flat_args.len() == 1 {
Expr::log(flat_args[0].clone())
} else {
Expr::divide(Expr::log(flat_args[1].clone()), Expr::log(flat_args[0].clone()))
}
}
"log2" => Expr::divide(Expr::log(Expr::val(2)), Expr::log(flat_args[0].clone())),
"log10" => Expr::divide(Expr::log(Expr::val(10)), Expr::log(flat_args[0].clone())),
"abs" => Expr::abs(flat_args[0].clone()),
"sin" => Expr::sin(flat_args[0].clone()),
"cos" => Expr::cos(flat_args[0].clone()),
"tan" => Expr::divide(Expr::sin(flat_args[0].clone()), Expr::cos(flat_args[0].clone())),
"sqrt" => Expr::sqrt(flat_args[0].clone()),
"pow" => Expr::pow(flat_args[0].clone(), flat_args[1].clone()),
"power" => Expr::pow(flat_args[0].clone(), flat_args[1].clone()),
"square" => Expr::pow(flat_args[0].clone(), Expr::val(2)),
"md5" => Expr::md5(flat_args[0].clone()),
"coalesce" => {
let (first, vec) = flat_args.split_first().unwrap();
Expand Down Expand Up @@ -981,6 +992,12 @@ impl<'a> Visitor<'a, Result<Expr>> for TryIntoExprVisitor<'a> {
)
}
"sign" => Expr::sign(flat_args[0].clone()),
"random" => Expr::random(namer::new_id("UNIFORM_SAMPLING")),
"pi" => Expr::pi(),
"degrees" => Expr::multiply(
flat_args[0].clone(),
Expr::divide(Expr::val(180.), Expr::pi())
),
// Aggregates
"min" => Expr::min(flat_args[0].clone()),
"max" => Expr::max(flat_args[0].clone()),
Expand Down

0 comments on commit 28688c2

Please sign in to comment.