fix resolving global variables

main
Ziyang Hu 2 years ago
parent 017025884a
commit bcb346f61d

@ -246,7 +246,7 @@ mod tests {
let engine2 = Engine::new(p2.to_string(), false); let engine2 = Engine::new(p2.to_string(), false);
assert!(engine2.is_ok()); assert!(engine2.is_ok());
println!("start ok"); println!("start ok");
let engine2 = Arc::new(Engine::new(p3.to_string(), true).unwrap()); let engine2 = Arc::new(Engine::new(p3.to_string(), false).unwrap());
{ {
for _i in 0..10 { for _i in 0..10 {
let _sess = engine2.session().unwrap(); let _sess = engine2.session().unwrap();
@ -274,9 +274,12 @@ mod tests {
sess.define_variable(&gname, &"xyz".into(), true).unwrap(); sess.define_variable(&gname, &"xyz".into(), true).unwrap();
sess.define_variable("pqr", &"xyz".into(), false).unwrap(); sess.define_variable("pqr", &"xyz".into(), false).unwrap();
} }
if i & 1 == 0 {
sess.commit().unwrap();
}
println!("pqr {:?}", sess.resolve("pqr")); println!("pqr {:?}", sess.resolve("pqr"));
println!("uvw {:?}", sess.resolve("uvw")); println!("uvw {:?}", sess.resolve("uvw"));
println!("aaa {:?}", sess.resolve(&gname)); println!("aaa {} {:?}", &gname, sess.resolve(&gname));
let it = sess.txn.iterator(false, &sess.temp_cf); let it = sess.txn.iterator(false, &sess.temp_cf);
it.to_first(); it.to_first();
// for (key, val) in it.iter() { // for (key, val) in it.iter() {
@ -286,14 +289,14 @@ mod tests {
for _ in 0..5000 { for _ in 0..5000 {
sess.pop_env().unwrap(); sess.pop_env().unwrap();
} }
if let Err(e) = sess.commit() { // if let Err(e) = sess.commit() {
println!("Err {} with {:?}", i, e); // println!("Err {} with {:?}", i, e);
} else { // } else {
println!("OK!!!! {}", i); // println!("OK!!!! {}", i);
sess.commit().unwrap(); // sess.commit().unwrap();
sess.commit().unwrap(); // sess.commit().unwrap();
println!("OK!!!!!!!! {}", i); // println!("OK!!!!!!!! {}", i);
} // }
// sess.commit().unwrap(); // sess.commit().unwrap();
// sess.commit().unwrap(); // sess.commit().unwrap();
println!("pqr {:?}", sess.resolve("pqr")); println!("pqr {:?}", sess.resolve("pqr"));

@ -1,49 +1,102 @@
use cozorocks::SlicePtr; use std::collections::BTreeMap;
use cozorocks::{SlicePtr, StatusCode};
use crate::db::engine::{Session}; use crate::db::engine::{Session};
use crate::relation::table::{Table}; use crate::relation::table::{Table};
use crate::relation::tuple::{Tuple}; use crate::relation::tuple::{Tuple};
use crate::relation::typing::Typing; use crate::relation::typing::Typing;
use crate::relation::value::Value; use crate::relation::value::Value;
use crate::error::Result; use crate::error::{CozoError, Result};
use crate::relation::data::DataKind; use crate::relation::data::DataKind;
pub trait Environment<T: AsRef<[u8]>> { pub trait Environment<T: AsRef<[u8]>> {
fn get_stack_depth(&self) -> i32;
fn push_env(&mut self); fn push_env(&mut self);
fn pop_env(&mut self) -> Result<()>; fn pop_env(&mut self) -> Result<()>;
fn define_variable(&mut self, name: &str, val: &Value, in_root: bool) -> Result<()>; fn define_variable(&mut self, name: &str, val: &Value, in_root: bool) -> Result<()> {
fn define_type_alias(&mut self, name: &str, typ: &Typing, in_root: bool) -> Result<()>; let mut data = Tuple::with_data_prefix(DataKind::Value);
fn define_table(&mut self, table: &Table, in_root: bool) -> Result<()>; data.push_value(val);
fn resolve(&self, name: &str) -> Result<Option<Tuple<T>>>; self.define_data(name, data, in_root)
fn delete_defined(&mut self, name: &str, in_root: bool) -> Result<()>;
} }
fn define_type_alias(&mut self, name: &str, typ: &Typing, in_root: bool) -> Result<()> {
let mut data = Tuple::with_data_prefix(DataKind::TypeAlias);
data.push_str(typ.to_string());
self.define_data(name, data, in_root)
}
impl<'a> Session<'a> { fn define_table(&mut self, table: &Table, in_root: bool) -> Result<()> {
todo!()
}
fn resolve(&self, name: &str) -> Result<Option<Tuple<T>>>;
fn delete_defined(&mut self, name: &str, in_root: bool) -> Result<()>;
fn define_data(&mut self, name: &str, data: Tuple<Vec<u8>>, in_root: bool) -> Result<()>;
fn encode_definable_key(&self, name: &str, in_root: bool) -> Tuple<Vec<u8>> { fn encode_definable_key(&self, name: &str, in_root: bool) -> Tuple<Vec<u8>> {
let depth_code = if in_root { 0 } else { self.stack_depth as i64 }; let depth_code = if in_root { 0 } else { self.get_stack_depth() as i64 };
let mut tuple = Tuple::with_null_prefix(); let mut tuple = Tuple::with_null_prefix();
tuple.push_str(name); tuple.push_str(name);
tuple.push_int(depth_code); tuple.push_int(depth_code);
tuple tuple
} }
}
fn define_data(&mut self, name: &str, data: Tuple<Vec<u8>>, in_root: bool) -> Result<()> { pub struct MemoryEnv {
let key = self.encode_definable_key(name, in_root); root: BTreeMap<String, Tuple<Vec<u8>>>,
if in_root { stack: Vec<BTreeMap<String, Tuple<Vec<u8>>>>,
self.txn.put(true, &self.perm_cf, key, data)?; }
} else {
let mut ikey = Tuple::with_null_prefix(); impl Default for MemoryEnv {
ikey.push_int(self.stack_depth as i64); fn default() -> Self {
ikey.push_str(name); MemoryEnv { root: BTreeMap::default(), stack: vec![BTreeMap::default()] }
self.txn.put(false, &self.temp_cf, key, data)?; }
self.txn.put(false, &self.temp_cf, ikey, "")?; }
impl Environment<Tuple<Vec<u8>>> for MemoryEnv {
fn get_stack_depth(&self) -> i32 {
-(self.stack.len() as i32)
}
fn push_env(&mut self) {
self.stack.push(BTreeMap::default());
}
fn pop_env(&mut self) -> Result<()> {
if self.stack.len() > 1 {
self.stack.pop();
} }
Ok(()) Ok(())
} }
fn define_variable(&mut self, name: &str, val: &Value, in_root: bool) -> Result<()> {
todo!()
}
fn define_type_alias(&mut self, name: &str, typ: &Typing, in_root: bool) -> Result<()> {
todo!()
}
fn define_table(&mut self, table: &Table, in_root: bool) -> Result<()> {
todo!()
}
fn resolve(&self, name: &str) -> Result<Option<Tuple<Tuple<Vec<u8>>>>> {
todo!()
}
fn delete_defined(&mut self, name: &str, in_root: bool) -> Result<()> {
todo!()
}
fn define_data(&mut self, name: &str, data: Tuple<Vec<u8>>, in_root: bool) -> Result<()> {
todo!()
}
} }
impl<'a> Environment<SlicePtr> for Session<'a> { impl<'a> Environment<SlicePtr> for Session<'a> {
fn get_stack_depth(&self) -> i32 {
self.stack_depth
}
fn push_env(&mut self) { fn push_env(&mut self) {
self.stack_depth -= 1; self.stack_depth -= 1;
} }
@ -76,48 +129,29 @@ impl<'a> Environment<SlicePtr> for Session<'a> {
Ok(()) Ok(())
} }
fn define_variable(&mut self, name: &str, val: &Value, in_root: bool) -> Result<()> {
let mut data = Tuple::with_data_prefix(DataKind::Value);
data.push_value(val);
self.define_data(name, data, in_root)
}
fn define_type_alias(&mut self, name: &str, typ: &Typing, in_root: bool) -> Result<()> {
let mut data = Tuple::with_data_prefix(DataKind::TypeAlias);
data.push_str(typ.to_string());
self.define_data(name, data, in_root)
}
fn define_table(&mut self, table: &Table, in_root: bool) -> Result<()> {
todo!()
}
fn resolve(&self, name: &str) -> Result<Option<Tuple<SlicePtr>>> { fn resolve(&self, name: &str) -> Result<Option<Tuple<SlicePtr>>> {
let mut tuple = Tuple::with_null_prefix(); let mut tuple = Tuple::with_null_prefix();
tuple.push_str(name); tuple.push_str(name);
let it = self.txn.iterator(false, &self.temp_cf); let it = self.txn.iterator(false, &self.temp_cf);
it.seek(&tuple); it.seek(&tuple);
Ok(match it.pair() { if let Some((tk, vk)) = it.pair() {
None => {
None
}
Some((tk, vk)) => {
let k = Tuple::new(tk); let k = Tuple::new(tk);
if k.starts_with(&tuple) { if k.starts_with(&tuple) {
println!("Resolved to key {:?}", k); return Ok(Some(Tuple::new(vk)));
Some(Tuple::new(vk)) }
} else {
None
} }
let root_key = self.encode_definable_key(name, true);
match self.txn.get(true, &self.perm_cf, root_key) {
Ok(root_res) => Ok(Some(Tuple::new(root_res))),
Err(e) if e.status.code == StatusCode::kNotFound => Ok(None),
Err(e) => Err(CozoError::Bridge(e))
} }
})
} }
fn delete_defined(&mut self, name: &str, in_root: bool) -> Result<()> { fn delete_defined(&mut self, name: &str, in_root: bool) -> Result<()> {
let key = self.encode_definable_key(name, in_root); let key = self.encode_definable_key(name, in_root);
if in_root { if in_root {
self.txn.del(true, &self.perm_cf, key)?; self.txn.del(true, &self.perm_cf, key)?;
} else { } else {
let it = self.txn.iterator(false, &self.temp_cf); let it = self.txn.iterator(false, &self.temp_cf);
it.seek(&key); it.seek(&key);
@ -129,7 +163,6 @@ impl<'a> Environment<SlicePtr> for Session<'a> {
ikey.push_value(&found_key_tuple.get(0).unwrap()); ikey.push_value(&found_key_tuple.get(0).unwrap());
self.txn.del(false, &self.temp_cf, found_key_tuple)?; self.txn.del(false, &self.temp_cf, found_key_tuple)?;
self.txn.del(false, &self.temp_cf, ikey)?; self.txn.del(false, &self.temp_cf, ikey)?;
} }
} }
} }
@ -137,4 +170,18 @@ impl<'a> Environment<SlicePtr> for Session<'a> {
Ok(()) Ok(())
} }
fn define_data(&mut self, name: &str, data: Tuple<Vec<u8>>, in_root: bool) -> Result<()> {
let key = self.encode_definable_key(name, in_root);
if in_root {
self.txn.put(true, &self.perm_cf, key, data)?;
} else {
let mut ikey = Tuple::with_null_prefix();
ikey.push_int(self.stack_depth as i64);
ikey.push_str(name);
self.txn.put(false, &self.temp_cf, key, data)?;
self.txn.put(false, &self.temp_cf, ikey, "")?;
}
Ok(())
}
} }

@ -8,3 +8,30 @@ impl<'a> Session<'a> {
todo!() todo!()
} }
} }
#[cfg(test)]
mod tests {
use super::*;
use crate::parser::Parser;
use pest::Parser as PestParser;
#[test]
fn node() {
let s = r#"
create node "Person" {
*id: Int,
name: String,
email: ?String,
habits: ?[?String]
}
create edge (Person)-[Friend]->(Person) {
relation: ?String
}
"#;
let mut parsed = Parser::parse(Rule::file, s).unwrap();
let first_t = parsed.next().unwrap().into_inner().next().unwrap();
let second_t = parsed.next().unwrap().into_inner().next().unwrap();
println!("{:#?}", first_t);
}
}
Loading…
Cancel
Save