From 375fd6b7b8fc194092a06144ac824667e6f0cfcd Mon Sep 17 00:00:00 2001 From: Ziyang Hu Date: Fri, 6 May 2022 17:34:28 +0800 Subject: [PATCH] fix coalesce partial eval; going through --- TODO.md | 6 ++++++ src/db/eval.rs | 34 ++++++++++++++++++---------------- src/db/plan.rs | 33 ++++++++++++++++++++++++++------- src/db/query.rs | 1 - 4 files changed, 50 insertions(+), 24 deletions(-) create mode 100644 TODO.md diff --git a/TODO.md b/TODO.md new file mode 100644 index 00000000..77a7724d --- /dev/null +++ b/TODO.md @@ -0,0 +1,6 @@ +## Methods + +* Conversion methods + * `v.format()` + * `v.parse_int()` + * `v.parse_float()` \ No newline at end of file diff --git a/src/db/eval.rs b/src/db/eval.rs index d994be94..333e8cd1 100644 --- a/src/db/eval.rs +++ b/src/db/eval.rs @@ -245,30 +245,32 @@ impl<'s> Session<'s> { table_bindings: &AccessorMap) -> Result<(bool, Value<'a>)> { let res = args.into_iter().try_fold(vec![], |mut accum, cur| { match self.partial_eval(cur, params, table_bindings) { - Ok((ev, cur)) => { + Ok((ev, cur)) => if ev { if cur == Value::Null { Ok(accum) } else { - Err(Ok(cur)) + accum.push(cur); + Err(Ok(accum)) } } 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))) - } + 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(Ok(accum)) => match accum.len() { + 0 => Ok((true, Value::Null)), + 1 => Ok((true, accum.into_iter().next().unwrap())), + _ => Ok((false, Value::Apply(value::OP_COALESCE.into(), accum))) + }, Err(Err(e)) => Err(e) } } @@ -915,9 +917,9 @@ impl<'s> Session<'s> { fn concat_values<'a>(&self, args: Vec>, tuples: &'a [(Tuple, Tuple)]) -> Result> { let mut coll = vec![]; for v in args.into_iter() { - let v = self.tuple_eval(v, tuples)?; + let v = self.tuple_eval(v, tuples)?; match v { - Value::Null => {}, + Value::Null => {} Value::List(l) => coll.extend(l), _ => return Err(CozoError::InvalidArgument) } @@ -934,7 +936,7 @@ impl<'s> Session<'s> { let (ev, val) = self.partial_eval(val, params, table_bindings)?; evaluated = ev && evaluated; match val { - Value::Null => {}, + Value::Null => {} Value::List(l) => { if cur_ret.is_empty() { cur_ret = l; @@ -972,7 +974,7 @@ impl<'s> Session<'s> { for v in args.into_iter() { let v = self.tuple_eval(v, tuples)?; match v { - Value::Null => {}, + Value::Null => {} Value::Dict(d) => coll.extend(d), _ => return Err(CozoError::InvalidArgument) } @@ -989,7 +991,7 @@ impl<'s> Session<'s> { let (ev, val) = self.partial_eval(val, params, table_bindings)?; evaluated = ev && evaluated; match val { - Value::Null => {}, + Value::Null => {} Value::Dict(d) => { if cur_ret.is_empty() { cur_ret = d; diff --git a/src/db/plan.rs b/src/db/plan.rs index 4e2a6ba3..ce9766ad 100644 --- a/src/db/plan.rs +++ b/src/db/plan.rs @@ -142,6 +142,7 @@ mod tests { use crate::db::query::FromEl; use crate::relation::value::Value; use crate::error::Result; + use crate::relation::tuple::{OwnTuple, Tuple}; #[test] fn pair_value() -> Result<()> { @@ -183,22 +184,40 @@ mod tests { FromEl::Simple(s) => s, FromEl::Chain(_) => panic!() }; - let s = "select {id: e.id, data: e.first_name ++ ' ' ++ e.last_name}"; + let s = r#"select {id: e.id, + full_name: e.first_name ++ ' ' ++ e.last_name, bibio_name: e.last_name ++ ', ' + ++ e.first_name ++ ': ' ++ (e.phone_number ~ 'N.A.')}"#; let p = Parser::parse(Rule::select_pattern, s).unwrap().next().unwrap(); - println!("{:#?}", p); let sel_pat = sess.parse_select_pattern(p).unwrap(); - println!("{:?}", sel_pat); let amap = sess.base_relation_to_accessor_map(&from_pat.table, &from_pat.binding, &from_pat.info); - println!("VALS ORIGINAL {:?}", sel_pat.vals); let (_, vals) = sess.partial_eval(sel_pat.vals,& Default::default(), &amap).unwrap(); - println!("VALS AFTER 1 {:?}", vals); - let (vals, rel_tbls) = vals.extract_relevant_tables().unwrap(); - println!("VALS AFTER 2 {:?}", vals); + let (vals, mut rel_tbls) = vals.extract_relevant_tables().unwrap(); + println!("VALS AFTER 2 {}", vals); println!("{:?}", from_pat); println!("{:?}", amap); println!("{:?}", rel_tbls); + + let tbl = rel_tbls.pop().unwrap(); + let key_prefix = OwnTuple::with_prefix(tbl.id as u32); + let it = sess.txn.iterator(true, &sess.perm_cf); + it.seek(&key_prefix); + while it.is_valid() { + if let Some((k, v)) = it.pair() { + let k = Tuple::new(k); + if !k.starts_with(&key_prefix) { + break; + } + let v = Tuple::new(v); + let tpair = [(k, v)]; + let extracted = sess.tuple_eval(vals.clone(), &tpair).unwrap(); + println!("{:?}", extracted); + it.next(); + } else { + break + } + } } drop(engine); let _ = fs::remove_dir_all(db_path); diff --git a/src/db/query.rs b/src/db/query.rs index b4c41e2c..297d3943 100644 --- a/src/db/query.rs +++ b/src/db/query.rs @@ -204,7 +204,6 @@ impl<'a> Session<'a> { let mut inner = p.into_inner(); let name = parse_string(inner.next().unwrap())?; let val_pair = inner.next().unwrap(); - println!("{:?}", val_pair); let val = Value::from_pair(val_pair)?; collected_vals.insert(name.into(), val); }