Arc for value

main
Ziyang Hu 2 years ago
parent a4b00852a0
commit 20de063830

@ -318,6 +318,10 @@ pub struct DB {
pub default_write_options: WriteOptions, pub default_write_options: WriteOptions,
} }
unsafe impl Send for DB {}
unsafe impl Sync for DB {}
pub trait DBImpl { pub trait DBImpl {
fn open(options: Options, path: &Path) -> Result<DB>; fn open(options: Options, path: &Path) -> Result<DB>;
fn get_cf_handle(&self, name: impl AsRef<str>) -> Result<ColumnFamilyHandle>; fn get_cf_handle(&self, name: impl AsRef<str>) -> Result<ColumnFamilyHandle>;

@ -1,3 +1,4 @@
use std::sync::Arc;
use pest::iterators::{Pair}; use pest::iterators::{Pair};
use pest::Parser as PestParser; use pest::Parser as PestParser;
use pest::prec_climber::{Assoc, PrecClimber, Operator}; use pest::prec_climber::{Assoc, PrecClimber, Operator};
@ -59,6 +60,7 @@ pub enum Expr<'a> {
List(Vec<Expr<'a>>), List(Vec<Expr<'a>>),
Dict(Vec<String>, Vec<Expr<'a>>), Dict(Vec<String>, Vec<Expr<'a>>),
Apply(Op, Vec<Expr<'a>>), Apply(Op, Vec<Expr<'a>>),
Ident(String),
Const(Value<'a>), Const(Value<'a>),
} }
@ -192,7 +194,7 @@ fn build_expr_primary(pair: Pair<Rule>) -> Result<Expr> {
Rule::null => Ok(Const(Value::Null)), Rule::null => Ok(Const(Value::Null)),
Rule::boolean => Ok(Const(Value::Bool(pair.as_str() == "true"))), Rule::boolean => Ok(Const(Value::Bool(pair.as_str() == "true"))),
Rule::quoted_string | Rule::s_quoted_string | Rule::raw_string => Ok( Rule::quoted_string | Rule::s_quoted_string | Rule::raw_string => Ok(
Const(Value::OwnString(Box::new(parse_string(pair)?)))), Const(Value::OwnString(Arc::new(parse_string(pair)?)))),
Rule::list => { Rule::list => {
let mut vals = vec![]; let mut vals = vec![];
let mut has_apply = false; let mut has_apply = false;
@ -209,12 +211,13 @@ fn build_expr_primary(pair: Pair<Rule>) -> Result<Expr> {
if has_apply { if has_apply {
Ok(Expr::List(vals)) Ok(Expr::List(vals))
} else { } else {
Ok(Const(Value::List(Box::new(vals.into_iter().map(|v| { Ok(Const(Value::List(Arc::new(vals.into_iter().map(|v| {
match v { match v {
Apply(_, _) => { unreachable!() } Apply(_, _) => { unreachable!() }
Expr::List(_) => { unreachable!() } Expr::List(_) => { unreachable!() }
Expr::Dict(_, _) => { unreachable!() } Expr::Dict(_, _) => { unreachable!() }
Const(v) => { v } Const(v) => { v }
Expr::Ident(_) => unimplemented!()
} }
}).collect())))) }).collect()))))
} }
@ -246,7 +249,7 @@ fn build_expr_primary(pair: Pair<Rule>) -> Result<Expr> {
if has_apply { if has_apply {
Ok(Expr::Dict(keys, vals)) Ok(Expr::Dict(keys, vals))
} else { } else {
Ok(Const(Value::Dict(Box::new(keys.into_iter().zip(vals.into_iter()).map(|(k, v)| { Ok(Const(Value::Dict(Arc::new(keys.into_iter().zip(vals.into_iter()).map(|(k, v)| {
match v { match v {
Expr::List(_) => { unreachable!() } Expr::List(_) => { unreachable!() }
Expr::Dict(_, _) => { unreachable!() } Expr::Dict(_, _) => { unreachable!() }
@ -254,10 +257,14 @@ fn build_expr_primary(pair: Pair<Rule>) -> Result<Expr> {
Const(v) => { Const(v) => {
(k.into(), v) (k.into(), v)
} }
Expr::Ident(_) => unimplemented!()
} }
}).collect())))) }).collect()))))
} }
} }
Rule::param => {
Ok(Expr::Ident(pair.as_str().to_string()))
}
_ => { _ => {
println!("Unhandled rule {:?}", pair.as_rule()); println!("Unhandled rule {:?}", pair.as_rule());
unimplemented!() unimplemented!()
@ -265,7 +272,7 @@ fn build_expr_primary(pair: Pair<Rule>) -> Result<Expr> {
} }
} }
fn build_expr(pair: Pair<Rule>) -> Result<Expr> { pub fn build_expr(pair: Pair<Rule>) -> Result<Expr> {
PREC_CLIMBER.climb(pair.into_inner(), build_expr_primary, build_expr_infix) PREC_CLIMBER.climb(pair.into_inner(), build_expr_primary, build_expr_infix)
} }

@ -1,4 +1,5 @@
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::sync::Arc;
use pest::iterators::{Pair, Pairs}; use pest::iterators::{Pair, Pairs};
use crate::ast::parse_string; use crate::ast::parse_string;
use crate::env::{Env, LayeredEnv, StructuredEnvItem}; use crate::env::{Env, LayeredEnv, StructuredEnvItem};
@ -304,19 +305,20 @@ impl RocksStorage {
let mut key_parser = ByteArrayParser::new(&k); let mut key_parser = ByteArrayParser::new(&k);
let mut data_parser = ByteArrayParser::new(&v); let mut data_parser = ByteArrayParser::new(&v);
key_parser.parse_varint().unwrap(); key_parser.parse_varint().unwrap();
let table_name = key_parser.parse_value().unwrap().get_string().unwrap(); let table_name = key_parser.parse_value().unwrap().get_string().unwrap().to_string();
let table_kind = data_parser.parse_value().unwrap(); let table_kind = data_parser.parse_value().unwrap();
let table_id = TableId { name: table_name, local_id: 0 }; let table_id = TableId { name: table_name, local_id: 0 };
match table_kind { match table_kind {
Value::UInt(i) if i == TableKind::Node as u64 => { Value::UInt(i) if i == TableKind::Node as u64 => {
let keys: Vec<_> = data_parser.parse_value().unwrap().get_list().unwrap() let keys: Vec<_> = data_parser.parse_value().unwrap().get_list().unwrap()
.into_iter().map(|v| { .iter().map(|v| {
let mut vs = v.get_list().unwrap().into_iter(); let vs = v.get_list().unwrap();
let name = vs.next().unwrap().get_string().unwrap(); let mut vs = vs.iter();
let name = vs.next().unwrap().get_string().unwrap().to_string();
let typ = vs.next().unwrap().get_string().unwrap(); let typ = vs.next().unwrap().get_string().unwrap();
let typ = env.build_type_from_str(&typ).unwrap(); let typ = env.build_type_from_str(&typ).unwrap();
let default = vs.next().unwrap().into_owned(); let default = vs.next().unwrap().to_owned();
Col { Col {
name, name,
typ, typ,
@ -324,12 +326,13 @@ impl RocksStorage {
} }
}).collect(); }).collect();
let cols: Vec<_> = data_parser.parse_value().unwrap().get_list().unwrap() let cols: Vec<_> = data_parser.parse_value().unwrap().get_list().unwrap()
.into_iter().map(|v| { .iter().map(|v| {
let mut vs = v.get_list().unwrap().into_iter(); let vs = v.get_list().unwrap();
let name = vs.next().unwrap().get_string().unwrap(); let mut vs = vs.iter();
let name = vs.next().unwrap().get_string().unwrap().to_string();
let typ = vs.next().unwrap().get_string().unwrap(); let typ = vs.next().unwrap().get_string().unwrap();
let typ = env.build_type_from_str(&typ).unwrap(); let typ = env.build_type_from_str(&typ).unwrap();
let default = vs.next().unwrap().into_owned(); let default = vs.next().unwrap().to_owned();
Col { Col {
name, name,
typ, typ,
@ -348,17 +351,18 @@ impl RocksStorage {
ret.push(Structured::Node(node)); ret.push(Structured::Node(node));
} }
Value::UInt(i) if i == TableKind::Edge as u64 => { Value::UInt(i) if i == TableKind::Edge as u64 => {
let src_name = data_parser.parse_value().unwrap().get_string().unwrap(); let src_name = data_parser.parse_value().unwrap().get_string().unwrap().to_string();
let dst_name = data_parser.parse_value().unwrap().get_string().unwrap(); let dst_name = data_parser.parse_value().unwrap().get_string().unwrap().to_string();
let src_id = TableId { name: src_name, local_id: 0 }; let src_id = TableId { name: src_name, local_id: 0 };
let dst_id = TableId { name: dst_name, local_id: 0 }; let dst_id = TableId { name: dst_name, local_id: 0 };
let keys: Vec<_> = data_parser.parse_value().unwrap().get_list().unwrap() let keys: Vec<_> = data_parser.parse_value().unwrap().get_list().unwrap()
.into_iter().map(|v| { .iter().map(|v| {
let mut vs = v.get_list().unwrap().into_iter(); let vs = v.get_list().unwrap();
let name = vs.next().unwrap().get_string().unwrap(); let mut vs = vs.iter();
let name = vs.next().unwrap().get_string().unwrap().to_string();
let typ = vs.next().unwrap().get_string().unwrap(); let typ = vs.next().unwrap().get_string().unwrap();
let typ = env.build_type_from_str(&typ).unwrap(); let typ = env.build_type_from_str(&typ).unwrap();
let default = vs.next().unwrap().into_owned(); let default = vs.next().unwrap().to_owned();
Col { Col {
name, name,
typ, typ,
@ -366,12 +370,13 @@ impl RocksStorage {
} }
}).collect(); }).collect();
let cols: Vec<_> = data_parser.parse_value().unwrap().get_list().unwrap() let cols: Vec<_> = data_parser.parse_value().unwrap().get_list().unwrap()
.into_iter().map(|v| { .iter().map(|v| {
let mut vs = v.get_list().unwrap().into_iter(); let vs = v.get_list().unwrap();
let name = vs.next().unwrap().get_string().unwrap(); let mut vs = vs.iter();
let name = vs.next().unwrap().get_string().unwrap().to_string();
let typ = vs.next().unwrap().get_string().unwrap(); let typ = vs.next().unwrap().get_string().unwrap();
let typ = env.build_type_from_str(&typ).unwrap(); let typ = env.build_type_from_str(&typ).unwrap();
let default = vs.next().unwrap().into_owned(); let default = vs.next().unwrap().to_owned();
Col { Col {
name, name,
typ, typ,
@ -408,17 +413,17 @@ impl RocksStorage {
key_writer.build_value(&Value::RefString(&node.id.name)); key_writer.build_value(&Value::RefString(&node.id.name));
let mut val_writer = ByteArrayBuilder::with_capacity(128); let mut val_writer = ByteArrayBuilder::with_capacity(128);
val_writer.build_value(&Value::UInt(TableKind::Node as u64)); val_writer.build_value(&Value::UInt(TableKind::Node as u64));
val_writer.build_value(&Value::List(Box::new(node.keys.iter().map(|k| { val_writer.build_value(&Value::List(Arc::new(node.keys.iter().map(|k| {
Value::List(Box::new(vec![ Value::List(Arc::new(vec![
Value::RefString(&k.name), Value::RefString(&k.name),
Value::OwnString(Box::new(format!("{}", k.typ))), Value::OwnString(Arc::new(format!("{}", k.typ))),
k.default.clone(), k.default.clone(),
])) ]))
}).collect()))); }).collect())));
val_writer.build_value(&Value::List(Box::new(node.cols.iter().map(|k| { val_writer.build_value(&Value::List(Arc::new(node.cols.iter().map(|k| {
Value::List(Box::new(vec![ Value::List(Arc::new(vec![
Value::RefString(&k.name), Value::RefString(&k.name),
Value::OwnString(Box::new(format!("{}", k.typ))), Value::OwnString(Arc::new(format!("{}", k.typ))),
k.default.clone(), k.default.clone(),
])) ]))
}).collect()))); }).collect())));
@ -437,17 +442,17 @@ impl RocksStorage {
val_writer.build_value(&Value::UInt(TableKind::Edge as u64)); val_writer.build_value(&Value::UInt(TableKind::Edge as u64));
val_writer.build_value(&Value::RefString(&edge.src.name)); val_writer.build_value(&Value::RefString(&edge.src.name));
val_writer.build_value(&Value::RefString(&edge.dst.name)); val_writer.build_value(&Value::RefString(&edge.dst.name));
val_writer.build_value(&Value::List(Box::new(edge.keys.iter().map(|k| { val_writer.build_value(&Value::List(Arc::new(edge.keys.iter().map(|k| {
Value::List(Box::new(vec![ Value::List(Arc::new(vec![
Value::RefString(&k.name), Value::RefString(&k.name),
Value::OwnString(Box::new(format!("{}", k.typ))), Value::OwnString(Arc::new(format!("{}", k.typ))),
k.default.clone(), k.default.clone(),
])) ]))
}).collect()))); }).collect())));
val_writer.build_value(&Value::List(Box::new(edge.cols.iter().map(|k| { val_writer.build_value(&Value::List(Arc::new(edge.cols.iter().map(|k| {
Value::List(Box::new(vec![ Value::List(Arc::new(vec![
Value::RefString(&k.name), Value::RefString(&k.name),
Value::OwnString(Box::new(format!("{}", k.typ))), Value::OwnString(Arc::new(format!("{}", k.typ))),
k.default.clone(), k.default.clone(),
])) ]))
}).collect()))); }).collect())));
@ -460,26 +465,27 @@ impl RocksStorage {
impl Evaluator<RocksStorage> { impl Evaluator<RocksStorage> {
pub fn restore_metadata(&mut self) -> Result<()> { pub fn restore_metadata(&mut self) -> Result<()> {
let mds = self.storage.all_metadata(self.s_envs.root())?; let mds = self.storage.all_metadata(self.env.root())?;
for md in &mds { for md in &mds {
match md { match md {
v @ Structured::Node(n) => { v @ Structured::Node(n) => {
// TODO: check if they are the same if one already exists // TODO: check if they are the same if one already exists
self.s_envs.root_define(n.id.name.clone(), v.clone()); self.env.root_define(n.id.name.clone(), v.clone());
} }
v @ Structured::Edge(e) => { v @ Structured::Edge(e) => {
self.s_envs.root_define(e.id.name.clone(), v.clone()); self.env.root_define(e.id.name.clone(), v.clone());
} }
Structured::Columns(_) => {} Structured::Columns(_) => {}
Structured::Index(_) => {} Structured::Index(_) => {}
Structured::Typing(_) => unreachable!() Structured::Typing(_) => unreachable!(),
Structured::Value(_) => unreachable!()
} }
} }
Ok(()) Ok(())
} }
fn persist_change(&mut self, tname: &str, global: bool) -> Result<()> { fn persist_change(&mut self, tname: &str, global: bool) -> Result<()> {
let tbl = self.s_envs.resolve_mut(tname).unwrap(); let tbl = self.env.resolve_mut(tname).unwrap();
self.storage.create_table(tname, global)?; self.storage.create_table(tname, global)?;
if global { if global {
match tbl { match tbl {
@ -488,6 +494,7 @@ impl Evaluator<RocksStorage> {
Structured::Columns(_) => unimplemented!(), Structured::Columns(_) => unimplemented!(),
Structured::Index(_) => unimplemented!(), Structured::Index(_) => unimplemented!(),
Structured::Typing(_) => panic!(), Structured::Typing(_) => panic!(),
Structured::Value(_) => unreachable!()
} }
} else { } else {
Ok(()) Ok(())
@ -504,9 +511,9 @@ impl Evaluator<RocksStorage> {
let global = r == Rule::global_def; let global = r == Rule::global_def;
let local_id = self.get_next_local_id(global); let local_id = self.get_next_local_id(global);
let env_to_build = if global { let env_to_build = if global {
self.s_envs.root_mut() self.env.root_mut()
} else { } else {
self.s_envs.cur_mut() self.env.cur_mut()
}; };
new_tables.push((global, match inner.as_rule() { new_tables.push((global, match inner.as_rule() {
Rule::node_def => { Rule::node_def => {
@ -566,7 +573,7 @@ mod tests {
eval.build_table(parsed).unwrap(); eval.build_table(parsed).unwrap();
eval.restore_metadata().unwrap(); eval.restore_metadata().unwrap();
eval.storage.delete().unwrap(); eval.storage.delete().unwrap();
println!("{:#?}", eval.s_envs.resolve("Person")); println!("{:#?}", eval.env.resolve("Person"));
println!("{:#?}", eval.s_envs.resolve("Friend")); println!("{:#?}", eval.env.resolve("Friend"));
} }
} }

@ -22,6 +22,12 @@ pub enum CozoError {
#[error("Undefined type")] #[error("Undefined type")]
UndefinedType, UndefinedType,
#[error("Undefined parameter")]
UndefinedParam,
#[error("Value required")]
ValueRequired,
#[error("Wrong type")] #[error("Wrong type")]
WrongType, WrongType,
@ -44,7 +50,10 @@ pub enum CozoError {
Parse(#[from] pest::error::Error<Rule>), Parse(#[from] pest::error::Error<Rule>),
#[error(transparent)] #[error(transparent)]
Storage(#[from] cozo_rocks::BridgeStatus) Storage(#[from] cozo_rocks::BridgeStatus),
#[error(transparent)]
Io(#[from] std::io::Error),
} }
pub type Result<T> = result::Result<T, CozoError>; pub type Result<T> = result::Result<T, CozoError>;

@ -7,16 +7,17 @@ use crate::error::CozoError;
use crate::error::CozoError::*; use crate::error::CozoError::*;
use crate::value::Value::*; use crate::value::Value::*;
use crate::ast::*; use crate::ast::*;
use crate::env::StructuredEnv; use crate::env::{Env, StructuredEnv};
use crate::storage::{DummyStorage, RocksStorage, Storage}; use crate::storage::{DummyStorage, RocksStorage, Storage};
use crate::typing::Structured;
pub struct Evaluator<S: Storage> { pub struct Evaluator<S: Storage> {
pub s_envs: StructuredEnv, pub env: StructuredEnv,
pub storage: S, pub storage: S,
pub last_local_id: Arc<AtomicUsize>, pub last_local_id: Arc<AtomicUsize>,
} }
impl <S:Storage> Evaluator<S> { impl<S: Storage> Evaluator<S> {
pub fn get_next_local_id(&self, is_global: bool) -> usize { pub fn get_next_local_id(&self, is_global: bool) -> usize {
if is_global { if is_global {
0 0
@ -32,7 +33,7 @@ pub type BareEvaluator = Evaluator<DummyStorage>;
impl EvaluatorWithStorage { impl EvaluatorWithStorage {
pub fn new(path: String) -> Result<Self> { pub fn new(path: String) -> Result<Self> {
Ok(Self { Ok(Self {
s_envs: StructuredEnv::new(), env: StructuredEnv::new(),
storage: RocksStorage::new(path)?, storage: RocksStorage::new(path)?,
last_local_id: Arc::new(AtomicUsize::new(1)), last_local_id: Arc::new(AtomicUsize::new(1)),
}) })
@ -42,7 +43,7 @@ impl EvaluatorWithStorage {
impl Default for BareEvaluator { impl Default for BareEvaluator {
fn default() -> Self { fn default() -> Self {
Self { Self {
s_envs: StructuredEnv::new(), env: StructuredEnv::new(),
storage: DummyStorage, storage: DummyStorage,
last_local_id: Arc::new(AtomicUsize::new(0)), last_local_id: Arc::new(AtomicUsize::new(0)),
} }
@ -80,6 +81,16 @@ impl<'a, S: Storage> ExprVisitor<'a, Result<Expr<'a>>> for Evaluator<S> {
Const(v) => Ok(Const(v.clone())), Const(v) => Ok(Const(v.clone())),
Expr::List(_) => { unimplemented!() } Expr::List(_) => { unimplemented!() }
Expr::Dict(_, _) => { unimplemented!() } Expr::Dict(_, _) => { unimplemented!() }
Ident(ident) => {
let resolved = self.env.resolve(ident).ok_or(UndefinedParam)?;
match resolved {
Structured::Value(v) => {
Ok(Const(v.clone()))
}
_ => return Err(ValueRequired)
}
}
} }
} }
} }
@ -100,10 +111,10 @@ impl<S: Storage> Evaluator<S> {
(Float(va), Int(vb)) => Float(va + vb as f64), (Float(va), Int(vb)) => Float(va + vb as f64),
(Int(va), Float(vb)) => Float(va as f64 + vb), (Int(va), Float(vb)) => Float(va as f64 + vb),
(Float(va), Float(vb)) => Float(va + vb), (Float(va), Float(vb)) => Float(va + vb),
(OwnString(va), OwnString(vb)) => OwnString(Box::new(*va + &*vb)), (OwnString(va), OwnString(vb)) => OwnString(Arc::new(va.clone().to_string() + &vb)),
(OwnString(va), RefString(vb)) => OwnString(Box::new(*va + &*vb)), (OwnString(va), RefString(vb)) => OwnString(Arc::new(va.clone().to_string() + &*vb)),
(RefString(va), OwnString(vb)) => OwnString(Box::new(va.to_string() + &*vb)), (RefString(va), OwnString(vb)) => OwnString(Arc::new(va.to_string() + &*vb)),
(RefString(va), RefString(vb)) => OwnString(Box::new(va.to_string() + &*vb)), (RefString(va), RefString(vb)) => OwnString(Arc::new(va.to_string() + &*vb)),
(_, _) => return Err(CozoError::TypeError) (_, _) => return Err(CozoError::TypeError)
} }
} }
@ -535,342 +546,4 @@ mod tests {
println!("{:#?}", ev.visit_expr(&parse_expr_from_str("null || true").unwrap()).unwrap()); println!("{:#?}", ev.visit_expr(&parse_expr_from_str("null || true").unwrap()).unwrap());
println!("{:#?}", ev.visit_expr(&parse_expr_from_str("true && null").unwrap()).unwrap()); println!("{:#?}", ev.visit_expr(&parse_expr_from_str("true && null").unwrap()).unwrap());
} }
#[test]
fn data() -> Result<()> {
let data = r#"[{"_src":"AR","_dst":2,"_type":"InRegion"},
{"_src":"AU","_dst":3,"_type":"InRegion"},
{"_src":"BE","_dst":1,"_type":"InRegion"},
{"_src":"BR","_dst":2,"_type":"InRegion"},
{"_src":"CA","_dst":2,"_type":"InRegion"},
{"_src":"CH","_dst":1,"_type":"InRegion"},
{"_src":"CN","_dst":3,"_type":"InRegion"},
{"_src":"DE","_dst":1,"_type":"InRegion"},
{"_src":"DK","_dst":1,"_type":"InRegion"},
{"_src":"EG","_dst":4,"_type":"InRegion"},
{"_src":"FR","_dst":1,"_type":"InRegion"},
{"_src":"HK","_dst":3,"_type":"InRegion"},
{"_src":"IL","_dst":4,"_type":"InRegion"},
{"_src":"IN","_dst":3,"_type":"InRegion"},
{"_src":"IT","_dst":1,"_type":"InRegion"},
{"_src":"JP","_dst":3,"_type":"InRegion"},
{"_src":"KW","_dst":4,"_type":"InRegion"},
{"_src":"MX","_dst":2,"_type":"InRegion"},
{"_src":"NG","_dst":4,"_type":"InRegion"},
{"_src":"NL","_dst":1,"_type":"InRegion"},
{"_src":"SG","_dst":3,"_type":"InRegion"},
{"_src":"UK","_dst":1,"_type":"InRegion"},
{"_src":"US","_dst":2,"_type":"InRegion"},
{"_src":"ZM","_dst":4,"_type":"InRegion"},
{"_src":"ZW","_dst":4,"_type":"InRegion"},
{"_src":1400,"_dst":"US","_type":"InCountry"},
{"_src":1500,"_dst":"US","_type":"InCountry"},
{"_src":1700,"_dst":"US","_type":"InCountry"},
{"_src":1800,"_dst":"CA","_type":"InCountry"},
{"_src":2400,"_dst":"UK","_type":"InCountry"},
{"_src":2500,"_dst":"UK","_type":"InCountry"},
{"_src":2700,"_dst":"DE","_type":"InCountry"},
{"_dst":101,"_src":100,"_type":"Manages"},
{"_dst":102,"_src":100,"_type":"Manages"},
{"_dst":103,"_src":102,"_type":"Manages"},
{"_dst":104,"_src":103,"_type":"Manages"},
{"_dst":105,"_src":103,"_type":"Manages"},
{"_dst":106,"_src":103,"_type":"Manages"},
{"_dst":107,"_src":103,"_type":"Manages"},
{"_dst":108,"_src":101,"_type":"Manages"},
{"_dst":109,"_src":108,"_type":"Manages"},
{"_dst":110,"_src":108,"_type":"Manages"},
{"_dst":111,"_src":108,"_type":"Manages"},
{"_dst":112,"_src":108,"_type":"Manages"},
{"_dst":113,"_src":108,"_type":"Manages"},
{"_dst":114,"_src":100,"_type":"Manages"},
{"_dst":115,"_src":114,"_type":"Manages"},
{"_dst":116,"_src":114,"_type":"Manages"},
{"_dst":117,"_src":114,"_type":"Manages"},
{"_dst":118,"_src":114,"_type":"Manages"},
{"_dst":119,"_src":114,"_type":"Manages"},
{"_dst":120,"_src":100,"_type":"Manages"},
{"_dst":121,"_src":100,"_type":"Manages"},
{"_dst":122,"_src":100,"_type":"Manages"},
{"_dst":123,"_src":100,"_type":"Manages"},
{"_dst":126,"_src":120,"_type":"Manages"},
{"_dst":145,"_src":100,"_type":"Manages"},
{"_dst":146,"_src":100,"_type":"Manages"},
{"_dst":176,"_src":100,"_type":"Manages"},
{"_dst":177,"_src":100,"_type":"Manages"},
{"_dst":178,"_src":100,"_type":"Manages"},
{"_dst":179,"_src":100,"_type":"Manages"},
{"_dst":192,"_src":123,"_type":"Manages"},
{"_dst":193,"_src":123,"_type":"Manages"},
{"_dst":200,"_src":101,"_type":"Manages"},
{"_dst":201,"_src":100,"_type":"Manages"},
{"_dst":202,"_src":201,"_type":"Manages"},
{"_dst":203,"_src":101,"_type":"Manages"},
{"_dst":204,"_src":101,"_type":"Manages"},
{"_dst":205,"_src":101,"_type":"Manages"},
{"_dst":206,"_src":205,"_type":"Manages"},
{"_src":100,"hire_date":"1987-06-17","_dst":4,"salary":24000.0,"_type":"HasJob"},
{"_src":101,"hire_date":"1989-09-21","_dst":5,"salary":17000.0,"_type":"HasJob"},
{"_src":102,"hire_date":"1993-01-13","_dst":5,"salary":17000.0,"_type":"HasJob"},
{"_src":103,"hire_date":"1990-01-03","_dst":9,"salary":9000.0,"_type":"HasJob"},
{"_src":104,"hire_date":"1991-05-21","_dst":9,"salary":6000.0,"_type":"HasJob"},
{"_src":105,"hire_date":"1997-06-25","_dst":9,"salary":4800.0,"_type":"HasJob"},
{"_src":106,"hire_date":"1998-02-05","_dst":9,"salary":4800.0,"_type":"HasJob"},
{"_src":107,"hire_date":"1999-02-07","_dst":9,"salary":4200.0,"_type":"HasJob"},
{"_src":108,"hire_date":"1994-08-17","_dst":7,"salary":12000.0,"_type":"HasJob"},
{"_src":109,"hire_date":"1994-08-16","_dst":6,"salary":9000.0,"_type":"HasJob"},
{"_src":110,"hire_date":"1997-09-28","_dst":6,"salary":8200.0,"_type":"HasJob"},
{"_src":111,"hire_date":"1997-09-30","_dst":6,"salary":7700.0,"_type":"HasJob"},
{"_src":112,"hire_date":"1998-03-07","_dst":6,"salary":7800.0,"_type":"HasJob"},
{"_src":113,"hire_date":"1999-12-07","_dst":6,"salary":6900.0,"_type":"HasJob"},
{"_src":114,"hire_date":"1994-12-07","_dst":14,"salary":11000.0,"_type":"HasJob"},
{"_src":115,"hire_date":"1995-05-18","_dst":13,"salary":3100.0,"_type":"HasJob"},
{"_src":116,"hire_date":"1997-12-24","_dst":13,"salary":2900.0,"_type":"HasJob"},
{"_src":117,"hire_date":"1997-07-24","_dst":13,"salary":2800.0,"_type":"HasJob"},
{"_src":118,"hire_date":"1998-11-15","_dst":13,"salary":2600.0,"_type":"HasJob"},
{"_src":119,"hire_date":"1999-08-10","_dst":13,"salary":2500.0,"_type":"HasJob"},
{"_src":120,"hire_date":"1996-07-18","_dst":19,"salary":8000.0,"_type":"HasJob"},
{"_src":121,"hire_date":"1997-04-10","_dst":19,"salary":8200.0,"_type":"HasJob"},
{"_src":122,"hire_date":"1995-05-01","_dst":19,"salary":7900.0,"_type":"HasJob"},
{"_src":123,"hire_date":"1997-10-10","_dst":19,"salary":6500.0,"_type":"HasJob"},
{"_src":126,"hire_date":"1998-09-28","_dst":18,"salary":2700.0,"_type":"HasJob"},
{"_src":145,"hire_date":"1996-10-01","_dst":15,"salary":14000.0,"_type":"HasJob"},
{"_src":146,"hire_date":"1997-01-05","_dst":15,"salary":13500.0,"_type":"HasJob"},
{"_src":176,"hire_date":"1998-03-24","_dst":16,"salary":8600.0,"_type":"HasJob"},
{"_src":177,"hire_date":"1998-04-23","_dst":16,"salary":8400.0,"_type":"HasJob"},
{"_src":178,"hire_date":"1999-05-24","_dst":16,"salary":7000.0,"_type":"HasJob"},
{"_src":179,"hire_date":"2000-01-04","_dst":16,"salary":6200.0,"_type":"HasJob"},
{"_src":192,"hire_date":"1996-02-04","_dst":17,"salary":4000.0,"_type":"HasJob"},
{"_src":193,"hire_date":"1997-03-03","_dst":17,"salary":3900.0,"_type":"HasJob"},
{"_src":200,"hire_date":"1987-09-17","_dst":3,"salary":4400.0,"_type":"HasJob"},
{"_src":201,"hire_date":"1996-02-17","_dst":10,"salary":13000.0,"_type":"HasJob"},
{"_src":202,"hire_date":"1997-08-17","_dst":11,"salary":6000.0,"_type":"HasJob"},
{"_src":203,"hire_date":"1994-06-07","_dst":8,"salary":6500.0,"_type":"HasJob"},
{"_src":204,"hire_date":"1994-06-07","_dst":12,"salary":10000.0,"_type":"HasJob"},
{"_src":205,"hire_date":"1994-06-07","_dst":2,"salary":12000.0,"_type":"HasJob"},
{"_src":206,"hire_date":"1994-06-07","_dst":1,"salary":8300.0,"_type":"HasJob"},
{"_src":1,"_dst":1700,"_type":"InLocation"},
{"_src":2,"_dst":1800,"_type":"InLocation"},
{"_src":3,"_dst":1700,"_type":"InLocation"},
{"_src":4,"_dst":2400,"_type":"InLocation"},
{"_src":5,"_dst":1500,"_type":"InLocation"},
{"_src":6,"_dst":1400,"_type":"InLocation"},
{"_src":7,"_dst":2700,"_type":"InLocation"},
{"_src":8,"_dst":2500,"_type":"InLocation"},
{"_src":9,"_dst":1700,"_type":"InLocation"},
{"_src":10,"_dst":1700,"_type":"InLocation"},
{"_src":11,"_dst":1700,"_type":"InLocation"},
{"id":1,"title":"Public Accountant","min_salary":4200.0,"max_salary":9000.0,"_type":"Job"},
{"id":2,"title":"Accounting Manager","min_salary":8200.0,"max_salary":16000.0,"_type":"Job"},
{"id":3,"title":"Administration Assistant","min_salary":3000.0,"max_salary":6000.0,"_type":"Job"},
{"id":4,"title":"President","min_salary":20000.0,"max_salary":40000.0,"_type":"Job"},
{"id":5,"title":"Administration Vice President","min_salary":15000.0,"max_salary":30000.0,"_type":"Job"},
{"id":6,"title":"Accountant","min_salary":4200.0,"max_salary":9000.0,"_type":"Job"},
{"id":7,"title":"Finance Manager","min_salary":8200.0,"max_salary":16000.0,"_type":"Job"},
{"id":8,"title":"Human Resources Representative","min_salary":4000.0,"max_salary":9000.0,"_type":"Job"},
{"id":9,"title":"Programmer","min_salary":4000.0,"max_salary":10000.0,"_type":"Job"},
{"id":10,"title":"Marketing Manager","min_salary":9000.0,"max_salary":15000.0,"_type":"Job"},
{"id":11,"title":"Marketing Representative","min_salary":4000.0,"max_salary":9000.0,"_type":"Job"},
{"id":12,"title":"Public Relations Representative","min_salary":4500.0,"max_salary":10500.0,"_type":"Job"},
{"id":13,"title":"Purchasing Clerk","min_salary":2500.0,"max_salary":5500.0,"_type":"Job"},
{"id":14,"title":"Purchasing Manager","min_salary":8000.0,"max_salary":15000.0,"_type":"Job"},
{"id":15,"title":"Sales Manager","min_salary":10000.0,"max_salary":20000.0,"_type":"Job"},
{"id":16,"title":"Sales Representative","min_salary":6000.0,"max_salary":12000.0,"_type":"Job"},
{"id":17,"title":"Shipping Clerk","min_salary":2500.0,"max_salary":5500.0,"_type":"Job"},
{"id":18,"title":"Stock Clerk","min_salary":2000.0,"max_salary":5000.0,"_type":"Job"},
{"id":19,"title":"Stock Manager","min_salary":5500.0,"max_salary":8500.0,"_type":"Job"},
{"id":1,"first_name":"Penelope","last_name":"Gietz","_type":"Dependent"},
{"id":2,"first_name":"Nick","last_name":"Higgins","_type":"Dependent"},
{"id":3,"first_name":"Ed","last_name":"Whalen","_type":"Dependent"},
{"id":4,"first_name":"Jennifer","last_name":"King","_type":"Dependent"},
{"id":5,"first_name":"Johnny","last_name":"Kochhar","_type":"Dependent"},
{"id":6,"first_name":"Bette","last_name":"De Haan","_type":"Dependent"},
{"id":7,"first_name":"Grace","last_name":"Faviet","_type":"Dependent"},
{"id":8,"first_name":"Matthew","last_name":"Chen","_type":"Dependent"},
{"id":9,"first_name":"Joe","last_name":"Sciarra","_type":"Dependent"},
{"id":10,"first_name":"Christian","last_name":"Urman","_type":"Dependent"},
{"id":11,"first_name":"Zero","last_name":"Popp","_type":"Dependent"},
{"id":12,"first_name":"Karl","last_name":"Greenberg","_type":"Dependent"},
{"id":13,"first_name":"Uma","last_name":"Mavris","_type":"Dependent"},
{"id":14,"first_name":"Vivien","last_name":"Hunold","_type":"Dependent"},
{"id":15,"first_name":"Cuba","last_name":"Ernst","_type":"Dependent"},
{"id":16,"first_name":"Fred","last_name":"Austin","_type":"Dependent"},
{"id":17,"first_name":"Helen","last_name":"Pataballa","_type":"Dependent"},
{"id":18,"first_name":"Dan","last_name":"Lorentz","_type":"Dependent"},
{"id":19,"first_name":"Bob","last_name":"Hartstein","_type":"Dependent"},
{"id":20,"first_name":"Lucille","last_name":"Fay","_type":"Dependent"},
{"id":21,"first_name":"Kirsten","last_name":"Baer","_type":"Dependent"},
{"id":22,"first_name":"Elvis","last_name":"Khoo","_type":"Dependent"},
{"id":23,"first_name":"Sandra","last_name":"Baida","_type":"Dependent"},
{"id":24,"first_name":"Cameron","last_name":"Tobias","_type":"Dependent"},
{"id":25,"first_name":"Kevin","last_name":"Himuro","_type":"Dependent"},
{"id":26,"first_name":"Rip","last_name":"Colmenares","_type":"Dependent"},
{"id":27,"first_name":"Julia","last_name":"Raphaely","_type":"Dependent"},
{"id":28,"first_name":"Woody","last_name":"Russell","_type":"Dependent"},
{"id":29,"first_name":"Alec","last_name":"Partners","_type":"Dependent"},
{"id":30,"first_name":"Sandra","last_name":"Taylor","_type":"Dependent"},
{"id":1,"name":"Administration","_type":"Department"},
{"id":2,"name":"Marketing","_type":"Department"},
{"id":3,"name":"Purchasing","_type":"Department"},
{"id":4,"name":"Human Resources","_type":"Department"},
{"id":5,"name":"Shipping","_type":"Department"},
{"id":6,"name":"IT","_type":"Department"},
{"id":7,"name":"Public Relations","_type":"Department"},
{"id":8,"name":"Sales","_type":"Department"},
{"id":9,"name":"Executive","_type":"Department"},
{"id":10,"name":"Finance","_type":"Department"},
{"id":11,"name":"Accounting","_type":"Department"},
{"id":1,"name":"Europe","_type":"Region"},
{"id":2,"name":"Americas","_type":"Region"},
{"id":3,"name":"Asia","_type":"Region"},
{"id":4,"name":"Middle East and Africa","_type":"Region"},
{"id":"AR","name":"Argentina","_type":"Country"},
{"id":"AU","name":"Australia","_type":"Country"},
{"id":"BE","name":"Belgium","_type":"Country"},
{"id":"BR","name":"Brazil","_type":"Country"},
{"id":"CA","name":"Canada","_type":"Country"},
{"id":"CH","name":"Switzerland","_type":"Country"},
{"id":"CN","name":"China","_type":"Country"},
{"id":"DE","name":"Germany","_type":"Country"},
{"id":"DK","name":"Denmark","_type":"Country"},
{"id":"EG","name":"Egypt","_type":"Country"},
{"id":"FR","name":"France","_type":"Country"},
{"id":"HK","name":"HongKong","_type":"Country"},
{"id":"IL","name":"Israel","_type":"Country"},
{"id":"IN","name":"India","_type":"Country"},
{"id":"IT","name":"Italy","_type":"Country"},
{"id":"JP","name":"Japan","_type":"Country"},
{"id":"KW","name":"Kuwait","_type":"Country"},
{"id":"MX","name":"Mexico","_type":"Country"},
{"id":"NG","name":"Nigeria","_type":"Country"},
{"id":"NL","name":"Netherlands","_type":"Country"},
{"id":"SG","name":"Singapore","_type":"Country"},
{"id":"UK","name":"United Kingdom","_type":"Country"},
{"id":"US","name":"United States of America","_type":"Country"},
{"id":"ZM","name":"Zambia","_type":"Country"},
{"id":"ZW","name":"Zimbabwe","_type":"Country"},
{"_src":1,"relationship":"Child","_dst":206,"_type":"HasDependent"},
{"_src":2,"relationship":"Child","_dst":205,"_type":"HasDependent"},
{"_src":3,"relationship":"Child","_dst":200,"_type":"HasDependent"},
{"_src":4,"relationship":"Child","_dst":100,"_type":"HasDependent"},
{"_src":5,"relationship":"Child","_dst":101,"_type":"HasDependent"},
{"_src":6,"relationship":"Child","_dst":102,"_type":"HasDependent"},
{"_src":7,"relationship":"Child","_dst":109,"_type":"HasDependent"},
{"_src":8,"relationship":"Child","_dst":110,"_type":"HasDependent"},
{"_src":9,"relationship":"Child","_dst":111,"_type":"HasDependent"},
{"_src":10,"relationship":"Child","_dst":112,"_type":"HasDependent"},
{"_src":11,"relationship":"Child","_dst":113,"_type":"HasDependent"},
{"_src":12,"relationship":"Child","_dst":108,"_type":"HasDependent"},
{"_src":13,"relationship":"Child","_dst":203,"_type":"HasDependent"},
{"_src":14,"relationship":"Child","_dst":103,"_type":"HasDependent"},
{"_src":15,"relationship":"Child","_dst":104,"_type":"HasDependent"},
{"_src":16,"relationship":"Child","_dst":105,"_type":"HasDependent"},
{"_src":17,"relationship":"Child","_dst":106,"_type":"HasDependent"},
{"_src":18,"relationship":"Child","_dst":107,"_type":"HasDependent"},
{"_src":19,"relationship":"Child","_dst":201,"_type":"HasDependent"},
{"_src":20,"relationship":"Child","_dst":202,"_type":"HasDependent"},
{"_src":21,"relationship":"Child","_dst":204,"_type":"HasDependent"},
{"_src":22,"relationship":"Child","_dst":115,"_type":"HasDependent"},
{"_src":23,"relationship":"Child","_dst":116,"_type":"HasDependent"},
{"_src":24,"relationship":"Child","_dst":117,"_type":"HasDependent"},
{"_src":25,"relationship":"Child","_dst":118,"_type":"HasDependent"},
{"_src":26,"relationship":"Child","_dst":119,"_type":"HasDependent"},
{"_src":27,"relationship":"Child","_dst":114,"_type":"HasDependent"},
{"_src":28,"relationship":"Child","_dst":145,"_type":"HasDependent"},
{"_src":29,"relationship":"Child","_dst":146,"_type":"HasDependent"},
{"_src":30,"relationship":"Child","_dst":176,"_type":"HasDependent"},
{"id":1400,"street_address":"2014 Jabberwocky Rd","postal_code":"26192","city":"Southlake","state_province":"Texas","_type":"Location"},
{"id":1500,"street_address":"2011 Interiors Blvd","postal_code":"99236","city":"South San Francisco","state_province":"California","_type":"Location"},
{"id":1700,"street_address":"2004 Charade Rd","postal_code":"98199","city":"Seattle","state_province":"Washington","_type":"Location"},
{"id":1800,"street_address":"147 Spadina Ave","postal_code":"M5V 2L7","city":"Toronto","state_province":"Ontario","_type":"Location"},
{"id":2400,"street_address":"8204 Arthur St","postal_code":null,"city":"London","state_province":null,"_type":"Location"},
{"id":2500,"street_address":"Magdalen Centre The Oxford Science Park","postal_code":"OX9 9ZB","city":"Oxford","state_province":"Oxford","_type":"Location"},
{"id":2700,"street_address":"Schwanthalerstr. 7031","postal_code":"80925","city":"Munich","state_province":"Bavaria","_type":"Location"},
{"id":100,"first_name":"Steven","last_name":"King","email":"steven.king@sqltutorial.org","phone_number":"515.123.4567","_type":"Employee"},
{"id":101,"first_name":"Neena","last_name":"Kochhar","email":"neena.kochhar@sqltutorial.org","phone_number":"515.123.4568","_type":"Employee"},
{"id":102,"first_name":"Lex","last_name":"De Haan","email":"lex.de haan@sqltutorial.org","phone_number":"515.123.4569","_type":"Employee"},
{"id":103,"first_name":"Alexander","last_name":"Hunold","email":"alexander.hunold@sqltutorial.org","phone_number":"590.423.4567","_type":"Employee"},
{"id":104,"first_name":"Bruce","last_name":"Ernst","email":"bruce.ernst@sqltutorial.org","phone_number":"590.423.4568","_type":"Employee"},
{"id":105,"first_name":"David","last_name":"Austin","email":"david.austin@sqltutorial.org","phone_number":"590.423.4569","_type":"Employee"},
{"id":106,"first_name":"Valli","last_name":"Pataballa","email":"valli.pataballa@sqltutorial.org","phone_number":"590.423.4560","_type":"Employee"},
{"id":107,"first_name":"Diana","last_name":"Lorentz","email":"diana.lorentz@sqltutorial.org","phone_number":"590.423.5567","_type":"Employee"},
{"id":108,"first_name":"Nancy","last_name":"Greenberg","email":"nancy.greenberg@sqltutorial.org","phone_number":"515.124.4569","_type":"Employee"},
{"id":109,"first_name":"Daniel","last_name":"Faviet","email":"daniel.faviet@sqltutorial.org","phone_number":"515.124.4169","_type":"Employee"},
{"id":110,"first_name":"John","last_name":"Chen","email":"john.chen@sqltutorial.org","phone_number":"515.124.4269","_type":"Employee"},
{"id":111,"first_name":"Ismael","last_name":"Sciarra","email":"ismael.sciarra@sqltutorial.org","phone_number":"515.124.4369","_type":"Employee"},
{"id":112,"first_name":"Jose Manuel","last_name":"Urman","email":"jose manuel.urman@sqltutorial.org","phone_number":"515.124.4469","_type":"Employee"},
{"id":113,"first_name":"Luis","last_name":"Popp","email":"luis.popp@sqltutorial.org","phone_number":"515.124.4567","_type":"Employee"},
{"id":114,"first_name":"Den","last_name":"Raphaely","email":"den.raphaely@sqltutorial.org","phone_number":"515.127.4561","_type":"Employee"},
{"id":115,"first_name":"Alexander","last_name":"Khoo","email":"alexander.khoo@sqltutorial.org","phone_number":"515.127.4562","_type":"Employee"},
{"id":116,"first_name":"Shelli","last_name":"Baida","email":"shelli.baida@sqltutorial.org","phone_number":"515.127.4563","_type":"Employee"},
{"id":117,"first_name":"Sigal","last_name":"Tobias","email":"sigal.tobias@sqltutorial.org","phone_number":"515.127.4564","_type":"Employee"},
{"id":118,"first_name":"Guy","last_name":"Himuro","email":"guy.himuro@sqltutorial.org","phone_number":"515.127.4565","_type":"Employee"},
{"id":119,"first_name":"Karen","last_name":"Colmenares","email":"karen.colmenares@sqltutorial.org","phone_number":"515.127.4566","_type":"Employee"},
{"id":120,"first_name":"Matthew","last_name":"Weiss","email":"matthew.weiss@sqltutorial.org","phone_number":"650.123.1234","_type":"Employee"},
{"id":121,"first_name":"Adam","last_name":"Fripp","email":"adam.fripp@sqltutorial.org","phone_number":"650.123.2234","_type":"Employee"},
{"id":122,"first_name":"Payam","last_name":"Kaufling","email":"payam.kaufling@sqltutorial.org","phone_number":"650.123.3234","_type":"Employee"},
{"id":123,"first_name":"Shanta","last_name":"Vollman","email":"shanta.vollman@sqltutorial.org","phone_number":"650.123.4234","_type":"Employee"},
{"id":126,"first_name":"Irene","last_name":"Mikkilineni","email":"irene.mikkilineni@sqltutorial.org","phone_number":"650.124.1224","_type":"Employee"},
{"id":145,"first_name":"John","last_name":"Russell","email":"john.russell@sqltutorial.org","phone_number":null,"_type":"Employee"},
{"id":146,"first_name":"Karen","last_name":"Partners","email":"karen.partners@sqltutorial.org","phone_number":null,"_type":"Employee"},
{"id":176,"first_name":"Jonathon","last_name":"Taylor","email":"jonathon.taylor@sqltutorial.org","phone_number":null,"_type":"Employee"},
{"id":177,"first_name":"Jack","last_name":"Livingston","email":"jack.livingston@sqltutorial.org","phone_number":null,"_type":"Employee"},
{"id":178,"first_name":"Kimberely","last_name":"Grant","email":"kimberely.grant@sqltutorial.org","phone_number":null,"_type":"Employee"},
{"id":179,"first_name":"Charles","last_name":"Johnson","email":"charles.johnson@sqltutorial.org","phone_number":null,"_type":"Employee"},
{"id":192,"first_name":"Sarah","last_name":"Bell","email":"sarah.bell@sqltutorial.org","phone_number":"650.501.1876","_type":"Employee"},
{"id":193,"first_name":"Britney","last_name":"Everett","email":"britney.everett@sqltutorial.org","phone_number":"650.501.2876","_type":"Employee"},
{"id":200,"first_name":"Jennifer","last_name":"Whalen","email":"jennifer.whalen@sqltutorial.org","phone_number":"515.123.4444","_type":"Employee"},
{"id":201,"first_name":"Michael","last_name":"Hartstein","email":"michael.hartstein@sqltutorial.org","phone_number":"515.123.5555","_type":"Employee"},
{"id":202,"first_name":"Pat","last_name":"Fay","email":"pat.fay@sqltutorial.org","phone_number":"603.123.6666","_type":"Employee"},
{"id":203,"first_name":"Susan","last_name":"Mavris","email":"susan.mavris@sqltutorial.org","phone_number":"515.123.7777","_type":"Employee"},
{"id":204,"first_name":"Hermann","last_name":"Baer","email":"hermann.baer@sqltutorial.org","phone_number":"515.123.8888","_type":"Employee"},
{"id":205,"first_name":"Shelley","last_name":"Higgins","email":"shelley.higgins@sqltutorial.org","phone_number":"515.123.8080","_type":"Employee"},
{"id":206,"first_name":"William","last_name":"Gietz","email":"william.gietz@sqltutorial.org","phone_number":"515.123.8181","_type":"Employee"},
{"_src":100,"_dst":9,"_type":"InDepartment"},
{"_src":101,"_dst":9,"_type":"InDepartment"},
{"_src":102,"_dst":9,"_type":"InDepartment"},
{"_src":103,"_dst":6,"_type":"InDepartment"},
{"_src":104,"_dst":6,"_type":"InDepartment"},
{"_src":105,"_dst":6,"_type":"InDepartment"},
{"_src":106,"_dst":6,"_type":"InDepartment"},
{"_src":107,"_dst":6,"_type":"InDepartment"},
{"_src":108,"_dst":10,"_type":"InDepartment"},
{"_src":109,"_dst":10,"_type":"InDepartment"},
{"_src":110,"_dst":10,"_type":"InDepartment"},
{"_src":111,"_dst":10,"_type":"InDepartment"},
{"_src":112,"_dst":10,"_type":"InDepartment"},
{"_src":113,"_dst":10,"_type":"InDepartment"},
{"_src":114,"_dst":3,"_type":"InDepartment"},
{"_src":115,"_dst":3,"_type":"InDepartment"},
{"_src":116,"_dst":3,"_type":"InDepartment"},
{"_src":117,"_dst":3,"_type":"InDepartment"},
{"_src":118,"_dst":3,"_type":"InDepartment"},
{"_src":119,"_dst":3,"_type":"InDepartment"},
{"_src":120,"_dst":5,"_type":"InDepartment"},
{"_src":121,"_dst":5,"_type":"InDepartment"},
{"_src":122,"_dst":5,"_type":"InDepartment"},
{"_src":123,"_dst":5,"_type":"InDepartment"},
{"_src":126,"_dst":5,"_type":"InDepartment"},
{"_src":145,"_dst":8,"_type":"InDepartment"},
{"_src":146,"_dst":8,"_type":"InDepartment"},
{"_src":176,"_dst":8,"_type":"InDepartment"},
{"_src":177,"_dst":8,"_type":"InDepartment"},
{"_src":178,"_dst":8,"_type":"InDepartment"},
{"_src":179,"_dst":8,"_type":"InDepartment"},
{"_src":192,"_dst":5,"_type":"InDepartment"},
{"_src":193,"_dst":5,"_type":"InDepartment"},
{"_src":200,"_dst":1,"_type":"InDepartment"},
{"_src":201,"_dst":2,"_type":"InDepartment"},
{"_src":202,"_dst":2,"_type":"InDepartment"},
{"_src":203,"_dst":4,"_type":"InDepartment"},
{"_src":204,"_dst":7,"_type":"InDepartment"},
{"_src":205,"_dst":11,"_type":"InDepartment"},
{"_src":206,"_dst":11,"_type":"InDepartment"}]"#;
let parsed = parse_expr_from_str(data)?;
let mut ev = BareEvaluator::default();
let evaluated = ev.visit_expr(&parsed)?;
println!("{:#?}", evaluated);
Ok(())
}
} }

@ -158,7 +158,7 @@ statement = _{ global_def | local_def }
mutation = { (insert|update|delete) ~ expr ~ ("as" ~ name_in_def)? ~ mutation = { (insert|update|delete) ~ expr ~ ("as" ~ name_in_def)? ~
( (exclude ~ name_in_def ~ ("," ~ name_in_def)*) ( (exclude ~ name_in_def ~ ("," ~ name_in_def)*)
| (include ~ name_in_def ~ ("," ~ name_in_def)*))? } | (include ~ name_in_def ~ ("," ~ name_in_def)*))? ~ ";" }
exclude = {"exclude"} exclude = {"exclude"}
include = {"include"} include = {"include"}
insert = {"insert"} insert = {"insert"}

@ -7,4 +7,5 @@ pub mod eval;
pub mod function; pub mod function;
pub mod error; pub mod error;
pub mod definition; pub mod definition;
pub mod storage; pub mod storage;
pub mod mutation;

@ -0,0 +1,65 @@
use pest::iterators::Pair;
use crate::ast::{build_expr, Expr, ExprVisitor};
use crate::error::CozoError::ValueRequired;
use crate::eval::Evaluator;
use crate::storage::{RocksStorage};
use crate::error::Result;
use crate::parser::{Parser, Rule};
use crate::value::Value;
impl Evaluator<RocksStorage> {
pub fn eval_mutation(&mut self, pair: Pair<Rule>) -> Result<()> {
let mut pairs = pair.into_inner();
let op = pairs.next().unwrap().as_rule();
let expr = pairs.next().unwrap();
let expr = build_expr(expr)?;
let expr = self.visit_expr(&expr)?;
let val = match expr {
Expr::Const(v) => v,
_ => return Err(ValueRequired)
};
println!("{:#?}", val);
Ok(())
}
}
#[cfg(test)]
mod tests {
use std::fs;
use super::*;
use crate::ast::{Expr, ExprVisitor, parse_expr_from_str};
use crate::eval::{BareEvaluator, EvaluatorWithStorage};
use pest::Parser as PestParser;
use cozo_rocks::DBImpl;
use crate::env::Env;
use crate::typing::Structured;
#[test]
fn data() -> Result<()> {
let ddl = fs::read_to_string("test_data/hr.cozo")?;
let parsed = Parser::parse(Rule::file, &ddl).unwrap();
let mut eval = EvaluatorWithStorage::new("_path_hr".to_string()).unwrap();
eval.build_table(parsed).unwrap();
eval.restore_metadata().unwrap();
println!("{:?}", eval.storage.db.all_cf_names());
let insertion = "insert $data;";
let mut insert_stmt = Parser::parse(Rule::mutation, insertion).unwrap();
let data = fs::read_to_string("test_data/hr.json")?;
let parsed = parse_expr_from_str(&data)?;
let mut ev = BareEvaluator::default();
let evaluated = ev.visit_expr(&parsed)?;
let bound_value = match evaluated {
Expr::Const(v) => v,
_ => unreachable!()
};
eval.env.push();
eval.env.define("$data".to_string(), Structured::Value(bound_value.to_owned()));
eval.eval_mutation(insert_stmt.next().unwrap()).unwrap();
// println!("{:#?}", evaluated);
eval.env.pop();
Ok(())
}
}

@ -204,6 +204,7 @@ pub enum Structured {
Edge(Edge), Edge(Edge),
Columns(Columns), Columns(Columns),
Index(Index), Index(Index),
Value(Value<'static>)
} }
impl Structured { impl Structured {
@ -213,7 +214,8 @@ impl Structured {
Structured::Node(n) => Some(n.id.clone()), Structured::Node(n) => Some(n.id.clone()),
Structured::Edge(e) => Some(e.id.clone()), Structured::Edge(e) => Some(e.id.clone()),
Structured::Columns(c) => Some(c.id.clone()), Structured::Columns(c) => Some(c.id.clone()),
Structured::Index(i) => Some(i.id.clone()) Structured::Index(i) => Some(i.id.clone()),
Structured::Value(_) => None
} }
} }
} }

@ -6,6 +6,7 @@ use ordered_float::OrderedFloat;
use uuid::Uuid; use uuid::Uuid;
use crate::typing::{Typing}; use crate::typing::{Typing};
use Ordering::{Greater, Less, Equal}; use Ordering::{Greater, Less, Equal};
use std::sync::Arc;
// TODO: array types, alignment of values // TODO: array types, alignment of values
#[repr(u8)] #[repr(u8)]
@ -66,22 +67,22 @@ pub enum Value<'a> {
Float(f64), Float(f64),
Uuid(Uuid), Uuid(Uuid),
RefString(&'a str), RefString(&'a str),
OwnString(Box<String>), OwnString(Arc<String>),
List(Box<Vec<Value<'a>>>), List(Arc<Vec<Value<'a>>>),
Dict(Box<BTreeMap<Cow<'a, str>, Value<'a>>>), Dict(Arc<BTreeMap<Cow<'a, str>, Value<'a>>>),
} }
impl<'a> Value<'a> { impl<'a> Value<'a> {
pub fn get_list(self) -> Option<Vec<Self>> { pub fn get_list(&self) -> Option<Arc<Vec<Self>>> {
match self { match self {
Value::List(v) => Some(*v), Value::List(v) => Some(v.clone()),
_ => None _ => None
} }
} }
pub fn get_string(self) -> Option<String> { pub fn get_string(&self) -> Option<Arc<String>> {
match self { match self {
Value::OwnString(v) => Some(*v), Value::OwnString(v) => Some(v.clone()),
Value::RefString(v) => Some(v.to_string()), Value::RefString(v) => Some(Arc::new(v.to_string())),
_ => None _ => None
} }
} }
@ -282,8 +283,8 @@ impl<'a> ByteArrayParser<'a> {
FloatTag => Some(Float(self.parse_float()?)), FloatTag => Some(Float(self.parse_float()?)),
StringTag => Some(RefString(self.parse_string()?)), StringTag => Some(RefString(self.parse_string()?)),
UIntTag => Some(UInt(self.parse_varint()?)), UIntTag => Some(UInt(self.parse_varint()?)),
ListTag => Some(List(Box::new(self.parse_list()?))), ListTag => Some(List(Arc::new(self.parse_list()?))),
DictTag => Some(Dict(Box::new(self.parse_dict()?))), DictTag => Some(Dict(Arc::new(self.parse_dict()?))),
UuidTag => Some(Uuid(self.parse_uuid()?)) UuidTag => Some(Uuid(self.parse_uuid()?))
} }
} }
@ -505,35 +506,35 @@ pub fn cmp_data<'a>(pa: &mut ByteArrayParser<'a>, pb: &mut ByteArrayParser<'a>)
impl<'a> Value<'a> { impl<'a> Value<'a> {
pub fn into_owned(self) -> Value<'static> { pub fn to_owned(&self) -> Value<'static> {
use Value::*; use Value::*;
match self { match self {
Null => Null, Null => Null,
Bool(b) => Bool(b), Bool(b) => Bool(*b),
EdgeDir(dir) => EdgeDir(dir), EdgeDir(dir) => EdgeDir(*dir),
UInt(u) => UInt(u), UInt(u) => UInt(*u),
Int(i) => Int(i), Int(i) => Int(*i),
Float(f) => Float(f), Float(f) => Float(*f),
RefString(s) => OwnString(Box::new(s.to_string())), RefString(s) => OwnString(Arc::new(s.to_string())),
OwnString(s) => OwnString(s), OwnString(s) => OwnString(s.clone()),
List(l) => { List(l) => {
let mut inner = Vec::with_capacity(l.len()); let mut inner = Vec::with_capacity(l.len());
for el in *l { for el in l.iter() {
inner.push(el.into_owned()) inner.push(el.clone().to_owned())
} }
List(Box::new(inner)) List(Arc::new(inner))
} }
Dict(d) => { Dict(d) => {
let mut inner = BTreeMap::new(); let mut inner = BTreeMap::new();
for (k, v) in *d { for (k, v) in d.iter() {
let new_k = Cow::from(k.into_owned()); let new_k = Cow::from(k.clone().into_owned());
inner.insert(new_k, v.into_owned()); inner.insert(new_k, v.clone().to_owned());
} }
Dict(Box::new(inner)) Dict(Arc::new(inner))
} }
Uuid(u) => Uuid(u), Uuid(u) => Uuid(*u),
} }
} }
} }

@ -0,0 +1,62 @@
create node Job {
*id: Int,
title: String,
min_salary: Float,
max_salary: Float
}
create node Employee {
*id: Int,
first_name: String,
last_name: String,
email: String,
phone_number: ?String
}
create node Dependent {
*id: Int,
first_name: String,
last_name: String
}
create node Department {
*id: Int,
name: String
}
create node Location {
*id: Int,
street_address: String,
postal_code: ?String,
city: String,
state_province: ?String
}
create node Country {
*id: String,
name: String
}
create node Region {
*id: Int,
name: String
}
create edge (Employee)-[HasJob]->(Job) {
salary: Float,
hire_date: String
}
create edge (Employee)-[InDepartment]->(Department)
create edge (Employee)-[Manages]->(Employee)
create edge (Employee)-[HasDependent]->(Dependent) {
relationship: String
}
create edge (Department)-[InLocation]->(Location)
create edge (Location)-[InCountry]->(Country)
create edge (Country)-[InRegion]->(Region)

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save