edge definition

main
Ziyang Hu 2 years ago
parent 3368fc741c
commit 4c37f1b6ff

@ -1,4 +1,5 @@
use std::collections::{BTreeMap, HashSet};
use std::process::id;
use pest::iterators::{Pair, Pairs};
use cozorocks::{SlicePtr, StatusCode};
use crate::db::engine::{Session};
@ -7,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::UnexpectedDataKind;
use crate::relation::data::DataKind;
use crate::parser::Rule;
use crate::parser::text_identifier::build_name_in_def;
@ -44,17 +46,15 @@ pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
fn parse_definition(&self, pair: Pair<Rule>) -> Result<(String, OwnTuple)> {
match pair.as_rule() {
Rule::node_def => self.parse_node_def(pair.into_inner()),
Rule::edge_def => todo!(),
Rule::edge_def => self.parse_edge_def(pair.into_inner()),
Rule::associate_def => todo!(),
Rule::index_def => todo!(),
Rule::type_def => todo!(),
_ => unreachable!()
}
}
fn parse_node_def(&self, mut pairs: Pairs<Rule>) -> Result<(String, OwnTuple)> {
let name = build_name_in_def(pairs.next().unwrap(), true)?;
let col_pairs = pairs.next().unwrap().into_inner();
let col_res = col_pairs.into_iter().map(|p| {
fn parse_cols(&self, pair: Pair<Rule>) -> Result<(Typing, Typing)> {
let col_res = pair.into_inner().map(|p| {
let mut ps = p.into_inner();
let mut name_ps = ps.next().unwrap().into_inner();
let is_key;
@ -77,6 +77,63 @@ pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
let (keys, cols): (Vec<_>, Vec<_>) = col_res.iter().partition(|(is_key, _, _)| *is_key);
let keys_typing = Typing::NamedTuple(keys.iter().map(|(_, n, t)| (n.to_string(), t.clone())).collect());
let vals_typing = Typing::NamedTuple(cols.iter().map(|(_, n, t)| (n.to_string(), t.clone())).collect());
Ok((keys_typing, vals_typing))
}
fn parse_edge_def(&self, mut pairs: Pairs<Rule>) -> Result<(String, OwnTuple)> {
let src_name = build_name_in_def(pairs.next().unwrap(), true)?;
let src_tbl = match self.resolve(&src_name)? {
Some(res) => res,
None => return Err(CozoError::UndefinedType(src_name))
};
let (kind, src_id) = Self::extract_table_id(src_tbl)?;
if kind != DataKind::Node {
return Err(CozoError::UnexpectedDataKind(kind));
}
let name = build_name_in_def(pairs.next().unwrap(), true)?;
let dst_name = build_name_in_def(pairs.next().unwrap(), true)?;
let dst_tbl = match self.resolve(&dst_name)? {
Some(res) => res,
None => return Err(CozoError::UndefinedType(dst_name))
};
let (kind, dst_id) = Self::extract_table_id(dst_tbl)?;
if kind != DataKind::Node {
return Err(CozoError::UnexpectedDataKind(kind));
}
let (keys_typing, vals_typing) = match pairs.next() {
Some(p) => self.parse_cols(p)?,
None => (Typing::NamedTuple(vec![]), Typing::NamedTuple(vec![]))
};
let mut tuple = Tuple::with_data_prefix(DataKind::Edge);
tuple.push_str(keys_typing.to_string());
tuple.push_str(vals_typing.to_string());
tuple.push_null(); // TODO default values for keys
tuple.push_null(); // TODO default values for cols
tuple.push_uint(src_id);
tuple.push_uint(dst_id);
Ok((name, tuple))
}
fn extract_table_id(src_tbl: Tuple<T>) -> Result<(DataKind, u64)> {
let kind = src_tbl.data_kind()?;
let id_idx = match kind {
DataKind::DataTuple => return Err(CozoError::UnexpectedDataKind(kind)),
DataKind::Node => 4,
DataKind::Edge => 6,
DataKind::Associate => todo!(),
DataKind::Index => todo!(),
DataKind::Value => return Err(CozoError::UnexpectedDataKind(kind)),
DataKind::TypeAlias => return Err(CozoError::UnexpectedDataKind(kind)),
};
let table_id = match src_tbl.get(id_idx).expect("Data corrupt") {
Value::UInt(u) => u,
_ => panic!("Data corrupt")
};
Ok((kind, table_id))
}
fn parse_node_def(&self, mut pairs: Pairs<Rule>) -> Result<(String, OwnTuple)> {
let name = build_name_in_def(pairs.next().unwrap(), true)?;
let col_pair = pairs.next().unwrap();
let (keys_typing, vals_typing) = self.parse_cols(col_pair)?;
let mut tuple = Tuple::with_data_prefix(DataKind::Node);
tuple.push_str(keys_typing.to_string());
tuple.push_str(vals_typing.to_string());
@ -312,5 +369,7 @@ mod tests {
let mut env = MemoryEnv::default();
env.run_definition(first_t).unwrap();
println!("{:?}", env.resolve("Person"));
env.run_definition(second_t).unwrap();
println!("{:?}", env.resolve("Friend"));
}
}

@ -3,6 +3,7 @@ use std::time::SystemTimeError;
use thiserror::Error;
use cozorocks::BridgeError;
use crate::parser::Rule;
use crate::relation::data::DataKind;
#[derive(Error, Debug)]
pub enum CozoError {
@ -27,6 +28,9 @@ pub enum CozoError {
#[error("Undefined data kind {0}")]
UndefinedDataKind(u32),
#[error("Unexpected data kind {0:?}")]
UnexpectedDataKind(DataKind),
#[error("Bad data format {0:?}")]
BadDataFormat(Vec<u8>),

@ -5,7 +5,7 @@ use crate::relation::typing::Typing;
use crate::relation::value::Value;
#[repr(u32)]
#[derive(Ord, PartialOrd, Eq, PartialEq)]
#[derive(Ord, PartialOrd, Eq, PartialEq, Debug)]
pub enum DataKind {
DataTuple = 0,
Node = 1,

@ -1,8 +1,10 @@
use std::borrow::{Cow};
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::convert::Infallible;
use std::fmt::{Debug, Formatter};
use std::hash::{Hash, Hasher};
use std::ptr::write;
use uuid::Uuid;
use crate::relation::data::DataKind;
use crate::relation::value::{Tag, Value};
@ -204,7 +206,17 @@ impl<T: AsRef<[u8]>> Tuple<T> {
impl<T: AsRef<[u8]>> Debug for Tuple<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "<{}>{:?}", self.get_prefix(), self.iter().collect::<Vec<_>>())
match self.data_kind() {
Ok(data_kind) => {
write!(f, "Tuple<{}:{:?}>{{", self.get_prefix(), data_kind)?;
}
Err(_) => {
write!(f, "Tuple<{}>[", self.get_prefix())?;
}
}
let strings = self.iter().enumerate().map(|(i, v)| format!("{}: {}", i, v))
.collect::<Vec<_>>().join(", ");
write!(f, "{}}}", strings)
}
}

Loading…
Cancel
Save