associated tables

main
Ziyang Hu 2 years ago
parent 7b5980f721
commit fd32670b35

@ -8,6 +8,7 @@ use crate::relation::tuple::{OwnTuple, Tuple};
use crate::relation::typing::Typing;
use crate::relation::value::{Value};
use crate::error::{CozoError, Result};
use crate::error::CozoError::LogicError;
use crate::relation::data::DataKind;
use crate::parser::{Parser, Rule};
use crate::parser::text_identifier::build_name_in_def;
@ -32,7 +33,7 @@ pub trait Environment<'t, T: AsRef<[u8]>> where Self: Sized {
self.define_data(name, data, in_root)
}
fn resolve(&self, name: &str) -> Result<Option<Tuple<T>>>;
fn resolve_related_tables(&self, name: &str) -> Result<Vec<Tuple<T>>>;
fn resolve_related_tables(&self, name: &str) -> Result<Vec<(String, Tuple<SlicePtr>)>>;
fn resolve_param(&self, name: &str) -> Result<Value>;
fn resolve_value(&self, name: &str) -> Result<Option<Value>> {
if name.starts_with('&') {
@ -821,6 +822,45 @@ impl<'a, 't> Environment<'t, SlicePtr> for Session<'a, 't> {
Ok(res)
}
fn resolve_related_tables(&self, name: &str) -> Result<Vec<(String, Tuple<SlicePtr>)>> {
let mut prefix = Tuple::with_prefix(0);
prefix.push_null();
prefix.push_str(name);
let mut assocs = vec![];
let it = self.txn.iterator(true, &self.perm_cf);
it.seek(&prefix);
for val in it.keys() {
let cur = Tuple::new(val);
if !cur.starts_with(&prefix) {
break;
}
let name = cur.get_text(4).ok_or_else(|| LogicError("Bad data".to_string()))?;
if let Some(data) = self.resolve(&name)? {
if data.data_kind()? == DataKind::Assoc {
assocs.push((name.to_string(), data));
}
}
}
let it = self.txn.iterator(false, &self.temp_cf);
it.seek(&prefix);
for val in it.keys() {
let cur = Tuple::new(val);
if !cur.starts_with(&prefix) {
break;
}
let name = cur.get_text(4).ok_or_else(|| LogicError("Bad data".to_string()))?;
if let Some(data) = self.resolve(&name)? {
if data.data_kind()? == DataKind::Assoc {
assocs.push((name.to_string(), data));
}
}
}
Ok(assocs)
}
fn resolve_param(&self, name: &str) -> Result<Value> {
let text = self.params.get(name).ok_or_else(|| CozoError::UndefinedParam(name.to_string()))?;
let pair = Parser::parse(Rule::expr, text)?.next().unwrap();
@ -850,15 +890,6 @@ impl<'a, 't> Environment<'t, SlicePtr> for Session<'a, 't> {
Ok(())
}
fn define_raw_key(&mut self, key: OwnTuple, in_root: bool) -> Result<()> {
if in_root {
self.txn.put(true, &self.perm_cf, key, "")?;
} else {
self.txn.put(false, &self.temp_cf, key, "")?;
}
Ok(())
}
fn define_data(&mut self, name: &str, data: OwnTuple, in_root: bool) -> Result<()> {
let key = self.encode_definable_key(name, in_root);
if in_root {
@ -873,8 +904,13 @@ impl<'a, 't> Environment<'t, SlicePtr> for Session<'a, 't> {
Ok(())
}
fn resolve_related_tables(&self, name: &str) -> Result<Vec<Tuple<SlicePtr>>> {
todo!()
fn define_raw_key(&mut self, key: OwnTuple, in_root: bool) -> Result<()> {
if in_root {
self.txn.put(true, &self.perm_cf, key, "")?;
} else {
self.txn.put(false, &self.temp_cf, key, "")?;
}
Ok(())
}
}

@ -1,7 +1,6 @@
use std::borrow::Cow;
use std::collections::{BTreeMap, BTreeSet};
use std::collections::{BTreeMap};
use pest::iterators::Pair;
use cozorocks::SlicePtr;
use crate::db::engine::Session;
use crate::db::eval::Environment;
use crate::error::CozoError::LogicError;
@ -9,7 +8,6 @@ use crate::error::{CozoError, Result};
use crate::parser::Rule;
use crate::parser::text_identifier::build_name_in_def;
use crate::relation::data::DataKind;
use crate::relation::tuple::{OwnTuple, Tuple};
use crate::relation::value::Value;
impl<'a, 't> Session<'a, 't> {
@ -56,13 +54,12 @@ impl<'a, 't> Session<'a, 't> {
struct MutationManager<'a, 'b, 't> {
sess: &'a Session<'b, 't>,
cache: BTreeMap<String, ()>,
categorized: BTreeMap<String, BTreeSet<OwnTuple>>,
default_tbl: Option<String>,
}
impl<'a, 'b, 't> MutationManager<'a, 'b, 't> {
fn new(sess: &'a Session<'b, 't>, default_tbl: Option<String>) -> Self {
Self { sess, cache: BTreeMap::new(), categorized: BTreeMap::new(), default_tbl }
Self { sess, cache: BTreeMap::new(), default_tbl }
}
fn add(&mut self, val_map: BTreeMap<Cow<str>, Value>) -> Result<()> {
let tbl_name = match val_map.get("_type") {
@ -87,7 +84,10 @@ impl<'a, 'b, 't> MutationManager<'a, 'b, 't> {
}
_ => return Err(LogicError("Cannot insert into non-tables".to_string()))
}
let related = self.sess.resolve_related_tables(tbl_name)?;
for t in related {
println!("Found assoc {:?}", t);
}
}
}
// self.cache.insert(tbl_name.to_string(), ());
@ -124,6 +124,14 @@ mod tests {
create edge (Person)-[Friend]->(Person) {
relation: ?Text
}
create assoc WorkInfo : Person {
work_id: Int
}
create assoc RelationshipData: Person {
status: Text
}
"#;
for p in Parser::parse(Rule::file, s).unwrap() {
if p.as_rule() == Rule::EOI {
@ -138,7 +146,10 @@ mod tests {
let mut sess = engine.session().unwrap();
println!("{:#?}", sess.resolve("Person"));
let s = r#"
insert [{id: 1, name: "Jack"}, {id: 2, name: "Joe", habits: ["Balls"]}] as Person;
insert [
{id: 1, name: "Jack"},
{id: 2, name: "Joe", habits: ["Balls"]}
] as Person;
"#;
let p = Parser::parse(Rule::file, s).unwrap().next().unwrap();
sess.run_mutation(p).unwrap();

@ -2,7 +2,6 @@ use std::borrow::Borrow;
use crate::relation::tuple::Tuple;
use crate::error::{CozoError, Result};
use crate::relation::typing::Typing;
use crate::relation::value::Value;
#[repr(u32)]
#[derive(Ord, PartialOrd, Eq, PartialEq, Debug)]

Loading…
Cancel
Save