compiling commit

main
Ziyang Hu 2 years ago
parent 54c9327941
commit ffb24a612a

@ -1,4 +1,4 @@
use std::rc::Rc;
use std::sync::Arc;
use pest::iterators::{Pair};
use pest::Parser as PestParser;
use pest::prec_climber::{Assoc, PrecClimber, Operator};
@ -194,7 +194,7 @@ fn build_expr_primary(pair: Pair<Rule>) -> Result<Expr> {
Rule::null => Ok(Const(Value::Null)),
Rule::boolean => Ok(Const(Value::Bool(pair.as_str() == "true"))),
Rule::quoted_string | Rule::s_quoted_string | Rule::raw_string => Ok(
Const(Value::OwnString(Rc::new(parse_string(pair)?)))),
Const(Value::OwnString(Arc::new(parse_string(pair)?)))),
Rule::list => {
let mut vals = vec![];
let mut has_apply = false;
@ -211,7 +211,7 @@ fn build_expr_primary(pair: Pair<Rule>) -> Result<Expr> {
if has_apply {
Ok(Expr::List(vals))
} else {
Ok(Const(Value::List(Rc::new(vals.into_iter().map(|v| {
Ok(Const(Value::List(Arc::new(vals.into_iter().map(|v| {
match v {
Apply(_, _) => { unreachable!() }
Expr::List(_) => { unreachable!() }
@ -249,7 +249,7 @@ fn build_expr_primary(pair: Pair<Rule>) -> Result<Expr> {
if has_apply {
Ok(Expr::Dict(keys, vals))
} else {
Ok(Const(Value::Dict(Rc::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 {
Expr::List(_) => { unreachable!() }
Expr::Dict(_, _) => { unreachable!() }

@ -1,15 +1,16 @@
use std::borrow::{Borrow, BorrowMut};
use std::collections::BTreeMap;
use std::rc::Rc;
use std::sync::Arc;
use pest::iterators::{Pair, Pairs};
use crate::ast::parse_string;
use crate::env::{Env, LayeredEnv, StructuredEnvItem};
use crate::env::{Env, LayeredEnv, Environment};
use crate::error::Result;
use crate::error::CozoError::*;
use crate::eval::Evaluator;
use crate::storage::{RocksStorage};
use crate::typing::{Col, Columns, Edge, Index, Node, StorageStatus, Structured, TableId, Typing};
use crate::typing::StorageStatus::{Planned, Stored};
use crate::value::{ByteArrayBuilder, ByteArrayParser, Value};
use crate::value::{ByteArrayBuilder, ByteArrayParser, StaticValue, Value};
use crate::parser::{Parser, Rule};
use pest::Parser as PestParser;
use cozo_rocks::*;
@ -46,11 +47,12 @@ fn parse_col_name(pair: Pair<Rule>) -> Result<(String, bool)> {
}
impl StructuredEnvItem {
impl Environment {
pub fn build_edge_def(&mut self, pair: Pair<Rule>, local_id: usize) -> Result<String> {
let mut inner = pair.into_inner();
let src_name = build_name_in_def(inner.next().unwrap(), true)?;
let src = self.resolve(&src_name).ok_or(UndefinedType)?;
let src = src.borrow();
let src_id = if let Structured::Node(n) = src {
n.id.clone()
} else {
@ -59,6 +61,7 @@ impl StructuredEnvItem {
let name = build_name_in_def(inner.next().unwrap(), true)?;
let dst_name = build_name_in_def(inner.next().unwrap(), true)?;
let dst = self.resolve(&dst_name).ok_or(UndefinedType)?;
let dst = dst.borrow();
let dst_id = if let Structured::Node(n) = dst {
n.id.clone()
} else {
@ -80,6 +83,7 @@ impl StructuredEnvItem {
id: table_id.clone(),
keys,
cols,
col_map: BTreeMap::new(),
};
if self.define_new(name.clone(), Structured::Edge(edge)) {
if let Some(Structured::Node(src)) = self.resolve_mut(&src_name) {
@ -111,6 +115,7 @@ impl StructuredEnvItem {
out_e: vec![],
in_e: vec![],
attached: vec![],
col_map: BTreeMap::new(),
};
if self.define_new(name.clone(), Structured::Node(node)) {
Ok(name)
@ -131,6 +136,7 @@ impl StructuredEnvItem {
let name = build_name_in_def(inner.next().unwrap(), true)?;
let node_name = build_name_in_def(inner.next().unwrap(), true)?;
let node = self.resolve(&node_name).ok_or(UndefinedType)?;
let node = node.borrow();
let node_id = if let Structured::Node(n) = node {
n.id.clone()
} else if let Structured::Edge(n) = node {
@ -184,6 +190,7 @@ impl StructuredEnvItem {
};
let node = self.resolve(&node_name).ok_or(UndefinedType)?;
let node = node.borrow();
let node_id = if let Structured::Node(n) = node {
n.id.clone()
} else {
@ -226,7 +233,9 @@ impl StructuredEnvItem {
let t = match inner.as_rule() {
Rule::simple_type => {
let name = parse_ident(inner.into_inner().next().unwrap());
if let Some(Structured::Typing(t)) = self.resolve(&name) {
let typ = self.resolve(&name).ok_or(UndefinedType)?;
let typ = typ.borrow();
if let Structured::Typing(t) = typ {
t.clone()
} else {
return Err(UndefinedType);
@ -246,7 +255,7 @@ impl StructuredEnvItem {
})
}
fn build_default_value(&self, _pair: Pair<Rule>) -> Result<Value<'static>> {
fn build_default_value(&self, _pair: Pair<Rule>) -> Result<StaticValue> {
// TODO: _pair is an expression, parse it and evaluate it to a constant value
Ok(Value::Null)
}
@ -294,11 +303,11 @@ pub enum TableKind {
impl RocksStorage {
#[allow(unused_variables)]
fn all_metadata(&self, env: &StructuredEnvItem) -> Result<Vec<Structured>> {
fn all_metadata(&self) -> Result<Vec<Structured>> {
let default_cf = self.db.get_cf_handle("default")?;
let it = self.db.iterator(&default_cf, None);
let mut ret = vec![];
let env = self.root_env.write().expect("Root environment poisoned");
while it.is_valid() {
let k = it.key();
let v = it.value();
@ -347,6 +356,7 @@ impl RocksStorage {
out_e: vec![], // TODO fix these
in_e: vec![],
attached: vec![],
col_map: BTreeMap::new(),
};
ret.push(Structured::Node(node));
}
@ -390,6 +400,7 @@ impl RocksStorage {
id: table_id,
keys,
cols,
col_map: BTreeMap::new(),
};
ret.push(Structured::Edge(edge));
}
@ -413,17 +424,17 @@ impl RocksStorage {
key_writer.build_value(&Value::RefString(&node.id.name));
let mut val_writer = ByteArrayBuilder::with_capacity(128);
val_writer.build_value(&Value::UInt(TableKind::Node as u64));
val_writer.build_value(&Value::List(Rc::new(node.keys.iter().map(|k| {
Value::List(Rc::new(vec![
val_writer.build_value(&Value::List(Arc::new(node.keys.iter().map(|k| {
Value::List(Arc::new(vec![
Value::RefString(&k.name),
Value::OwnString(Rc::new(format!("{}", k.typ))),
Value::OwnString(Arc::new(format!("{}", k.typ))),
k.default.clone(),
]))
}).collect())));
val_writer.build_value(&Value::List(Rc::new(node.cols.iter().map(|k| {
Value::List(Rc::new(vec![
val_writer.build_value(&Value::List(Arc::new(node.cols.iter().map(|k| {
Value::List(Arc::new(vec![
Value::RefString(&k.name),
Value::OwnString(Rc::new(format!("{}", k.typ))),
Value::OwnString(Arc::new(format!("{}", k.typ))),
k.default.clone(),
]))
}).collect())));
@ -442,17 +453,17 @@ impl RocksStorage {
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.dst.name));
val_writer.build_value(&Value::List(Rc::new(edge.keys.iter().map(|k| {
Value::List(Rc::new(vec![
val_writer.build_value(&Value::List(Arc::new(edge.keys.iter().map(|k| {
Value::List(Arc::new(vec![
Value::RefString(&k.name),
Value::OwnString(Rc::new(format!("{}", k.typ))),
Value::OwnString(Arc::new(format!("{}", k.typ))),
k.default.clone(),
]))
}).collect())));
val_writer.build_value(&Value::List(Rc::new(edge.cols.iter().map(|k| {
Value::List(Rc::new(vec![
val_writer.build_value(&Value::List(Arc::new(edge.cols.iter().map(|k| {
Value::List(Arc::new(vec![
Value::RefString(&k.name),
Value::OwnString(Rc::new(format!("{}", k.typ))),
Value::OwnString(Arc::new(format!("{}", k.typ))),
k.default.clone(),
]))
}).collect())));
@ -465,15 +476,15 @@ impl RocksStorage {
impl Evaluator<RocksStorage> {
pub fn restore_metadata(&mut self) -> Result<()> {
let mds = self.storage.all_metadata(self.env.root())?;
let mds = self.storage.all_metadata()?;
for md in &mds {
match md {
v @ Structured::Node(n) => {
// TODO: check if they are the same if one already exists
self.env.root_define(n.id.name.clone(), v.clone());
self.root_define(n.id.name.clone(), v.clone());
}
v @ Structured::Edge(e) => {
self.env.root_define(e.id.name.clone(), v.clone());
self.root_define(e.id.name.clone(), v.clone());
}
Structured::Columns(_) => {}
Structured::Index(_) => {}
@ -484,22 +495,24 @@ impl Evaluator<RocksStorage> {
Ok(())
}
fn persist_change(&mut self, tname: &str, global: bool) -> Result<()> {
let tbl = self.env.resolve_mut(tname).unwrap();
self.storage.create_table(tname, global)?;
if global {
match tbl {
Structured::Node(n) => self.storage.persist_node(n),
Structured::Edge(e) => self.storage.persist_edge(e),
Structured::Columns(_) => unimplemented!(),
Structured::Index(_) => unimplemented!(),
Structured::Typing(_) => panic!(),
Structured::Value(_) => unreachable!()
}
} else {
Ok(())
}
}
// fn persist_change(&mut self, tname: &str, global: bool) -> Result<()> {
// self.storage.create_table(tname, global)?;
// let tbl = {
// self.resolve_mut(tname).unwrap()
// };
// if global {
// match tbl {
// Structured::Node(n) => self.storage.persist_node(n),
// Structured::Edge(e) => self.storage.persist_edge(e),
// Structured::Columns(_) => unimplemented!(),
// Structured::Index(_) => unimplemented!(),
// Structured::Typing(_) => panic!(),
// Structured::Value(_) => unreachable!()
// }
// } else {
// Ok(())
// }
// }
pub fn build_table(&mut self, pairs: Pairs<Rule>) -> Result<()> {
@ -509,12 +522,14 @@ impl Evaluator<RocksStorage> {
r @ (Rule::global_def | Rule::local_def) => {
let inner = pair.into_inner().next().unwrap();
let global = r == Rule::global_def;
let local_id = self.get_next_local_id(global);
let env_to_build = if global {
self.env.root_mut()
} else {
self.env.cur_mut()
};
let local_id = self.storage.get_next_local_id(global);
let mut env_to_build =
// if global {
// self.storage.root_env.write().expect("Root environment poisoned").borrow_mut()
// } else {
self.env_stack.last_mut().unwrap()
;
// };
new_tables.push((global, match inner.as_rule() {
Rule::node_def => {
env_to_build.build_node_def(inner, local_id)?
@ -536,7 +551,7 @@ impl Evaluator<RocksStorage> {
}
}
for (global, tname) in &new_tables {
self.persist_change(tname, *global).unwrap(); // TODO proper error handling
// self.persist_change(tname, *global).unwrap(); // TODO proper error handling
}
Ok(())
}
@ -554,6 +569,8 @@ mod tests {
use crate::eval::EvaluatorWithStorage;
use crate::parser::Parser;
fn send_sync<X: Send + Sync>(_x: &X) {}
#[test]
fn definitions() {
let s = r#"
@ -569,11 +586,13 @@ mod tests {
}
"#;
let parsed = Parser::parse(Rule::file, s).unwrap();
let mut eval = EvaluatorWithStorage::new("_path_for_rocksdb_storagex".to_string()).unwrap();
let db = RocksStorage::new("_path_for_rocksdb_storagex".to_string()).unwrap();
send_sync(&db);
let mut eval = EvaluatorWithStorage::new(db).unwrap();
eval.build_table(parsed).unwrap();
eval.restore_metadata().unwrap();
eval.storage.delete_storage().unwrap();
println!("{:#?}", eval.env.resolve("Person"));
println!("{:#?}", eval.env.resolve("Friend"));
// eval.storage.delete_storage().unwrap();
println!("{:#?}", eval.resolve("Person"));
println!("{:#?}", eval.resolve("Friend"));
}
}

@ -1,135 +1,35 @@
use std::borrow::Cow;
use std::collections::BTreeMap;
use crate::typing::{define_base_types, Structured};
use crate::typing::{Structured};
pub trait Env<V> {
pub trait Env<V> where V: Clone {
fn define(&mut self, name: String, value: V) -> Option<V>;
fn define_new(&mut self, name: String, value: V) -> bool;
fn resolve(&self, name: &str) -> Option<&V>;
fn resolve(&self, name: &str) -> Option<Cow<V>>;
fn resolve_mut(&mut self, name: &str) -> Option<&mut V>;
fn undef(&mut self, name: &str) -> Option<V>;
}
pub trait LayeredEnv<V>: Env<V> {
pub trait LayeredEnv<V>: Env<V> where V: Clone {
fn root_define(&mut self, name: String, value: V) -> Option<V>;
fn root_define_new(&mut self, name: String, value: V) -> bool;
fn root_resolve(&self, name: &str) -> Option<&V>;
fn root_resolve_mut(&mut self, name: &str) -> Option<&mut V>;
fn root_resolve(&self, name: &str) -> Option<Cow<V>>;
fn root_undef(&mut self, name: &str) -> Option<V>;
}
pub struct StructuredEnvItem {
pub struct Environment {
map: BTreeMap<String, Structured>,
}
pub struct StructuredEnv {
stack: Vec<StructuredEnvItem>,
}
impl StructuredEnv {
pub fn new() -> Self {
let mut root = StructuredEnvItem { map: BTreeMap::new() };
define_base_types(&mut root);
Self { stack: vec![root] }
}
pub fn root(&self) -> &StructuredEnvItem {
&self.stack[0]
}
pub fn root_mut(&mut self) -> &mut StructuredEnvItem {
&mut self.stack[0]
}
pub fn cur(&self) -> &StructuredEnvItem {
self.stack.last().unwrap()
}
pub fn cur_mut(&mut self) -> &mut StructuredEnvItem {
self.stack.last_mut().unwrap()
}
pub fn push(&mut self) {
self.stack.push(StructuredEnvItem { map: BTreeMap::new() })
}
pub fn pop(&mut self) -> bool {
if self.stack.len() <= 1 {
false
} else {
self.stack.pop();
true
}
}
}
impl LayeredEnv<Structured> for StructuredEnv {
fn root_define(&mut self, name: String, value: Structured) -> Option<Structured> {
self.root_mut().define(name, value)
}
fn root_define_new(&mut self, name: String, value: Structured) -> bool {
self.root_mut().define_new(name, value)
}
fn root_resolve(&self, name: &str) -> Option<&Structured> {
self.root().resolve(name)
}
fn root_resolve_mut(&mut self, name: &str) -> Option<&mut Structured> {
self.root_mut().resolve_mut(name)
}
fn root_undef(&mut self, name: &str) -> Option<Structured> {
self.root_mut().undef(name)
}
}
impl Env<Structured> for StructuredEnv {
fn define(&mut self, name: String, value: Structured) -> Option<Structured> {
self.stack.last_mut().unwrap().define(name, value)
}
fn define_new(&mut self, name: String, value: Structured) -> bool {
self.stack.last_mut().unwrap().define_new(name, value)
}
fn resolve(&self, name: &str) -> Option<&Structured> {
let mut res = None;
for item in self.stack.iter().rev() {
res = item.resolve(name);
if res.is_some() {
return res;
}
}
res
}
fn resolve_mut(&mut self, name: &str) -> Option<&mut Structured> {
let mut res = None;
for item in self.stack.iter_mut().rev() {
res = item.resolve_mut(name);
if res.is_some() {
return res;
}
}
res
}
fn undef(&mut self, name: &str) -> Option<Structured> {
let mut res = None;
for item in self.stack.iter_mut().rev() {
res = item.undef(name);
if res.is_some() {
return res;
}
}
res
impl Default for Environment {
fn default() -> Self {
Self { map: BTreeMap::new() }
}
}
impl Env<Structured> for StructuredEnvItem {
impl Env<Structured> for Environment {
fn define(&mut self, name: String, value: Structured) -> Option<Structured> {
let old = self.map.remove(&name);
self.map.insert(name, value);
@ -145,8 +45,9 @@ impl Env<Structured> for StructuredEnvItem {
}
}
fn resolve(&self, name: &str) -> Option<&Structured> {
fn resolve(&self, name: &str) -> Option<Cow<Structured>> {
self.map.get(name)
.map(|v| Cow::Borrowed(v))
}
fn resolve_mut(&mut self, name: &str) -> Option<&mut Structured> {
@ -158,10 +59,3 @@ impl Env<Structured> for StructuredEnvItem {
self.map.remove(name)
}
}
impl Default for StructuredEnv {
fn default() -> Self {
StructuredEnv::new()
}
}

@ -1,4 +1,5 @@
use std::rc::Rc;
use std::borrow::{Borrow, Cow};
use std::sync::Arc;
use crate::ast::Expr;
use crate::ast::Expr::*;
use crate::error::Result;
@ -6,52 +7,124 @@ use crate::error::CozoError;
use crate::error::CozoError::*;
use crate::value::Value::*;
use crate::ast::*;
use crate::env::{Env, StructuredEnv};
use crate::env::{Env, Environment, LayeredEnv};
use crate::storage::{DummyStorage, RocksStorage, Storage};
use crate::typing::Structured;
pub struct Evaluator<S: Storage> {
pub env: StructuredEnv,
pub env_stack: Vec<Environment>,
pub storage: S,
pub last_local_id: usize,
}
impl<S: Storage> Evaluator<S> {
pub fn get_next_local_id(&mut self, is_global: bool) -> usize {
if is_global {
0
} else {
self.last_local_id += 1;
self.last_local_id
impl Env<Structured> for Evaluator<DummyStorage> {
fn define(&mut self, name: String, value: Structured) -> Option<Structured> {
None
}
fn define_new(&mut self, name: String, value: Structured) -> bool {
false
}
fn resolve(&self, name: &str) -> Option<Cow<Structured>> {
None
}
fn resolve_mut(&mut self, name: &str) -> Option<&mut Structured> {
None
}
fn undef(&mut self, name: &str) -> Option<Structured> {
None
}
}
impl Env<Structured> for Evaluator<RocksStorage> {
fn define(&mut self, name: String, value: Structured) -> Option<Structured> {
self.env_stack.last_mut().unwrap().define(name, value)
}
fn define_new(&mut self, name: String, value: Structured) -> bool {
if self.env_stack.is_empty() {
self.env_stack.push(Environment::default());
}
self.env_stack.last_mut().unwrap().define_new(name, value)
}
fn resolve(&self, name: &str) -> Option<Cow<Structured>> {
let mut res = None;
for item in self.env_stack.iter().rev() {
res = item.resolve(name);
if res.is_some() {
return res;
}
}
// Unwrap here because read() only fails if lock is poisoned
let env = self.storage.root_env.read().expect("Root environment is poisoned");
env.resolve(name).map(|v| Cow::Owned(v.into_owned()))
}
fn resolve_mut(&mut self, name: &str) -> Option<&mut Structured> {
// Cannot obtain root elements this way
let mut res = None;
for item in self.env_stack.iter_mut().rev() {
res = item.resolve_mut(name);
if res.is_some() {
return res;
}
}
res
}
fn undef(&mut self, name: &str) -> Option<Structured> {
// Cannot undef root elements this way
let mut res = None;
for item in self.env_stack.iter_mut().rev() {
res = item.undef(name);
if res.is_some() {
return res;
}
}
res
}
}
impl LayeredEnv<Structured> for Evaluator<RocksStorage> {
fn root_define(&mut self, name: String, value: Structured) -> Option<Structured> {
self.storage.root_env.write().expect("Root environment is poisoned")
.define(name, value)
}
fn root_define_new(&mut self, name: String, value: Structured) -> bool {
self.storage.root_env.write().expect("Root environment is poisoned")
.define_new(name, value)
}
fn root_resolve(&self, name: &str) -> Option<Cow<Structured>> {
let env = self.storage.root_env.read().expect("Root environment is poisoned");
env.resolve(name).map(|v| Cow::Owned(v.into_owned()))
}
fn root_undef(&mut self, name: &str) -> Option<Structured> {
self.storage.root_env.write().expect("Root environment is poisoned")
.undef(name)
}
}
pub type EvaluatorWithStorage = Evaluator<RocksStorage>;
pub type BareEvaluator = Evaluator<DummyStorage>;
impl EvaluatorWithStorage {
pub fn new(path: String) -> Result<Self> {
impl<S: Storage> Evaluator<S> {
pub fn new(storage: S) -> Result<Self> {
Ok(Self {
env: StructuredEnv::new(),
storage: RocksStorage::new(path)?,
last_local_id: 0,
env_stack: vec![Environment::default()],
storage,
})
}
}
impl Default for BareEvaluator {
fn default() -> Self {
Self {
env: StructuredEnv::new(),
storage: DummyStorage,
last_local_id: 0,
}
}
}
impl<'a, S: Storage> ExprVisitor<'a, Result<Expr<'a>>> for Evaluator<S> {
impl<'a, S: Storage> ExprVisitor<'a, Result<Expr<'a>>> for Evaluator<S>
where Evaluator<S>: Env<Structured> {
fn visit_expr(&self, ex: &Expr<'a>) -> Result<Expr<'a>> {
match ex {
Apply(op, args) => {
@ -82,8 +155,8 @@ impl<'a, S: Storage> ExprVisitor<'a, Result<Expr<'a>>> for Evaluator<S> {
Expr::List(_) => { unimplemented!() }
Expr::Dict(_, _) => { unimplemented!() }
Ident(ident) => {
let resolved = self.env.resolve(ident).ok_or(UndefinedParam)?;
match resolved {
let resolved = self.resolve(ident).ok_or(UndefinedParam)?;
match resolved.borrow() {
Structured::Value(v) => {
Ok(Const(v.clone()))
}
@ -94,7 +167,8 @@ impl<'a, S: Storage> ExprVisitor<'a, Result<Expr<'a>>> for Evaluator<S> {
}
}
impl<S: Storage> Evaluator<S> {
impl<S: Storage> Evaluator<S>
where Evaluator<S>: Env<Structured> {
fn add_exprs<'a>(&self, exprs: &[Expr<'a>]) -> Result<Expr<'a>> {
match exprs {
[a, b] => {
@ -110,10 +184,10 @@ impl<S: Storage> Evaluator<S> {
(Float(va), Int(vb)) => Float(va + vb as f64),
(Int(va), Float(vb)) => Float(va as f64 + vb),
(Float(va), Float(vb)) => Float(va + vb),
(OwnString(va), OwnString(vb)) => OwnString(Rc::new(va.clone().to_string() + &vb)),
(OwnString(va), RefString(vb)) => OwnString(Rc::new(va.clone().to_string() + &*vb)),
(RefString(va), OwnString(vb)) => OwnString(Rc::new(va.to_string() + &*vb)),
(RefString(va), RefString(vb)) => OwnString(Rc::new(va.to_string() + &*vb)),
(OwnString(va), OwnString(vb)) => OwnString(Arc::new(va.clone().to_string() + &vb)),
(OwnString(va), RefString(vb)) => OwnString(Arc::new(va.clone().to_string() + &*vb)),
(RefString(va), OwnString(vb)) => OwnString(Arc::new(va.to_string() + &*vb)),
(RefString(va), RefString(vb)) => OwnString(Arc::new(va.to_string() + &*vb)),
(_, _) => return Err(CozoError::TypeError)
}
}
@ -536,7 +610,7 @@ mod tests {
#[test]
fn operators() {
let ev = BareEvaluator::default();
let ev = Evaluator::new(DummyStorage {}).unwrap();
println!("{:#?}", ev.visit_expr(&parse_expr_from_str("1/10+(-2+3)*4^5").unwrap()).unwrap());
println!("{:#?}", ev.visit_expr(&parse_expr_from_str("true && false").unwrap()).unwrap());

@ -1,6 +1,6 @@
use std::fmt::{Debug, Formatter};
use crate::typing::{Typing};
use crate::value::Value;
use crate::value::{StaticValue, Value};
// use lazy_static::lazy_static;
#[derive(PartialEq, Debug)]
@ -35,7 +35,7 @@ impl PartialEq for FunctionImpl {
#[derive(PartialEq, Debug)]
pub struct Arg {
pub typing: Typing,
pub default_val: Option<Value<'static>>,
pub default_val: Option<StaticValue>,
pub name: Option<String>,
}

@ -8,4 +8,5 @@ pub mod function;
pub mod error;
pub mod definition;
pub mod storage;
pub mod mutation;
pub mod mutation;
pub mod plan;

@ -1,3 +1,4 @@
use std::borrow::Borrow;
use std::collections::BTreeMap;
use pest::iterators::Pair;
use crate::ast::{build_expr, Expr, ExprVisitor};
@ -26,9 +27,10 @@ impl Evaluator<RocksStorage> {
Some(v) => {
match v.as_rule() {
Rule::name_in_def => {
let resolved = self.env.resolve(&build_name_in_def(v, true)?)
.ok_or(UndefinedTable)?;
main_target = Some(resolved);
// let resolved = self.resolve(&build_name_in_def(v, true)?)
// .ok_or(UndefinedTable)?.borrow();
// main_target = Some(resolved);
todo!()
}
Rule::mutation_filter => {
main_target = None;
@ -61,36 +63,35 @@ 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 crate::env::Env;
use crate::storage::DummyStorage;
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();
let db = RocksStorage::new("_path_hr".to_string())?;
let mut eval = Evaluator::new(db).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 ev = BareEvaluator::default();
let ev = Evaluator::new(DummyStorage {})?;
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.owned_clone()));
eval.define("$data".to_string(), Structured::Value(bound_value.owned_clone()));
eval.eval_mutation(insert_stmt.next().unwrap()).unwrap();
// println!("{:#?}", evaluated);
eval.env.pop();
Ok(())
}
}

@ -1,6 +1,9 @@
use std::fs;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::{RwLock};
use crate::error::{CozoError, Result};
use cozo_rocks::*;
use crate::env::Environment;
use crate::value::{cozo_comparator_v1};
@ -8,8 +11,14 @@ pub struct RocksStorage {
pub db: DB,
#[allow(dead_code)]
path: String,
last_local_id: AtomicUsize,
pub root_env: RwLock<Environment>,
}
const DEFAULT_CF: &str = "default";
const SCRATCH_CF: &str = "scratch";
const COMPARATOR_NAME: &str = "cozo_comparator_v1";
impl RocksStorage {
#[allow(unused_variables)]
pub fn new(path: String) -> Result<Self> {
@ -17,18 +26,26 @@ impl RocksStorage {
.increase_parallelism()
.optimize_level_style_compaction()
.set_create_if_missing(true)
.set_comparator("cozo_comparator_v1", cozo_comparator_v1);
.set_comparator(COMPARATOR_NAME, cozo_comparator_v1);
let db = DB::open(options, path.as_ref())?;
Ok(RocksStorage {db, path})
(match db.create_column_family(SCRATCH_CF) {
Err(s) if s.bridge_code == StatusBridgeCode::EXISTING_ERROR => Ok(()),
v => v
})?;
let mut env = Environment::default();
env.define_base_types();
Ok(RocksStorage {
db,
path,
last_local_id: AtomicUsize::new(0),
root_env: RwLock::new(env),
})
}
#[allow(unused_variables)]
pub fn delete_storage(self) -> Result<()> {
// unimplemented!()
// drop(self.db.take());
// DB::destroy(&make_options(), &self.path)?;
let path = self.path.clone();
let path = self.path.clone();
drop(self);
fs::remove_dir_all(path)?;
Ok(())
@ -36,25 +53,37 @@ impl RocksStorage {
#[allow(unused_variables)]
pub fn put_global(&self, k: &[u8], v: &[u8]) -> Result<()> {
// let db = self.db.as_ref().ok_or(DatabaseClosed)?;
let default_cf = self.db.get_cf_handle("default")?;
let default_cf = self.db.get_cf_handle(DEFAULT_CF)?;
self.db.put(k, v, &default_cf, None)?;
Ok(())
}
#[allow(unused_variables)]
pub fn create_table(&mut self, name: &str, _global: bool) -> Result<()> {
match self.db.create_column_family(name) {
pub fn create_table(&self, name: &str, _global: bool) -> Result<()> {
match self.db.create_column_family(table_name_to_cf_name(name)) {
Ok(_) => Ok(()),
Err(s) if s.bridge_code == StatusBridgeCode::EXISTING_ERROR => Ok(()),
Err(e) => Err(CozoError::Storage(e))
}
}
#[allow(unused_variables)]
pub fn drop_table(&mut self, name: &str, _global: bool) -> Result<()> {
self.db.drop_column_family(name)?;
pub fn drop_table(&self, name: &str, _global: bool) -> Result<()> {
self.db.drop_column_family(table_name_to_cf_name(name))?;
Ok(())
}
pub fn get_next_local_id(&self, global: bool) -> usize {
if global {
0
} else {
self.last_local_id.fetch_add(1, Ordering::Relaxed) + 1
}
}
}
#[inline]
fn table_name_to_cf_name(name: &str) -> String {
format!("${}", name)
}
pub trait Storage {}

@ -1,7 +1,7 @@
use std::collections::BTreeMap;
use std::fmt::{Debug, Display, Formatter, Write};
use crate::env::{Env};
use crate::value::Value;
use crate::env::{Env, Environment};
use crate::value::{StaticValue, Value};
#[derive(Debug, Eq, PartialEq, Clone)]
pub enum BaseType {
@ -43,7 +43,7 @@ pub enum BaseType {
pub struct Col {
pub name: String,
pub typ: Typing,
pub default: Value<'static>,
pub default: StaticValue,
}
@ -77,13 +77,22 @@ impl Debug for TableId {
}
}
#[derive(Ord, PartialOrd, Eq, PartialEq)]
pub struct ColumnId(TableId, i64);
#[derive(Ord, PartialOrd, Eq, PartialEq, Clone)]
pub struct ColumnId {
table_id: TableId,
is_key: bool,
col_order: usize,
}
impl Debug for ColumnId {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str(&format!("{:?}", self.0))?;
f.write_str(&format!("~{}", self.1))?;
f.write_str(&format!("{:?}", self.table_id))?;
if self.is_key {
f.write_char('*')?;
} else {
f.write_char('-')?;
}
f.write_str(&format!("{}", self.col_order))?;
Ok(())
}
}
@ -97,6 +106,7 @@ pub struct Node {
pub out_e: Vec<TableId>,
pub in_e: Vec<TableId>,
pub attached: Vec<TableId>,
pub col_map: BTreeMap<String, ColumnId>,
}
#[derive(Debug, PartialEq, Clone)]
@ -107,6 +117,7 @@ pub struct Edge {
pub id: TableId,
pub keys: Vec<Col>,
pub cols: Vec<Col>,
pub col_map: BTreeMap<String, ColumnId>,
}
#[derive(Debug, PartialEq, Clone)]
@ -204,7 +215,7 @@ pub enum Structured {
Edge(Edge),
Columns(Columns),
Index(Index),
Value(Value<'static>)
Value(StaticValue),
}
impl Structured {
@ -220,24 +231,26 @@ impl Structured {
}
}
pub fn define_base_types<T: Env<Structured>>(env: &mut T) {
env.define("Any".to_string(), Structured::Typing(Typing::Any));
env.define("Bool".to_string(), Structured::Typing(Typing::Base(BaseType::Bool)));
env.define("Int".to_string(), Structured::Typing(Typing::Base(BaseType::Int)));
env.define("UInt".to_string(), Structured::Typing(Typing::Base(BaseType::UInt)));
env.define("Float".to_string(), Structured::Typing(Typing::Base(BaseType::Float)));
env.define("String".to_string(), Structured::Typing(Typing::Base(BaseType::String)));
env.define("Bytes".to_string(), Structured::Typing(Typing::Base(BaseType::U8Arr)));
env.define("U8Arr".to_string(), Structured::Typing(Typing::Base(BaseType::U8Arr)));
env.define("Uuid".to_string(), Structured::Typing(Typing::Base(BaseType::Uuid)));
env.define("Timestamp".to_string(), Structured::Typing(Typing::Base(BaseType::Timestamp)));
env.define("Datetime".to_string(), Structured::Typing(Typing::Base(BaseType::Datetime)));
env.define("Timezone".to_string(), Structured::Typing(Typing::Base(BaseType::Timezone)));
env.define("Date".to_string(), Structured::Typing(Typing::Base(BaseType::Date)));
env.define("Time".to_string(), Structured::Typing(Typing::Base(BaseType::Time)));
env.define("Duration".to_string(), Structured::Typing(Typing::Base(BaseType::Duration)));
env.define("BigInt".to_string(), Structured::Typing(Typing::Base(BaseType::BigInt)));
env.define("BigDecimal".to_string(), Structured::Typing(Typing::Base(BaseType::BigDecimal)));
env.define("Int".to_string(), Structured::Typing(Typing::Base(BaseType::Int)));
env.define("Crs".to_string(), Structured::Typing(Typing::Base(BaseType::Crs)));
impl Environment {
pub fn define_base_types(&mut self) {
self.define("Any".to_string(), Structured::Typing(Typing::Any));
self.define("Bool".to_string(), Structured::Typing(Typing::Base(BaseType::Bool)));
self.define("Int".to_string(), Structured::Typing(Typing::Base(BaseType::Int)));
self.define("UInt".to_string(), Structured::Typing(Typing::Base(BaseType::UInt)));
self.define("Float".to_string(), Structured::Typing(Typing::Base(BaseType::Float)));
self.define("String".to_string(), Structured::Typing(Typing::Base(BaseType::String)));
self.define("Bytes".to_string(), Structured::Typing(Typing::Base(BaseType::U8Arr)));
self.define("U8Arr".to_string(), Structured::Typing(Typing::Base(BaseType::U8Arr)));
self.define("Uuid".to_string(), Structured::Typing(Typing::Base(BaseType::Uuid)));
self.define("Timestamp".to_string(), Structured::Typing(Typing::Base(BaseType::Timestamp)));
self.define("Datetime".to_string(), Structured::Typing(Typing::Base(BaseType::Datetime)));
self.define("Timezone".to_string(), Structured::Typing(Typing::Base(BaseType::Timezone)));
self.define("Date".to_string(), Structured::Typing(Typing::Base(BaseType::Date)));
self.define("Time".to_string(), Structured::Typing(Typing::Base(BaseType::Time)));
self.define("Duration".to_string(), Structured::Typing(Typing::Base(BaseType::Duration)));
self.define("BigInt".to_string(), Structured::Typing(Typing::Base(BaseType::BigInt)));
self.define("BigDecimal".to_string(), Structured::Typing(Typing::Base(BaseType::BigDecimal)));
self.define("Int".to_string(), Structured::Typing(Typing::Base(BaseType::Int)));
self.define("Crs".to_string(), Structured::Typing(Typing::Base(BaseType::Crs)));
}
}

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

Loading…
Cancel
Save