complete first batch of operators

main
Ziyang Hu 2 years ago
parent 7c2e3c588e
commit 731f4a88a7

@ -15,7 +15,6 @@ use crate::relation::data::DataKind;
use crate::parser::Rule;
use crate::parser::text_identifier::build_name_in_def;
use crate::relation::value;
use crate::relation::value::Value::Apply;
pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
fn get_next_storage_id(&mut self, in_root: bool) -> Result<u32>;
@ -255,16 +254,47 @@ pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
value::OP_GE => self.ge_values(args)?,
value::OP_LT => self.lt_values(args)?,
value::OP_LE => self.le_values(args)?,
value::OP_POW => { todo!() }
value::OP_COALESCE => { todo!() }
value::OP_NEGATE => { todo!() }
value::OP_MINUS => { todo!() }
value::OP_POW => self.pow_values(args)?,
value::OP_COALESCE => self.coalesce_values(args)?,
value::OP_NEGATE => self.negate_values(args)?,
value::OP_MINUS => self.minus_values(args)?,
_ => { todo!() }
})
}
}
}
fn coalesce_values<'a>(&self, args: Vec<Value<'a>>) -> Result<(bool, Value<'a>)> {
let res = args.into_iter().try_fold(vec![], |mut accum, cur| {
match self.partial_eval(cur) {
Ok((ev, cur)) => {
if ev {
if cur == Value::Null {
Ok(accum)
} else {
Err(Ok(cur))
}
} else {
accum.push(cur);
Ok(accum)
}
}
Err(e) => Err(Err(e))
}
});
match res {
Ok(accum) => {
match accum.len() {
0 => Ok((true, Value::Null)),
1 => Ok((false, accum.into_iter().next().unwrap())),
_ => Ok((false, Value::Apply(value::OP_COALESCE.into(), accum)))
}
}
Err(Ok(v)) => Ok((true, v)),
Err(Err(e)) => Err(e)
}
}
fn add_values<'a>(&self, args: Vec<Value<'a>>) -> Result<(bool, Value<'a>)> {
let mut args = args.into_iter();
let (le, left) = self.partial_eval(args.next().unwrap())?;
@ -273,12 +303,13 @@ pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
return Ok((true, Value::Null));
}
if !le || !re {
return Ok((false, Apply(value::OP_ADD.into(), vec![left, right])));
return Ok((false, Value::Apply(value::OP_ADD.into(), vec![left, right])));
}
Ok(match (left, right) {
(Value::Int(l), Value::Int(r)) => (true, (l + r).into()),
(Value::Float(l), Value::Int(r)) => (true, (l + (r as f64)).into()),
(Value::Int(l), Value::Float(r)) => (true, ((l as f64) + r.into_inner()).into()),
(Value::Float(l), Value::Float(r)) => (true, (l.into_inner() + r.into_inner()).into()),
(Value::Text(l), Value::Text(r)) => (true, (l.to_string() + r.as_ref()).into()),
(_, _) => return Err(CozoError::InvalidArgument)
})
@ -291,12 +322,60 @@ pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
return Ok((true, Value::Null));
}
if !le || !re {
return Ok((false, Apply(value::OP_SUB.into(), vec![left, right])));
return Ok((false, Value::Apply(value::OP_SUB.into(), vec![left, right])));
}
Ok(match (left, right) {
(Value::Int(l), Value::Int(r)) => (true, (l - r).into()),
(Value::Float(l), Value::Int(r)) => (true, (l - (r as f64)).into()),
(Value::Int(l), Value::Float(r)) => (true, ((l as f64) - r.into_inner()).into()),
(Value::Float(l), Value::Float(r)) => (true, (l.into_inner() - r.into_inner()).into()),
(_, _) => return Err(CozoError::InvalidArgument)
})
}
fn minus_values<'a>(&self, args: Vec<Value<'a>>) -> Result<(bool, Value<'a>)> {
let mut args = args.into_iter();
let (le, left) = self.partial_eval(args.next().unwrap())?;
if left == Value::Null {
return Ok((true, Value::Null));
}
if !le {
return Ok((false, Value::Apply(value::OP_MINUS.into(), vec![left])));
}
Ok(match left {
Value::Int(l) => (true, (-l).into()),
Value::Float(l) => (true, (-l).into()),
_ => return Err(CozoError::InvalidArgument)
})
}
fn negate_values<'a>(&self, args: Vec<Value<'a>>) -> Result<(bool, Value<'a>)> {
let mut args = args.into_iter();
let (le, left) = self.partial_eval(args.next().unwrap())?;
if left == Value::Null {
return Ok((true, Value::Null));
}
if !le {
return Ok((false, Value::Apply(value::OP_NEGATE.into(), vec![left])));
}
Ok(match left {
Value::Bool(l) => (true, (!l).into()),
_ => return Err(CozoError::InvalidArgument)
})
}
fn pow_values<'a>(&self, args: Vec<Value<'a>>) -> Result<(bool, Value<'a>)> {
let mut args = args.into_iter();
let (le, left) = self.partial_eval(args.next().unwrap())?;
let (re, right) = self.partial_eval(args.next().unwrap())?;
if left == Value::Null || right == Value::Null {
return Ok((true, Value::Null));
}
if !le || !re {
return Ok((false, Value::Apply(value::OP_POW.into(), vec![left, right])));
}
Ok(match (left, right) {
(Value::Int(l), Value::Int(r)) => (true, ((l as f64).powf(r as f64)).into()),
(Value::Float(l), Value::Int(r)) => (true, ((l.into_inner()).powf(r as f64)).into()),
(Value::Int(l), Value::Float(r)) => (true, ((l as f64).powf(r.into_inner())).into()),
(Value::Float(l), Value::Float(r)) => (true, ((l.into_inner()).powf(r.into_inner())).into()),
(_, _) => return Err(CozoError::InvalidArgument)
})
}
@ -308,12 +387,13 @@ pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
return Ok((true, Value::Null));
}
if !le || !re {
return Ok((false, Apply(value::OP_GT.into(), vec![left, right])));
return Ok((false, Value::Apply(value::OP_GT.into(), vec![left, right])));
}
Ok(match (left, right) {
(Value::Int(l), Value::Int(r)) => (true, (l > r).into()),
(Value::Float(l), Value::Int(r)) => (true, (l > (r as f64).into()).into()),
(Value::Int(l), Value::Float(r)) => (true, ((l as f64) > r.into_inner()).into()),
(Value::Float(l), Value::Float(r)) => (true, (l > r).into()),
(_, _) => return Err(CozoError::InvalidArgument)
})
}
@ -325,12 +405,13 @@ pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
return Ok((true, Value::Null));
}
if !le || !re {
return Ok((false, Apply(value::OP_LT.into(), vec![left, right])));
return Ok((false, Value::Apply(value::OP_LT.into(), vec![left, right])));
}
Ok(match (left, right) {
(Value::Int(l), Value::Int(r)) => (true, (l < r).into()),
(Value::Float(l), Value::Int(r)) => (true, (l < (r as f64).into()).into()),
(Value::Int(l), Value::Float(r)) => (true, ((l as f64) < r.into_inner()).into()),
(Value::Float(l), Value::Float(r)) => (true, (l < r).into()),
(_, _) => return Err(CozoError::InvalidArgument)
})
}
@ -342,12 +423,13 @@ pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
return Ok((true, Value::Null));
}
if !le || !re {
return Ok((false, Apply(value::OP_GE.into(), vec![left, right])));
return Ok((false, Value::Apply(value::OP_GE.into(), vec![left, right])));
}
Ok(match (left, right) {
(Value::Int(l), Value::Int(r)) => (true, (l >= r).into()),
(Value::Float(l), Value::Int(r)) => (true, (l >= (r as f64).into()).into()),
(Value::Int(l), Value::Float(r)) => (true, ((l as f64) >= r.into_inner()).into()),
(Value::Float(l), Value::Float(r)) => (true, (l >= r).into()),
(_, _) => return Err(CozoError::InvalidArgument)
})
}
@ -359,12 +441,13 @@ pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
return Ok((true, Value::Null));
}
if !le || !re {
return Ok((false, Apply(value::OP_GE.into(), vec![left, right])));
return Ok((false, Value::Apply(value::OP_GE.into(), vec![left, right])));
}
Ok(match (left, right) {
(Value::Int(l), Value::Int(r)) => (true, (l <= r).into()),
(Value::Float(l), Value::Int(r)) => (true, (l <= (r as f64).into()).into()),
(Value::Int(l), Value::Float(r)) => (true, ((l as f64) <= r.into_inner()).into()),
(Value::Float(l), Value::Float(r)) => (true, (l <= r).into()),
(_, _) => return Err(CozoError::InvalidArgument)
})
}
@ -376,7 +459,7 @@ pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
return Ok((true, Value::Null));
}
if !le || !re {
return Ok((false, Apply(value::OP_MOD.into(), vec![left, right])));
return Ok((false, Value::Apply(value::OP_MOD.into(), vec![left, right])));
}
Ok(match (left, right) {
(Value::Int(l), Value::Int(r)) => (true, (l % r).into()),
@ -391,12 +474,13 @@ pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
return Ok((true, Value::Null));
}
if !le || !re {
return Ok((false, Apply(value::OP_MUL.into(), vec![left, right])));
return Ok((false, Value::Apply(value::OP_MUL.into(), vec![left, right])));
}
Ok(match (left, right) {
(Value::Int(l), Value::Int(r)) => (true, (l * r).into()),
(Value::Float(l), Value::Int(r)) => (true, (l * (r as f64)).into()),
(Value::Int(l), Value::Float(r)) => (true, ((l as f64) * r.into_inner()).into()),
(Value::Float(l), Value::Float(r)) => (true, (l.into_inner() * r.into_inner()).into()),
(_, _) => return Err(CozoError::InvalidArgument)
})
}
@ -408,12 +492,13 @@ pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
return Ok((true, Value::Null));
}
if !le || !re {
return Ok((false, Apply(value::OP_DIV.into(), vec![left, right])));
return Ok((false, Value::Apply(value::OP_DIV.into(), vec![left, right])));
}
Ok(match (left, right) {
(Value::Int(l), Value::Int(r)) => (true, (l as f64 / r as f64).into()),
(Value::Float(l), Value::Int(r)) => (true, (l / (r as f64)).into()),
(Value::Int(l), Value::Float(r)) => (true, ((l as f64) / r.into_inner()).into()),
(Value::Float(l), Value::Float(r)) => (true, (l.into_inner() / r.into_inner()).into()),
(_, _) => return Err(CozoError::InvalidArgument)
})
}
@ -425,7 +510,7 @@ pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
return Ok((true, Value::Null));
}
if !le || !re {
return Ok((false, Apply(value::OP_EQ.into(), vec![left, right])));
return Ok((false, Value::Apply(value::OP_EQ.into(), vec![left, right])));
}
Ok((true, (left == right).into()))
}
@ -437,7 +522,7 @@ pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
return Ok((true, Value::Null));
}
if !le || !re {
return Ok((false, Apply(value::OP_NE.into(), vec![left, right])));
return Ok((false, Value::Apply(value::OP_NE.into(), vec![left, right])));
}
Ok((true, (left != right).into()))
}
@ -473,7 +558,7 @@ pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
Value::List(_) |
Value::Dict(_) => Err(Err(CozoError::InvalidArgument)),
cur_val @ (Value::Variable(_) |
Apply(_, _)) => {
Value::Apply(_, _)) => {
collected.push(cur_val);
Ok((false, has_null, collected))
}
@ -534,7 +619,7 @@ pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
Value::List(_) |
Value::Dict(_) => Err(Err(CozoError::InvalidArgument)),
cur_val @ (Value::Variable(_) |
Apply(_, _)) => {
Value::Apply(_, _)) => {
collected.push(cur_val);
Ok((false, has_null, collected))
}
@ -807,7 +892,7 @@ mod tests {
// match self.visit_expr(a)? {
// Const(Null) => Const(Bool(true)),
// Const(_) => Const(Bool(false)),
// v => Apply(Op::IsNull, vec![v])
// v => Value::Apply(Op::IsNull, vec![v])
// }
// }
// _ => unreachable!()
@ -820,7 +905,7 @@ mod tests {
// match self.visit_expr(a)? {
// Const(Null) => Const(Bool(false)),
// Const(_) => Const(Bool(true)),
// v => Apply(Op::IsNull, vec![v])
// v => Value::Apply(Op::IsNull, vec![v])
// }
// }
// _ => unreachable!()

@ -1,90 +0,0 @@
// impl<S: Storage> Evaluator<S>
// where Evaluator<S>: Env<Structured> {
//
// fn pow_exprs<'a>(&self, exprs: &[Expr<'a>]) -> Result<Expr<'a>> {
// match exprs {
// [a, b] => {
// let a = self.visit_expr(a)?;
// let b = self.visit_expr(b)?;
// if a == Const(Null) || b == Const(Null) {
// return Ok(Const(Null));
// }
// match (a, b) {
// (Const(a), Const(b)) => {
// match (a, b) {
// (Int(a), Int(b)) => Ok(Const(Float((a as f64).powf(b as f64)))),
// (Float(a), Int(b)) => Ok(Const(Float(a.powi(b as i32)))),
// (Int(a), Float(b)) => Ok(Const(Float((a as f64).powf(b)))),
// (Float(a), Float(b)) => Ok(Const(Float(a.powf(b)))),
// (_, _) => Err(CozoError::TypeError)
// }
// }
// (a, b) => Ok(Apply(Op::Pow, vec![a, b]))
// }
// }
// _ => unreachable!()
// }
// }
//
// fn coalesce_exprs<'a>(&self, exprs: &[Expr<'a>]) -> Result<Expr<'a>> {
// match exprs {
// [a, b] => {
// let a = self.visit_expr(a)?;
// let b = self.visit_expr(b)?;
// if a == Const(Null) {
// return Ok(b);
// }
// if b == Const(Null) {
// return Ok(a);
// }
// if let a @ Const(_) = a {
// return Ok(a);
// }
// return Ok(Apply(Op::Coalesce, vec![a, b]));
// }
// _ => unreachable!()
// }
// }
//
// fn negate_expr<'a>(&self, exprs: &[Expr<'a>]) -> Result<Expr<'a>> {
// Ok(match exprs {
// [a] => {
// match self.visit_expr(a)? {
// Const(Null) => Const(Null),
// Const(Bool(b)) => Const(Bool(!b)),
// Const(_) => return Err(TypeError),
// Apply(Op::Neg, v) => v.into_iter().next().unwrap(),
// Apply(Op::IsNull, v) => Apply(Op::NotNull, v),
// Apply(Op::NotNull, v) => Apply(Op::IsNull, v),
// Apply(Op::Eq, v) => Apply(Op::Neq, v),
// Apply(Op::Neq, v) => Apply(Op::Eq, v),
// Apply(Op::Gt, v) => Apply(Op::Le, v),
// Apply(Op::Ge, v) => Apply(Op::Lt, v),
// Apply(Op::Le, v) => Apply(Op::Gt, v),
// Apply(Op::Lt, v) => Apply(Op::Ge, v),
// v => Apply(Op::Neg, vec![v])
// }
// }
// _ => unreachable!()
// })
// }
//
// fn minus_expr<'a>(&self, exprs: &[Expr<'a>]) -> Result<Expr<'a>> {
// Ok(match exprs {
// [a] => {
// match self.visit_expr(a)? {
// Const(Null) => Const(Null),
// Const(Int(i)) => Const(Int(-i)),
// Const(Float(f)) => Const(Float(-f)),
// Const(_) => return Err(TypeError),
// Apply(Op::Minus, v) => v.into_iter().next().unwrap(),
// v => Apply(Op::Minus, vec![v])
// }
// }
// _ => unreachable!()
// })
// }
//
//
// }
//
Loading…
Cancel
Save