From 62a5876cc2782922d950d0df793bf5a3458aac2f Mon Sep 17 00:00:00 2001 From: Ziyang Hu Date: Mon, 2 May 2022 17:00:31 +0800 Subject: [PATCH] implement params --- src/db/eval.rs | 68 +++++++++++++++++++++---------------------- src/db/mutation.rs | 20 ++++++++----- src/relation/value.rs | 12 ++++++-- 3 files changed, 57 insertions(+), 43 deletions(-) diff --git a/src/db/eval.rs b/src/db/eval.rs index 982a9de2..34ec94f2 100644 --- a/src/db/eval.rs +++ b/src/db/eval.rs @@ -257,8 +257,8 @@ impl<'s> Session<'s> { } self.define_data(&name, tuple, in_root) } - pub fn partial_eval<'a>(&self, value: Value<'a>, params: BTreeMap>, - _table_bindings: BTreeMap) -> Result<(bool, Value<'a>)> { + pub fn partial_eval<'a>(&self, value: Value<'a>, params: &BTreeMap>, + _table_bindings: &BTreeMap) -> Result<(bool, Value<'a>)> { match value { v @ (Value::Null | Value::Bool(_) | @@ -271,7 +271,7 @@ impl<'s> Session<'s> { let init_vec = Vec::with_capacity(l.len()); let res: Result<(bool, Vec)> = l.into_iter() .try_fold((true, init_vec), |(is_evaluated, mut accum), val| { - let (ev, new_val) = self.partial_eval(val, Default::default(), Default::default())?; + let (ev, new_val) = self.partial_eval(val, &Default::default(), &Default::default())?; accum.push(new_val); Ok((ev && is_evaluated, accum)) }); @@ -281,7 +281,7 @@ impl<'s> Session<'s> { Value::Dict(d) => { let res: Result<(bool, BTreeMap, Value>)> = d.into_iter() .try_fold((true, BTreeMap::new()), |(is_evaluated, mut accum), (k, v)| { - let (ev, new_val) = self.partial_eval(v, Default::default(), Default::default())?; + let (ev, new_val) = self.partial_eval(v, &Default::default(), &Default::default())?; accum.insert(k, new_val); Ok((ev && is_evaluated, accum)) }); @@ -328,7 +328,7 @@ impl<'s> Session<'s> { fn coalesce_values<'a>(&self, args: Vec>) -> Result<(bool, Value<'a>)> { let res = args.into_iter().try_fold(vec![], |mut accum, cur| { - match self.partial_eval(cur, Default::default(), Default::default()) { + match self.partial_eval(cur, &Default::default(), &Default::default()) { Ok((ev, cur)) => { if ev { if cur == Value::Null { @@ -359,8 +359,8 @@ impl<'s> Session<'s> { fn add_values<'a>(&self, args: Vec>) -> Result<(bool, Value<'a>)> { let mut args = args.into_iter(); - let (le, left) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; - let (re, right) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; + let (le, left) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; + let (re, right) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; if left == Value::Null || right == Value::Null { return Ok((true, Value::Null)); } @@ -378,8 +378,8 @@ impl<'s> Session<'s> { } fn sub_values<'a>(&self, args: Vec>) -> Result<(bool, Value<'a>)> { let mut args = args.into_iter(); - let (le, left) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; - let (re, right) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; + let (le, left) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; + let (re, right) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; if left == Value::Null || right == Value::Null { return Ok((true, Value::Null)); } @@ -396,7 +396,7 @@ impl<'s> Session<'s> { } fn minus_values<'a>(&self, args: Vec>) -> Result<(bool, Value<'a>)> { let mut args = args.into_iter(); - let (le, left) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; + let (le, left) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; if left == Value::Null { return Ok((true, Value::Null)); } @@ -411,7 +411,7 @@ impl<'s> Session<'s> { } fn negate_values<'a>(&self, args: Vec>) -> Result<(bool, Value<'a>)> { let mut args = args.into_iter(); - let (le, left) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; + let (le, left) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; if left == Value::Null { return Ok((true, Value::Null)); } @@ -425,8 +425,8 @@ impl<'s> Session<'s> { } fn pow_values<'a>(&self, args: Vec>) -> Result<(bool, Value<'a>)> { let mut args = args.into_iter(); - let (le, left) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; - let (re, right) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; + let (le, left) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; + let (re, right) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; if left == Value::Null || right == Value::Null { return Ok((true, Value::Null)); } @@ -443,8 +443,8 @@ impl<'s> Session<'s> { } fn gt_values<'a>(&self, args: Vec>) -> Result<(bool, Value<'a>)> { let mut args = args.into_iter(); - let (le, left) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; - let (re, right) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; + let (le, left) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; + let (re, right) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; if left == Value::Null || right == Value::Null { return Ok((true, Value::Null)); } @@ -461,8 +461,8 @@ impl<'s> Session<'s> { } fn lt_values<'a>(&self, args: Vec>) -> Result<(bool, Value<'a>)> { let mut args = args.into_iter(); - let (le, left) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; - let (re, right) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; + let (le, left) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; + let (re, right) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; if left == Value::Null || right == Value::Null { return Ok((true, Value::Null)); } @@ -479,8 +479,8 @@ impl<'s> Session<'s> { } fn ge_values<'a>(&self, args: Vec>) -> Result<(bool, Value<'a>)> { let mut args = args.into_iter(); - let (le, left) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; - let (re, right) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; + let (le, left) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; + let (re, right) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; if left == Value::Null || right == Value::Null { return Ok((true, Value::Null)); } @@ -497,8 +497,8 @@ impl<'s> Session<'s> { } fn le_values<'a>(&self, args: Vec>) -> Result<(bool, Value<'a>)> { let mut args = args.into_iter(); - let (le, left) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; - let (re, right) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; + let (le, left) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; + let (re, right) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; if left == Value::Null || right == Value::Null { return Ok((true, Value::Null)); } @@ -515,8 +515,8 @@ impl<'s> Session<'s> { } fn mod_values<'a>(&self, args: Vec>) -> Result<(bool, Value<'a>)> { let mut args = args.into_iter(); - let (le, left) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; - let (re, right) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; + let (le, left) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; + let (re, right) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; if left == Value::Null || right == Value::Null { return Ok((true, Value::Null)); } @@ -530,8 +530,8 @@ impl<'s> Session<'s> { } fn mul_values<'a>(&self, args: Vec>) -> Result<(bool, Value<'a>)> { let mut args = args.into_iter(); - let (le, left) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; - let (re, right) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; + let (le, left) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; + let (re, right) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; if left == Value::Null || right == Value::Null { return Ok((true, Value::Null)); } @@ -548,8 +548,8 @@ impl<'s> Session<'s> { } fn div_values<'a>(&self, args: Vec>) -> Result<(bool, Value<'a>)> { let mut args = args.into_iter(); - let (le, left) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; - let (re, right) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; + let (le, left) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; + let (re, right) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; if left == Value::Null || right == Value::Null { return Ok((true, Value::Null)); } @@ -566,8 +566,8 @@ impl<'s> Session<'s> { } fn eq_values<'a>(&self, args: Vec>) -> Result<(bool, Value<'a>)> { let mut args = args.into_iter(); - let (le, left) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; - let (re, right) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; + let (le, left) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; + let (re, right) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; if left == Value::Null || right == Value::Null { return Ok((true, Value::Null)); } @@ -578,8 +578,8 @@ impl<'s> Session<'s> { } fn ne_values<'a>(&self, args: Vec>) -> Result<(bool, Value<'a>)> { let mut args = args.into_iter(); - let (le, left) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; - let (re, right) = self.partial_eval(args.next().unwrap(), Default::default(), Default::default())?; + let (le, left) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; + let (re, right) = self.partial_eval(args.next().unwrap(), &Default::default(), &Default::default())?; if left == Value::Null || right == Value::Null { return Ok((true, Value::Null)); } @@ -589,7 +589,7 @@ impl<'s> Session<'s> { Ok((true, (left != right).into())) } fn or_values<'a>(&self, args: Vec>) -> Result<(bool, Value<'a>)> { - let res = args.into_iter().map(|v| self.partial_eval(v, Default::default(), Default::default())) + let res = args.into_iter().map(|v| self.partial_eval(v, &Default::default(), &Default::default())) .try_fold( (true, false, vec![]), |(is_evaluated, has_null, mut collected), x| { @@ -649,7 +649,7 @@ impl<'s> Session<'s> { } } fn and_values<'a>(&self, args: Vec>) -> Result<(bool, Value<'a>)> { - let res = args.into_iter().map(|v| self.partial_eval(v, Default::default(), Default::default())) + let res = args.into_iter().map(|v| self.partial_eval(v, &Default::default(), &Default::default())) .try_fold( (true, false, vec![]), |(is_evaluated, has_null, mut collected), x| { @@ -1043,7 +1043,7 @@ mod tests { let (b, v) = sess.partial_eval( Value::from_pair(Parser::parse(Rule::expr, s) .unwrap().next().unwrap()).unwrap(), - Default::default(), Default::default()).unwrap(); + &Default::default(), &Default::default()).unwrap(); (b, v.to_static()) }; diff --git a/src/db/mutation.rs b/src/db/mutation.rs index 2d89c99c..c00aecc1 100644 --- a/src/db/mutation.rs +++ b/src/db/mutation.rs @@ -36,7 +36,7 @@ enum MutationKind { } impl<'a> Session<'a> { - pub fn run_mutation(&mut self, pair: Pair) -> Result<()> { + pub fn run_mutation(&mut self, pair: Pair, params: &BTreeMap) -> Result<()> { let mut pairs = pair.into_inner(); let kind = match pairs.next().unwrap().as_rule() { Rule::upsert => MutationKind::Upsert, @@ -45,7 +45,8 @@ impl<'a> Session<'a> { }; let (evaluated, expr) = self.partial_eval( Value::from_pair(pairs.next().unwrap())?, - Default::default(), Default::default())?; + params, + &Default::default())?; if !evaluated { return Err(LogicError("Mutation encountered unevaluated expression".to_string())); } @@ -226,12 +227,14 @@ impl<'a, 'b> MutationManager<'a, 'b> { #[cfg(test)] mod tests { + use std::collections::BTreeMap; use std::fs; use std::time::Instant; use pest::Parser as PestParser; use crate::db::engine::Engine; use crate::parser::{Parser, Rule}; use crate::relation::tuple::Tuple; + use crate::relation::value::Value; #[test] fn test_mutation() { @@ -280,9 +283,9 @@ mod tests { ] as Person; "#; let p = Parser::parse(Rule::file, s).unwrap().next().unwrap(); - assert!(sess.run_mutation(p.clone()).is_ok()); + assert!(sess.run_mutation(p.clone(), &Default::default()).is_ok()); sess.commit().unwrap(); - assert!(sess.run_mutation(p.clone()).is_err()); + assert!(sess.run_mutation(p.clone(), &Default::default()).is_err()); sess.rollback().unwrap(); let it = sess.txn.iterator(true, &sess.perm_cf); it.to_first(); @@ -319,14 +322,17 @@ mod tests { { let mut sess = engine.session().unwrap(); let data = fs::read_to_string("test_data/hr.json").unwrap(); - let s = format!("insert {};", data); + let value = Value::parse_str(&data).unwrap(); + assert!(value.is_evaluated()); + let s = "insert $data;"; let p = Parser::parse(Rule::file, &s).unwrap().next().unwrap(); + let params = BTreeMap::from([("$data".into(), value)]); let start = Instant::now(); - assert!(sess.run_mutation(p.clone()).is_ok()); + assert!(sess.run_mutation(p.clone(), ¶ms).is_ok()); sess.commit().unwrap(); - assert!(sess.run_mutation(p.clone()).is_err()); + assert!(sess.run_mutation(p.clone(), ¶ms).is_err()); sess.rollback().unwrap(); let duration = start.elapsed(); diff --git a/src/relation/value.rs b/src/relation/value.rs index c4eed19a..3031e44b 100644 --- a/src/relation/value.rs +++ b/src/relation/value.rs @@ -4,10 +4,11 @@ use std::fmt::{Display, Formatter, Write}; use lazy_static::lazy_static; use pest::prec_climber::{Assoc, PrecClimber, Operator}; use ordered_float::OrderedFloat; +use pest::Parser as PestParser; use pest::iterators::Pair; use uuid::Uuid; -use crate::parser::Rule; -use crate::error::Result; +use crate::parser::{Parser, Rule}; +use crate::error::{CozoError, Result}; use crate::parser::number::parse_int; use crate::parser::text_identifier::parse_string; @@ -140,6 +141,13 @@ impl<'a> Value<'a> { pub fn from_pair(pair: pest::iterators::Pair<'a, Rule>) -> Result { PREC_CLIMBER.climb(pair.into_inner(), build_expr_primary, build_expr_infix) } + + #[inline] + pub fn parse_str(s: &'a str) -> Result { + let pair = Parser::parse(Rule::expr, s)?.next(); + let pair = pair.ok_or_else(|| CozoError::LogicError("Parsing value failed".to_string()))?; + Value::from_pair(pair) + } } impl From<()> for StaticValue {