| 280 | } |
| 281 | |
| 282 | fn eval_binary_op( |
| 283 | l: &nodedb_types::Value, |
| 284 | op: &sqlparser::ast::BinaryOperator, |
| 285 | r: &nodedb_types::Value, |
| 286 | ) -> Option<nodedb_types::Value> { |
| 287 | use nodedb_types::Value; |
| 288 | use sqlparser::ast::BinaryOperator::*; |
| 289 | |
| 290 | match (l, r) { |
| 291 | (Value::Integer(a), Value::Integer(b)) => match op { |
| 292 | Plus => Some(Value::Integer(a.checked_add(*b)?)), |
| 293 | Minus => Some(Value::Integer(a.checked_sub(*b)?)), |
| 294 | Multiply => Some(Value::Integer(a.checked_mul(*b)?)), |
| 295 | Divide if *b != 0 => Some(Value::Integer(a.checked_div(*b)?)), |
| 296 | Modulo if *b != 0 => Some(Value::Integer(a.checked_rem(*b)?)), |
| 297 | Gt => Some(Value::Bool(a > b)), |
| 298 | GtEq => Some(Value::Bool(a >= b)), |
| 299 | Lt => Some(Value::Bool(a < b)), |
| 300 | LtEq => Some(Value::Bool(a <= b)), |
| 301 | Eq => Some(Value::Bool(a == b)), |
| 302 | NotEq => Some(Value::Bool(a != b)), |
| 303 | _ => None, |
| 304 | }, |
| 305 | (Value::Float(a), Value::Float(b)) => match op { |
| 306 | Plus => Some(Value::Float(a + b)), |
| 307 | Minus => Some(Value::Float(a - b)), |
| 308 | Multiply => Some(Value::Float(a * b)), |
| 309 | Divide if *b != 0.0 => { |
| 310 | let res = a / b; |
| 311 | if res.is_finite() { |
| 312 | Some(Value::Float(res)) |
| 313 | } else { |
| 314 | None |
| 315 | } |
| 316 | } |
| 317 | Gt => Some(Value::Bool(a > b)), |
| 318 | GtEq => Some(Value::Bool(a >= b)), |
| 319 | Lt => Some(Value::Bool(a < b)), |
| 320 | LtEq => Some(Value::Bool(a <= b)), |
| 321 | _ => None, |
| 322 | }, |
| 323 | (Value::Integer(a), Value::Float(b)) => { |
| 324 | eval_binary_op(&Value::Float(*a as f64), op, &Value::Float(*b)) |
| 325 | } |
| 326 | (Value::Float(a), Value::Integer(b)) => { |
| 327 | eval_binary_op(&Value::Float(*a), op, &Value::Float(*b as f64)) |
| 328 | } |
| 329 | (Value::Bool(a), Value::Bool(b)) => match op { |
| 330 | And => Some(Value::Bool(*a && *b)), |
| 331 | Or => Some(Value::Bool(*a || *b)), |
| 332 | Eq => Some(Value::Bool(a == b)), |
| 333 | NotEq => Some(Value::Bool(a != b)), |
| 334 | _ => None, |
| 335 | }, |
| 336 | (Value::String(a), Value::String(b)) => match op { |
| 337 | StringConcat => Some(Value::String(format!("{a}{b}"))), |
| 338 | Eq => Some(Value::Bool(a == b)), |
| 339 | NotEq => Some(Value::Bool(a != b)), |