From a15c43dc2e91b9b43c4d026875d1ebba16c5ebc3 Mon Sep 17 00:00:00 2001 From: Ziyang Hu Date: Sat, 21 May 2022 16:59:57 +0800 Subject: [PATCH] almost completing reify tables --- cozorocks/src/lib.rs | 2 +- src/algebra.rs | 7 +- src/algebra/parser.rs | 38 ++- src/data.rs | 2 +- src/data/eval.rs | 79 +++--- src/data/expr.rs | 37 +-- src/data/op.rs | 8 +- src/data/op/arithmetic.rs | 38 ++- src/data/op/boolean.rs | 3 +- src/data/op/combine.rs | 4 +- src/data/op/comparison.rs | 36 ++- src/data/op/sequence.rs | 2 +- src/data/op/text.rs | 6 +- src/data/op/uuid.rs | 4 +- src/data/parser.rs | 5 +- src/data/tuple.rs | 43 +-- src/data/tuple_set.rs | 22 +- src/data/value.rs | 12 +- src/ddl/parser.rs | 92 ++++--- src/ddl/reify.rs | 565 ++++++++++++++++++++++++++++---------- src/lib.rs | 4 +- src/runtime.rs | 2 +- src/runtime/instance.rs | 9 +- src/runtime/session.rs | 25 +- 24 files changed, 697 insertions(+), 348 deletions(-) diff --git a/cozorocks/src/lib.rs b/cozorocks/src/lib.rs index f1ee315c..49c65baa 100644 --- a/cozorocks/src/lib.rs +++ b/cozorocks/src/lib.rs @@ -307,7 +307,7 @@ impl TransactionPtr { pub fn get_for_update_owned( &self, options: &ReadOptions, - key: impl AsRef<[u8]> + key: impl AsRef<[u8]>, ) -> Result> { let mut slice = PinnableSlicePtr::default(); if self.get_for_update(options, key, &mut slice)? { diff --git a/src/algebra.rs b/src/algebra.rs index c7f98994..0290fa8c 100644 --- a/src/algebra.rs +++ b/src/algebra.rs @@ -3,13 +3,11 @@ mod parser; use crate::data::expr::StaticExpr; use crate::data::tuple_set::TupleSet; - pub(crate) trait Algebra { fn get_iterator(&self) -> TupleSource; fn get_filter(&self) -> Filter; } - type AlgebraItem = Box; type AlgebraPair = (Box, Box); @@ -30,8 +28,7 @@ impl Default for Filter { } } -type TupleSource = Box>; - +type TupleSource = Box>; // pub(crate) struct Source(TupleSource); @@ -76,4 +73,4 @@ pub(crate) struct Insert { pub(crate) struct Delete { algebra: AlgebraItem, -} \ No newline at end of file +} diff --git a/src/algebra/parser.rs b/src/algebra/parser.rs index f45b5bdf..fed8c929 100644 --- a/src/algebra/parser.rs +++ b/src/algebra/parser.rs @@ -1,10 +1,10 @@ -use std::result; -use std::sync::Arc; use crate::data::eval::EvalError; use crate::data::expr::Expr; use crate::data::parser::ExprParseError; -use crate::data::value::{StaticValue}; +use crate::data::value::StaticValue; use crate::parser::{Pair, Pairs, Rule}; +use std::result; +use std::sync::Arc; #[derive(thiserror::Error, Debug)] pub(crate) enum AlgebraParseError { @@ -34,29 +34,32 @@ const NAME_RA_FROM_VALUES: &str = "Values"; #[derive(Clone, Debug)] struct RaFromValues { - values: StaticValue + values: StaticValue, } impl RaFromValues { fn build(prev: Option>, mut args: Pairs) -> Result { if !matches!(prev, None) { - return Err(AlgebraParseError::Unchainable(NAME_RA_FROM_VALUES.to_string())); + return Err(AlgebraParseError::Unchainable( + NAME_RA_FROM_VALUES.to_string(), + )); } let data = args.next().unwrap().into_inner().next().unwrap(); if data.as_rule() != Rule::expr { return Err(AlgebraParseError::WrongArgumentType( NAME_RA_FROM_VALUES.to_string(), - format!("{:?}", data.as_rule()))); + format!("{:?}", data.as_rule()), + )); } if args.next() != None { - return Err(AlgebraParseError::WrongArgumentCount(NAME_RA_FROM_VALUES.to_string())); + return Err(AlgebraParseError::WrongArgumentCount( + NAME_RA_FROM_VALUES.to_string(), + )); } let data = Expr::try_from(data)?; let data = data.row_eval(&())?.to_static(); - Ok(Self { - values: data - }) + Ok(Self { values: data }) } } @@ -68,7 +71,6 @@ impl RelationalAlgebra for RaFromValues { const NAME_INSERT: &str = "Insert"; - fn build_ra_expr(pair: Pair) -> Result> { let mut built: Option> = None; for pair in pair.into_inner() { @@ -78,7 +80,7 @@ fn build_ra_expr(pair: Pair) -> Result> { NAME_RA_FROM_VALUES => { built = Some(Arc::new(RaFromValues::build(built, pairs)?)); } - _ => unimplemented!() + _ => unimplemented!(), } } Ok(built.unwrap()) @@ -86,9 +88,9 @@ fn build_ra_expr(pair: Pair) -> Result> { #[cfg(test)] mod tests { + use super::*; use crate::parser::{CozoParser, Rule}; use pest::Parser; - use super::*; #[test] fn parse_ra() -> Result<()> { @@ -96,7 +98,13 @@ mod tests { Values([{x: 1}]) //.Insert(f:Friend) "#; - build_ra_expr(CozoParser::parse(Rule::ra_expr_all, s).unwrap().into_iter().next().unwrap())?; + build_ra_expr( + CozoParser::parse(Rule::ra_expr_all, s) + .unwrap() + .into_iter() + .next() + .unwrap(), + )?; // let s = r#" // From(f:Person-[:HasJob]->j:Job, @@ -106,4 +114,4 @@ mod tests { // build_ra_expr(CozoParser::parse(Rule::ra_expr_all, s).unwrap().into_iter().next().unwrap()); Ok(()) } -} \ No newline at end of file +} diff --git a/src/data.rs b/src/data.rs index 4acb7dd5..4a29d8b2 100644 --- a/src/data.rs +++ b/src/data.rs @@ -1,8 +1,8 @@ pub(crate) mod eval; pub(crate) mod expr; -pub(crate) mod parser; pub(crate) mod key_order; pub(crate) mod op; +pub(crate) mod parser; pub(crate) mod tuple; pub(crate) mod tuple_set; pub(crate) mod typing; diff --git a/src/data/eval.rs b/src/data/eval.rs index 815b1ad0..ce1809bb 100644 --- a/src/data/eval.rs +++ b/src/data/eval.rs @@ -1,6 +1,6 @@ -use crate::data::expr::{Expr}; -use crate::data::parser::ExprParseError; +use crate::data::expr::Expr; use crate::data::op::*; +use crate::data::parser::ExprParseError; use crate::data::tuple_set::{ColId, TableId, TupleSetIdx}; use crate::data::value::{StaticValue, Value}; use std::borrow::Cow; @@ -123,21 +123,21 @@ impl<'a> Expr<'a> { .unwrap_or(Expr::Const(Value::Null)) .partial_eval(ctx)? } - arg => { - match arg.partial_eval(ctx)? { - Expr::Const(Value::Null) => Expr::Const(Value::Null), - Expr::Const(Value::Dict(mut d)) => { - Expr::Const(d.remove(&f as &str).unwrap_or(Value::Null)) - } - v @ (Expr::IdxAcc(_, _) - | Expr::FieldAcc(_, _) - | Expr::TableCol(_, _) - | Expr::Apply(_, _) - | Expr::ApplyAgg(_, _, _)) => Expr::FieldAcc(f, v.into()), - Expr::Dict(mut d) => d.remove(&f as &str).unwrap_or(Expr::Const(Value::Null)), - v => return Err(EvalError::FieldAccess(f, Value::from(v).to_static())), + arg => match arg.partial_eval(ctx)? { + Expr::Const(Value::Null) => Expr::Const(Value::Null), + Expr::Const(Value::Dict(mut d)) => { + Expr::Const(d.remove(&f as &str).unwrap_or(Value::Null)) } - } + v @ (Expr::IdxAcc(_, _) + | Expr::FieldAcc(_, _) + | Expr::TableCol(_, _) + | Expr::Apply(_, _) + | Expr::ApplyAgg(_, _, _)) => Expr::FieldAcc(f, v.into()), + Expr::Dict(mut d) => { + d.remove(&f as &str).unwrap_or(Expr::Const(Value::Null)) + } + v => return Err(EvalError::FieldAccess(f, Value::from(v).to_static())), + }, } } Expr::IdxAcc(i, arg) => { @@ -150,31 +150,29 @@ impl<'a> Expr<'a> { l.swap_remove(i).partial_eval(ctx)? } } - arg => { - match arg.partial_eval(ctx)? { - Expr::Const(Value::Null) => Expr::Const(Value::Null), - Expr::Const(Value::List(mut l)) => { - if i >= l.len() { - Expr::Const(Value::Null) - } else { - Expr::Const(l.swap_remove(i)) - } + arg => match arg.partial_eval(ctx)? { + Expr::Const(Value::Null) => Expr::Const(Value::Null), + Expr::Const(Value::List(mut l)) => { + if i >= l.len() { + Expr::Const(Value::Null) + } else { + Expr::Const(l.swap_remove(i)) } - Expr::List(mut l) => { - if i >= l.len() { - Expr::Const(Value::Null) - } else { - l.swap_remove(i) - } + } + Expr::List(mut l) => { + if i >= l.len() { + Expr::Const(Value::Null) + } else { + l.swap_remove(i) } - v @ (Expr::IdxAcc(_, _) - | Expr::FieldAcc(_, _) - | Expr::TableCol(_, _) - | Expr::Apply(_, _) - | Expr::ApplyAgg(_, _, _)) => Expr::IdxAcc(i, v.into()), - v => return Err(EvalError::IndexAccess(i, Value::from(v).to_static())), } - } + v @ (Expr::IdxAcc(_, _) + | Expr::FieldAcc(_, _) + | Expr::TableCol(_, _) + | Expr::Apply(_, _) + | Expr::ApplyAgg(_, _, _)) => Expr::IdxAcc(i, v.into()), + v => return Err(EvalError::IndexAccess(i, Value::from(v).to_static())), + }, } } Expr::Apply(op, args) => { @@ -305,10 +303,7 @@ impl<'a> Expr<'a> { } arg } - _ => Expr::Apply( - op, - args.into_iter().map(|v| v.optimize_ops()).collect(), - ), + _ => Expr::Apply(op, args.into_iter().map(|v| v.optimize_ops()).collect()), }, Expr::ApplyAgg(op, a_args, args) => Expr::ApplyAgg( op, diff --git a/src/data/expr.rs b/src/data/expr.rs index 59974bfd..837df14d 100644 --- a/src/data/expr.rs +++ b/src/data/expr.rs @@ -2,15 +2,15 @@ use crate::data::op::{ AggOp, Op, OpAdd, OpAnd, OpCoalesce, OpDiv, OpEq, OpGe, OpGt, OpIsNull, OpLe, OpLt, OpMinus, OpMod, OpMul, OpNe, OpNot, OpNotNull, OpOr, OpPow, OpStrCat, OpSub, UnresolvedOp, }; +use crate::data::parser::ExprParseError; use crate::data::tuple_set::{ColId, TableId, TupleSetIdx}; use crate::data::value::{StaticValue, Value}; +use crate::parser::{CozoParser, Rule}; +use pest::Parser; use std::collections::BTreeMap; use std::fmt::{Debug, Formatter}; use std::result; use std::sync::Arc; -use crate::parser::{CozoParser, Rule}; -use pest::Parser; -use crate::data::parser::ExprParseError; #[derive(thiserror::Error, Debug)] pub(crate) enum ExprError { @@ -27,7 +27,7 @@ pub(crate) enum ExprError { Parse(String), #[error(transparent)] - ParseInner(#[from] ExprParseError) + ParseInner(#[from] ExprParseError), } type Result = result::Result; @@ -78,8 +78,9 @@ impl<'a> Expr<'a> { Expr::Variable(v) => Expr::Variable(v), Expr::TableCol(tid, cid) => Expr::TableCol(tid, cid), Expr::TupleSetIdx(idx) => Expr::TupleSetIdx(idx), - Expr::Apply(op, args) => Expr::Apply(op, - args.into_iter().map(|v| v.to_static()).collect()), + Expr::Apply(op, args) => { + Expr::Apply(op, args.into_iter().map(|v| v.to_static()).collect()) + } Expr::ApplyAgg(op, a_args, args) => Expr::ApplyAgg( op, a_args.into_iter().map(|v| v.to_static()).collect(), @@ -91,8 +92,11 @@ impl<'a> Expr<'a> { let (a, b, c) = *args; Expr::IfExpr((a.to_static(), b.to_static(), c.to_static()).into()) } - Expr::SwitchExpr(args) => Expr::SwitchExpr(args.into_iter().map(|(a, b)| - (a.to_static(), b.to_static())).collect()), + Expr::SwitchExpr(args) => Expr::SwitchExpr( + args.into_iter() + .map(|(a, b)| (a.to_static(), b.to_static())) + .collect(), + ), Expr::Add(args) => { let (a, b) = *args; Expr::Add((a.to_static(), b.to_static()).into()) @@ -422,7 +426,7 @@ fn build_value_from_binop<'a>(name: &str, (left, right): (Expr<'a>, Expr<'a>)) - Value::from(name.to_string()), Value::from(vec![Value::from(left), Value::from(right)]), ] - .into(), + .into(), ) } @@ -433,7 +437,7 @@ fn build_value_from_uop<'a>(name: &str, arg: Expr<'a>) -> Value<'a> { Value::from(name.to_string()), Value::from(vec![Value::from(arg)]), ] - .into(), + .into(), ) } @@ -461,7 +465,7 @@ impl<'a> From> for Value<'a> { cid.is_key.into(), Value::from(cid.id as i64), ] - .into(), + .into(), ), Expr::TupleSetIdx(sid) => build_tagged_value( "TupleSetIdx", @@ -470,7 +474,7 @@ impl<'a> From> for Value<'a> { Value::from(sid.t_set as i64), Value::from(sid.col_idx as i64), ] - .into(), + .into(), ), Expr::Add(arg) => build_value_from_binop(OpAdd.name(), *arg), Expr::Sub(arg) => build_value_from_binop(OpSub.name(), *arg), @@ -498,7 +502,7 @@ impl<'a> From> for Value<'a> { Value::from(op.name().to_string()), args.into_iter().map(Value::from).collect::>().into(), ] - .into(), + .into(), ), Expr::IfExpr(_) => { todo!() @@ -517,7 +521,7 @@ impl<'a> From> for Value<'a> { .into(), args.into_iter().map(Value::from).collect::>().into(), ] - .into(), + .into(), ), Expr::FieldAcc(f, v) => { build_tagged_value("FieldAcc", vec![f.into(), Value::from(*v)].into()) @@ -533,8 +537,7 @@ fn build_tagged_value<'a>(tag: &'static str, val: Value<'a>) -> Value<'a> { Value::Dict(BTreeMap::from([(tag.into(), val)])) } - -impl <'a> TryFrom<&'a str> for Expr<'a> { +impl<'a> TryFrom<&'a str> for Expr<'a> { type Error = ExprError; fn try_from(value: &'a str) -> result::Result { @@ -544,4 +547,4 @@ impl <'a> TryFrom<&'a str> for Expr<'a> { .ok_or_else(|| ExprError::Parse(value.to_string()))?; Ok(Expr::try_from(pair)?) } -} \ No newline at end of file +} diff --git a/src/data/op.rs b/src/data/op.rs index 61e0ffe9..589d844f 100644 --- a/src/data/op.rs +++ b/src/data/op.rs @@ -3,21 +3,21 @@ mod boolean; mod combine; mod comparison; mod control; +mod sequence; mod text; mod uuid; -mod sequence; use crate::data::eval::EvalError; -use crate::data::value::{Value}; +use crate::data::value::Value; use std::result; +use crate::data::expr::Expr; pub(crate) use arithmetic::*; pub(crate) use boolean::*; pub(crate) use combine::*; pub(crate) use comparison::*; pub(crate) use control::*; pub(crate) use text::*; -use crate::data::expr::Expr; type Result = result::Result; @@ -82,4 +82,4 @@ impl AggOp for UnresolvedOp { pub(crate) fn extract_two_args<'a>(args: Vec>) -> (Value<'a>, Value<'a>) { let mut args = args.into_iter(); (args.next().unwrap(), args.next().unwrap()) -} \ No newline at end of file +} diff --git a/src/data/op/arithmetic.rs b/src/data/op/arithmetic.rs index 7b3d1f95..9fe0d8e9 100644 --- a/src/data/op/arithmetic.rs +++ b/src/data/op/arithmetic.rs @@ -1,6 +1,6 @@ use crate::data::eval::EvalError; use crate::data::op::{extract_two_args, Op}; -use crate::data::value::{Value}; +use crate::data::value::Value; use std::result; type Result = result::Result; @@ -8,7 +8,11 @@ type Result = result::Result; pub(crate) struct OpAdd; impl OpAdd { - pub(crate) fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result> { + pub(crate) fn eval_two_non_null<'a>( + &self, + left: Value<'a>, + right: Value<'a>, + ) -> Result> { let res: Value = match (left, right) { (Value::Int(l), Value::Int(r)) => (l + r).into(), (Value::Float(l), Value::Int(r)) => (l + (r as f64)).into(), @@ -52,7 +56,11 @@ impl Op for OpAdd { pub(crate) struct OpSub; impl OpSub { - pub(crate) fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result> { + pub(crate) fn eval_two_non_null<'a>( + &self, + left: Value<'a>, + right: Value<'a>, + ) -> Result> { let res: Value = match (left, right) { (Value::Int(l), Value::Int(r)) => (l - r).into(), (Value::Float(l), Value::Int(r)) => (l - (r as f64)).into(), @@ -96,7 +104,11 @@ impl Op for OpSub { pub(crate) struct OpMul; impl OpMul { - pub(crate) fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result> { + pub(crate) fn eval_two_non_null<'a>( + &self, + left: Value<'a>, + right: Value<'a>, + ) -> Result> { let res: Value = match (left, right) { (Value::Int(l), Value::Int(r)) => (l * r).into(), (Value::Float(l), Value::Int(r)) => (l * (r as f64)).into(), @@ -141,7 +153,11 @@ impl Op for OpMul { pub(crate) struct OpDiv; impl OpDiv { - pub(crate) fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result> { + pub(crate) fn eval_two_non_null<'a>( + &self, + left: Value<'a>, + right: Value<'a>, + ) -> Result> { let res: Value = match (left, right) { (Value::Int(l), Value::Int(r)) => (l as f64 / r as f64).into(), (Value::Float(l), Value::Int(r)) => (l / (r as f64)).into(), @@ -186,7 +202,11 @@ impl Op for OpDiv { pub(crate) struct OpMod; impl OpMod { - pub(crate) fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result> { + pub(crate) fn eval_two_non_null<'a>( + &self, + left: Value<'a>, + right: Value<'a>, + ) -> Result> { let res: Value = match (left, right) { (Value::Int(l), Value::Int(r)) => (l % r).into(), (l, r) => { @@ -228,7 +248,11 @@ impl Op for OpMod { pub(crate) struct OpPow; impl OpPow { - pub(crate) fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result> { + pub(crate) fn eval_two_non_null<'a>( + &self, + left: Value<'a>, + right: Value<'a>, + ) -> Result> { let res: Value = match (left, right) { (Value::Int(l), Value::Int(r)) => ((l as f64).powf(r as f64)).into(), (Value::Float(l), Value::Int(r)) => ((l.into_inner()).powf(r as f64)).into(), diff --git a/src/data/op/boolean.rs b/src/data/op/boolean.rs index 17b9aa70..75201e6b 100644 --- a/src/data/op/boolean.rs +++ b/src/data/op/boolean.rs @@ -1,7 +1,7 @@ use crate::data::eval::{EvalError, PartialEvalContext, RowEvalContext}; use crate::data::expr::Expr; use crate::data::op::Op; -use crate::data::value::{Value}; +use crate::data::value::Value; use std::result; use std::sync::Arc; @@ -61,7 +61,6 @@ impl Op for OpNotNull { fn eval<'a>(&self, args: Vec>) -> Result> { self.eval_one(args.into_iter().next().unwrap()) } - } pub(crate) struct OpOr; diff --git a/src/data/op/combine.rs b/src/data/op/combine.rs index a6e5e1ad..56bee45b 100644 --- a/src/data/op/combine.rs +++ b/src/data/op/combine.rs @@ -1,6 +1,6 @@ -use crate::data::eval::{EvalError}; +use crate::data::eval::EvalError; use crate::data::op::Op; -use crate::data::value::{Value}; +use crate::data::value::Value; use std::collections::BTreeMap; use std::result; diff --git a/src/data/op/comparison.rs b/src/data/op/comparison.rs index f7607870..5d1a04b8 100644 --- a/src/data/op/comparison.rs +++ b/src/data/op/comparison.rs @@ -8,7 +8,11 @@ type Result = result::Result; pub(crate) struct OpEq; impl OpEq { - pub(crate) fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result> { + pub(crate) fn eval_two_non_null<'a>( + &self, + left: Value<'a>, + right: Value<'a>, + ) -> Result> { Ok((left == right).into()) } } @@ -41,7 +45,11 @@ impl Op for OpEq { pub(crate) struct OpNe; impl OpNe { - pub(crate) fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result> { + pub(crate) fn eval_two_non_null<'a>( + &self, + left: Value<'a>, + right: Value<'a>, + ) -> Result> { Ok((left != right).into()) } } @@ -74,7 +82,11 @@ impl Op for OpNe { pub(crate) struct OpGt; impl OpGt { - pub(crate) fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result> { + pub(crate) fn eval_two_non_null<'a>( + &self, + left: Value<'a>, + right: Value<'a>, + ) -> Result> { let res: Value = match (left, right) { (Value::Int(l), Value::Int(r)) => (l > r).into(), (Value::Float(l), Value::Int(r)) => (l > (r as f64).into()).into(), @@ -119,7 +131,11 @@ impl Op for OpGt { pub(crate) struct OpGe; impl OpGe { - pub(crate) fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result> { + pub(crate) fn eval_two_non_null<'a>( + &self, + left: Value<'a>, + right: Value<'a>, + ) -> Result> { let res: Value = match (left, right) { (Value::Int(l), Value::Int(r)) => (l >= r).into(), (Value::Float(l), Value::Int(r)) => (l >= (r as f64).into()).into(), @@ -164,7 +180,11 @@ impl Op for OpGe { pub(crate) struct OpLt; impl OpLt { - pub(crate) fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result> { + pub(crate) fn eval_two_non_null<'a>( + &self, + left: Value<'a>, + right: Value<'a>, + ) -> Result> { let res: Value = match (left, right) { (Value::Int(l), Value::Int(r)) => (l < r).into(), (Value::Float(l), Value::Int(r)) => (l < (r as f64).into()).into(), @@ -209,7 +229,11 @@ impl Op for OpLt { pub(crate) struct OpLe; impl OpLe { - pub(crate) fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result> { + pub(crate) fn eval_two_non_null<'a>( + &self, + left: Value<'a>, + right: Value<'a>, + ) -> Result> { let res: Value = match (left, right) { (Value::Int(l), Value::Int(r)) => (l <= r).into(), (Value::Float(l), Value::Int(r)) => (l <= (r as f64).into()).into(), diff --git a/src/data/op/sequence.rs b/src/data/op/sequence.rs index 377c7b07..6912a10d 100644 --- a/src/data/op/sequence.rs +++ b/src/data/op/sequence.rs @@ -25,4 +25,4 @@ impl Op for SeqNext { fn eval<'a>(&self, args: Vec>) -> crate::data::op::Result> { todo!() } -} \ No newline at end of file +} diff --git a/src/data/op/text.rs b/src/data/op/text.rs index 74510543..b8f8335b 100644 --- a/src/data/op/text.rs +++ b/src/data/op/text.rs @@ -8,7 +8,11 @@ type Result = result::Result; pub(crate) struct OpStrCat; impl OpStrCat { - pub(crate) fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result> { + pub(crate) fn eval_two_non_null<'a>( + &self, + left: Value<'a>, + right: Value<'a>, + ) -> Result> { match (left, right) { (Value::Text(l), Value::Text(r)) => { let mut l = l.into_owned(); diff --git a/src/data/op/uuid.rs b/src/data/op/uuid.rs index 09e24f2f..38d8bec0 100644 --- a/src/data/op/uuid.rs +++ b/src/data/op/uuid.rs @@ -3,7 +3,7 @@ use crate::data::value::Value; pub(crate) struct OpGenUuidV1; -const NAME_OP_GEN_UUID_V1:&str = "gen_uuid_v1"; +const NAME_OP_GEN_UUID_V1: &str = "gen_uuid_v1"; impl Op for OpGenUuidV1 { fn arity(&self) -> Option { @@ -25,4 +25,4 @@ impl Op for OpGenUuidV1 { fn eval<'a>(&self, args: Vec>) -> crate::data::op::Result> { todo!() } -} \ No newline at end of file +} diff --git a/src/data/parser.rs b/src/data/parser.rs index 2b76dc24..5eba1873 100644 --- a/src/data/parser.rs +++ b/src/data/parser.rs @@ -149,7 +149,8 @@ fn build_expr_primary(pair: Pair) -> Result { } Rule::call => { let mut pairs = p.into_inner(); - let op: Arc = get_method(pairs.next().unwrap().as_str()); + let op: Arc = + get_method(pairs.next().unwrap().as_str()); let mut args = vec![head]; args.extend(pairs.map(Expr::try_from).collect::>>()?); head = Expr::Apply(op, args); @@ -293,7 +294,7 @@ fn get_method(name: &str) -> Arc { NAME_OP_NOT_NULL => Arc::new(OpNotNull), NAME_OP_CONCAT => Arc::new(OpConcat), NAME_OP_MERGE => Arc::new(OpMerge), - method_name => Arc::new(UnresolvedOp(method_name.to_string())) + method_name => Arc::new(UnresolvedOp(method_name.to_string())), } } diff --git a/src/data/tuple.rs b/src/data/tuple.rs index 99cc615a..9ab0e4f1 100644 --- a/src/data/tuple.rs +++ b/src/data/tuple.rs @@ -99,7 +99,7 @@ pub(crate) const DATAKIND_TYPE: u32 = 12; pub(crate) const DATAKIND_EMPTY: u32 = u32::MAX; #[repr(u32)] -#[derive(Ord, PartialOrd, Eq, PartialEq, Debug, Clone)] +#[derive(Ord, PartialOrd, Eq, PartialEq, Debug, Clone, Copy)] pub enum DataKind { Data = DATAKIND_DATA, Node = DATAKIND_NODE, @@ -143,8 +143,8 @@ impl From for u32 { #[derive(Clone)] pub struct Tuple - where - T: AsRef<[u8]>, +where + T: AsRef<[u8]>, { pub(crate) data: T, idx_cache: RefCell>, @@ -155,8 +155,8 @@ unsafe impl> Send for Tuple {} unsafe impl> Sync for Tuple {} impl From for Tuple - where - T: AsRef<[u8]>, +where + T: AsRef<[u8]>, { fn from(data: T) -> Self { Tuple::new(data) @@ -164,8 +164,8 @@ impl From for Tuple } impl Tuple - where - T: AsRef<[u8]>, +where + T: AsRef<[u8]>, { pub(crate) fn clear_cache(&self) { self.idx_cache.borrow_mut().clear() @@ -173,8 +173,8 @@ impl Tuple } impl AsRef<[u8]> for Tuple - where - T: AsRef<[u8]>, +where + T: AsRef<[u8]>, { fn as_ref(&self) -> &[u8] { self.data.as_ref() @@ -627,8 +627,10 @@ impl OwnTuple { cache.push(self.data.len()); } #[inline] - pub(crate) fn push_values_as_list<'a, It: IntoIterator, I: Borrow> + 'a> - (&mut self, l: It) { + pub(crate) fn push_values_as_list<'a, It: IntoIterator, I: Borrow> + 'a>( + &mut self, + l: It, + ) { self.push_tag(StorageTag::List); let start_pos = self.data.len(); let start_len = self.idx_cache.borrow().len(); @@ -644,9 +646,14 @@ impl OwnTuple { cache.push(self.data.len()); } #[inline] - pub(crate) fn push_values_as_dict<'a, I: IntoIterator)>, - T: AsRef + 'a> - (&mut self, d: I) { + pub(crate) fn push_values_as_dict< + 'a, + I: IntoIterator)>, + T: AsRef + 'a, + >( + &mut self, + d: I, + ) { self.push_tag(StorageTag::Dict); let start_pos = self.data.len(); let start_len = self.idx_cache.borrow().len(); @@ -731,7 +738,7 @@ impl OwnTuple { impl<'a> Extend> for OwnTuple { #[inline] - fn extend>>(&mut self, iter: T) { + fn extend>>(&mut self, iter: T) { for v in iter { self.push_value(&v) } @@ -754,9 +761,9 @@ impl> Hash for Tuple { impl> Eq for Tuple {} impl<'a, P, T> From<(P, T)> for OwnTuple - where - T: IntoIterator>, - P: Into, +where + T: IntoIterator>, + P: Into, { fn from((prefix, it): (P, T)) -> Self { let mut ret = OwnTuple::with_prefix(prefix.into()); diff --git a/src/data/tuple_set.rs b/src/data/tuple_set.rs index 95c45366..7acaa924 100644 --- a/src/data/tuple_set.rs +++ b/src/data/tuple_set.rs @@ -132,16 +132,16 @@ impl TupleSet { self.vals.extend(o.vals); } pub(crate) fn extend_keys(&mut self, keys: I) - where - I: IntoIterator, - ReifiedTuple: From, + where + I: IntoIterator, + ReifiedTuple: From, { self.keys.extend(keys.into_iter().map(ReifiedTuple::from)); } pub(crate) fn extend_vals(&mut self, keys: I) - where - I: IntoIterator, - ReifiedTuple: From, + where + I: IntoIterator, + ReifiedTuple: From, { self.vals.extend(keys.into_iter().map(ReifiedTuple::from)); } @@ -185,11 +185,11 @@ impl TupleSet { } impl From<(I1, I2)> for TupleSet - where - I1: IntoIterator, - ReifiedTuple: From, - I2: IntoIterator, - ReifiedTuple: From, +where + I1: IntoIterator, + ReifiedTuple: From, + I2: IntoIterator, + ReifiedTuple: From, { fn from((keys, vals): (I1, I2)) -> Self { TupleSet { diff --git a/src/data/value.rs b/src/data/value.rs index c3f8ce5a..444903b4 100644 --- a/src/data/value.rs +++ b/src/data/value.rs @@ -30,37 +30,37 @@ impl<'a> Value<'a> { pub(crate) fn get_bool(&self) -> Option { match self { Value::Bool(b) => Some(*b), - _ => None + _ => None, } } pub(crate) fn get_int(&self) -> Option { match self { Value::Int(b) => Some(*b), - _ => None + _ => None, } } pub(crate) fn get_float(&self) -> Option { match self { Value::Float(b) => Some(b.into_inner()), - _ => None + _ => None, } } pub(crate) fn get_str(&self) -> Option<&str> { match self { Value::Text(b) => Some(b.as_ref()), - _ => None + _ => None, } } pub(crate) fn get_slice(&self) -> Option<&[Value<'a>]> { match self { Value::List(l) => Some(l), - _ => None + _ => None, } } pub(crate) fn get_map(&self) -> Option<&BTreeMap, Value>> { match self { Value::Dict(m) => Some(m), - _ => None + _ => None, } } } diff --git a/src/ddl/parser.rs b/src/ddl/parser.rs index acd1f38f..ca4aaa87 100644 --- a/src/ddl/parser.rs +++ b/src/ddl/parser.rs @@ -1,10 +1,10 @@ -use std::result; use crate::data::expr::{Expr, ExprError, StaticExpr}; use crate::data::parser::ExprParseError; use crate::data::typing::{Typing, TypingError}; use crate::data::value::{StaticValue, Value}; -use crate::parser::{Pair, Rule}; use crate::parser::text_identifier::{build_name_in_def, TextParseError}; +use crate::parser::{Pair, Rule}; +use std::result; #[derive(thiserror::Error, Debug)] pub(crate) enum DdlParseError { @@ -52,15 +52,28 @@ impl<'a> TryFrom> for ColSchema { fn try_from(value: Value<'a>) -> Result { let mk_err = || DdlParseError::ColSchemaDeser(value.clone().to_static()); let fields = value.get_slice().ok_or_else(mk_err)?; - let name = fields.get(0).ok_or_else(mk_err)?.get_str().ok_or_else(mk_err)?.to_string(); - let typing = fields.get(1).ok_or_else(mk_err)?.get_str().ok_or_else(mk_err)?; + let name = fields + .get(0) + .ok_or_else(mk_err)? + .get_str() + .ok_or_else(mk_err)? + .to_string(); + let typing = fields + .get(1) + .ok_or_else(mk_err)? + .get_str() + .ok_or_else(mk_err)?; let typing = Typing::try_from(typing)?; - let default = fields.get(1).ok_or_else(mk_err)?.get_str().ok_or_else(mk_err)?; + let default = fields + .get(1) + .ok_or_else(mk_err)? + .get_str() + .ok_or_else(mk_err)?; let default = Expr::try_from(default)?.to_static(); Ok(Self { name, typing, - default + default, }) } } @@ -120,7 +133,7 @@ impl<'a> TryFrom> for DdlSchema { Rule::assoc_def => DdlSchema::Assoc(pair.try_into()?), Rule::seq_def => DdlSchema::Sequence(pair.try_into()?), Rule::index_def => DdlSchema::Index(pair.try_into()?), - _ => todo!() + _ => todo!(), }) } } @@ -133,11 +146,7 @@ impl<'a> TryFrom> for NodeSchema { let name = build_name_in_def(pairs.next().unwrap(), true)?; let cols_pair = pairs.next().unwrap(); let (keys, vals) = parse_cols(cols_pair)?; - Ok(Self { - name, - keys, - vals, - }) + Ok(Self { name, keys, vals }) } } @@ -150,7 +159,7 @@ impl<'a> TryFrom> for EdgeSchema { let dst_name = build_name_in_def(pairs.next().unwrap(), true)?; let (keys, vals) = match pairs.next() { Some(pair) => parse_cols(pair)?, - None => (vec![], vec![]) + None => (vec![], vec![]), }; Ok(EdgeSchema { name, @@ -195,7 +204,7 @@ impl<'a> TryFrom> for IndexSchema { for pair in pairs { match pair.as_rule() { Rule::name_in_def => associate_names.push(build_name_in_def(pair, false)?), - _ => indices.push(Expr::try_from(pair)?.to_static()) + _ => indices.push(Expr::try_from(pair)?.to_static()), } } if indices.is_empty() { @@ -214,9 +223,7 @@ impl<'a> TryFrom> for SequenceSchema { type Error = DdlParseError; fn try_from(pair: Pair) -> Result { let name = build_name_in_def(pair.into_inner().next().unwrap(), true)?; - Ok(SequenceSchema { - name - }) + Ok(SequenceSchema { name }) } } @@ -226,7 +233,7 @@ fn parse_cols(pair: Pair) -> Result<(Vec, Vec)> { for pair in pair.into_inner() { match parse_col_entry(pair)? { (true, res) => keys.push(res), - (false, res) => vals.push(res) + (false, res) => vals.push(res), } } Ok((keys, vals)) @@ -240,11 +247,14 @@ fn parse_col_entry(pair: Pair) -> Result<(bool, ColSchema)> { None => Expr::Const(Value::Null), Some(pair) => Expr::try_from(pair)?.to_static(), }; - Ok((is_key, ColSchema { - name, - typing, - default, - })) + Ok(( + is_key, + ColSchema { + name, + typing, + default, + }, + )) } fn parse_col_name(pair: Pair) -> Result<(bool, String)> { @@ -255,7 +265,7 @@ fn parse_col_name(pair: Pair) -> Result<(bool, String)> { nxt = pairs.next().unwrap(); true } - _ => false + _ => false, }; let name = build_name_in_def(nxt, true)?; Ok((is_key, name)) @@ -263,9 +273,9 @@ fn parse_col_name(pair: Pair) -> Result<(bool, String)> { #[cfg(test)] mod tests { + use super::*; use crate::parser::CozoParser; use pest::Parser; - use super::*; #[test] fn parse_ddl() -> Result<()> { @@ -277,13 +287,19 @@ mod tests { max_salary: Float } "#; - let p = CozoParser::parse(Rule::definition_all, s).unwrap().next().unwrap(); + let p = CozoParser::parse(Rule::definition_all, s) + .unwrap() + .next() + .unwrap(); dbg!(DdlSchema::try_from(p)?); let s = r#" edge (Department)-[InLocation]->(Location) "#; - let p = CozoParser::parse(Rule::definition_all, s).unwrap().next().unwrap(); + let p = CozoParser::parse(Rule::definition_all, s) + .unwrap() + .next() + .unwrap(); dbg!(DdlSchema::try_from(p)?); let s = r#" @@ -291,7 +307,10 @@ mod tests { relationship: Text } "#; - let p = CozoParser::parse(Rule::definition_all, s).unwrap().next().unwrap(); + let p = CozoParser::parse(Rule::definition_all, s) + .unwrap() + .next() + .unwrap(); dbg!(DdlSchema::try_from(p)?); let s = r#" @@ -299,21 +318,30 @@ mod tests { balance: Float = 0 } "#; - let p = CozoParser::parse(Rule::definition_all, s).unwrap().next().unwrap(); + let p = CozoParser::parse(Rule::definition_all, s) + .unwrap() + .next() + .unwrap(); dbg!(DdlSchema::try_from(p)?); let s = r#" sequence PersonId; "#; - let p = CozoParser::parse(Rule::definition_all, s).unwrap().next().unwrap(); + let p = CozoParser::parse(Rule::definition_all, s) + .unwrap() + .next() + .unwrap(); dbg!(DdlSchema::try_from(p)?); let s = r#" index bankaccountidx: Person + BankAccount [id, x, y, z] "#; - let p = CozoParser::parse(Rule::definition_all, s).unwrap().next().unwrap(); + let p = CozoParser::parse(Rule::definition_all, s) + .unwrap() + .next() + .unwrap(); dbg!(DdlSchema::try_from(p)?); Ok(()) } -} \ No newline at end of file +} diff --git a/src/ddl/reify.rs b/src/ddl/reify.rs index ae9fcf39..4f85080c 100644 --- a/src/ddl/reify.rs +++ b/src/ddl/reify.rs @@ -1,16 +1,22 @@ -use std::collections::{BTreeSet}; -use std::result; -use cozorocks::TransactionPtr; use crate::data::eval::{EvalError, PartialEvalContext}; use crate::data::expr::{Expr, ExprError, StaticExpr}; -use crate::data::tuple::{DataKind, DATAKIND_ASSOC, DATAKIND_EDGE, DATAKIND_INDEX, DATAKIND_NODE, DATAKIND_SEQUENCE, OwnTuple, Tuple, TupleError}; +use crate::data::tuple::{ + DataKind, OwnTuple, Tuple, TupleError, DATAKIND_ASSOC, DATAKIND_EDGE, DATAKIND_INDEX, + DATAKIND_NODE, DATAKIND_SEQUENCE, +}; use crate::data::tuple_set::{TableId, TupleSetError, TupleSetIdx}; use crate::data::value::{StaticValue, Value}; -use crate::ddl::parser::{AssocSchema, ColSchema, DdlParseError, DdlSchema, EdgeSchema, IndexSchema, NodeSchema, SequenceSchema}; +use crate::ddl::parser::{ + AssocSchema, ColSchema, DdlParseError, DdlSchema, EdgeSchema, IndexSchema, NodeSchema, + SequenceSchema, +}; use crate::runtime::instance::DbInstanceError; use crate::runtime::instance::DbInstanceError::NameConflict; use crate::runtime::options::default_read_options; -use crate::runtime::session::{Session, SessionDefinable}; +use crate::runtime::session::{Session, SessionDefinable, SessionStackFrame, TableAssocMap}; +use cozorocks::TransactionPtr; +use std::collections::BTreeSet; +use std::result; #[derive(thiserror::Error, Debug)] pub(crate) enum DdlReifyError { @@ -32,11 +38,14 @@ pub(crate) enum DdlReifyError { #[error("Cannot find table {0:?}")] TableNotFound(TableId), + #[error("Cannot find table {0}")] + TableNameNotFound(String), + #[error("Data corruption {0:?}")] Corruption(OwnTuple), #[error("Wrong table kind for {0:?}")] - WrongTableKind(TableId), + WrongDataKind(TableId), #[error(transparent)] Tuple(#[from] TupleError), @@ -45,20 +54,11 @@ pub(crate) enum DdlReifyError { TupleSet(#[from] TupleSetError), #[error(transparent)] - Expr(#[from] ExprError) + Expr(#[from] ExprError), } type Result = result::Result; -#[derive(Debug, Copy, Clone)] -pub(crate) enum TableKind { - Node, - Edge, - Assoc, - Index, - Sequence, -} - #[derive(Debug, Clone)] pub(crate) enum TableInfo { Node(NodeInfo), @@ -69,13 +69,22 @@ pub(crate) enum TableInfo { } impl TableInfo { + pub(crate) fn data_kind(&self) -> DataKind { + match self { + TableInfo::Node(_) => DataKind::Node, + TableInfo::Edge(_) => DataKind::Edge, + TableInfo::Assoc(_) => DataKind::Assoc, + TableInfo::Index(_) => DataKind::Index, + TableInfo::Sequence(_) => DataKind::Index, + } + } pub(crate) fn table_id(&self) -> TableId { match self { TableInfo::Node(n) => n.tid, TableInfo::Edge(e) => e.tid, TableInfo::Assoc(a) => a.tid, TableInfo::Index(i) => i.tid, - TableInfo::Sequence(s) => s.tid + TableInfo::Sequence(s) => s.tid, } } pub(crate) fn table_name(&self) -> &str { @@ -96,19 +105,26 @@ impl> TryFrom> for TableInfo { match tuple.get_prefix() { DATAKIND_NODE => { let mut it = tuple.iter(); - let name = it.next().ok_or_else(gen_err)??.get_str().ok_or_else(gen_err)?.to_string(); + let name = it + .next() + .ok_or_else(gen_err)?? + .get_str() + .ok_or_else(gen_err)? + .to_string(); let tid = it.next().ok_or_else(gen_err)??; let tid = TableId::try_from(&tid)?; let keys = it.next().ok_or_else(gen_err)??; let keys = keys.get_slice().ok_or_else(gen_err)?; - let keys = keys.iter().map(|v| - ColSchema::try_from(v.clone()).map_err(DdlReifyError::from) - ).collect::>>()?; + let keys = keys + .iter() + .map(|v| ColSchema::try_from(v.clone()).map_err(DdlReifyError::from)) + .collect::>>()?; let vals = it.next().ok_or_else(gen_err)??; let vals = vals.get_slice().ok_or_else(gen_err)?; - let vals = vals.iter().map(|v| - ColSchema::try_from(v.clone()).map_err(DdlReifyError::from) - ).collect::>>()?; + let vals = vals + .iter() + .map(|v| ColSchema::try_from(v.clone()).map_err(DdlReifyError::from)) + .collect::>>()?; Ok(TableInfo::Node(NodeInfo { name, tid, @@ -118,19 +134,26 @@ impl> TryFrom> for TableInfo { } DATAKIND_EDGE => { let mut it = tuple.iter(); - let name = it.next().ok_or_else(gen_err)??.get_str().ok_or_else(gen_err)?.to_string(); + let name = it + .next() + .ok_or_else(gen_err)?? + .get_str() + .ok_or_else(gen_err)? + .to_string(); let tid = it.next().ok_or_else(gen_err)??; let tid = TableId::try_from(&tid)?; let keys = it.next().ok_or_else(gen_err)??; let keys = keys.get_slice().ok_or_else(gen_err)?; - let keys = keys.iter().map(|v| - ColSchema::try_from(v.clone()).map_err(DdlReifyError::from) - ).collect::>>()?; + let keys = keys + .iter() + .map(|v| ColSchema::try_from(v.clone()).map_err(DdlReifyError::from)) + .collect::>>()?; let vals = it.next().ok_or_else(gen_err)??; let vals = vals.get_slice().ok_or_else(gen_err)?; - let vals = vals.iter().map(|v| - ColSchema::try_from(v.clone()).map_err(DdlReifyError::from) - ).collect::>>()?; + let vals = vals + .iter() + .map(|v| ColSchema::try_from(v.clone()).map_err(DdlReifyError::from)) + .collect::>>()?; let src_id = it.next().ok_or_else(gen_err)??; let src_id = TableId::try_from(&src_id)?; let dst_id = it.next().ok_or_else(gen_err)??; @@ -147,35 +170,52 @@ impl> TryFrom> for TableInfo { } DATAKIND_INDEX => { let mut it = tuple.iter(); - let name = it.next().ok_or_else(gen_err)??.get_str().ok_or_else(gen_err)?.to_string(); + let name = it + .next() + .ok_or_else(gen_err)?? + .get_str() + .ok_or_else(gen_err)? + .to_string(); let tid = it.next().ok_or_else(gen_err)??; let tid = TableId::try_from(&tid)?; let indices = it.next().ok_or_else(gen_err)??; let indices = indices.get_slice().ok_or_else(gen_err)?; - let indices = indices.iter().map(|v| IndexCol::try_from(v.clone())).collect::>>()?; + let indices = indices + .iter() + .map(|v| IndexCol::try_from(v.clone())) + .collect::>>()?; let src_id = it.next().ok_or_else(gen_err)??; let src_id = TableId::try_from(&src_id)?; let assoc_ids = it.next().ok_or_else(gen_err)??; let assoc_ids = assoc_ids.get_slice().ok_or_else(gen_err)?; - let assoc_ids = assoc_ids.iter().map(TableId::try_from).collect::, _>>()?; + let assoc_ids = assoc_ids + .iter() + .map(TableId::try_from) + .collect::, _>>()?; Ok(TableInfo::Index(IndexInfo { name, tid, src_id, assoc_ids, - index: indices + index: indices, })) } DATAKIND_ASSOC => { let mut it = tuple.iter(); - let name = it.next().ok_or_else(gen_err)??.get_str().ok_or_else(gen_err)?.to_string(); + let name = it + .next() + .ok_or_else(gen_err)?? + .get_str() + .ok_or_else(gen_err)? + .to_string(); let tid = it.next().ok_or_else(gen_err)??; let tid = TableId::try_from(&tid)?; let vals = it.next().ok_or_else(gen_err)??; let vals = vals.get_slice().ok_or_else(gen_err)?; - let vals = vals.iter().map(|v| - ColSchema::try_from(v.clone()).map_err(DdlReifyError::from) - ).collect::>>()?; + let vals = vals + .iter() + .map(|v| ColSchema::try_from(v.clone()).map_err(DdlReifyError::from)) + .collect::>>()?; let src_id = it.next().ok_or_else(gen_err)??; let src_id = TableId::try_from(&src_id)?; @@ -188,15 +228,17 @@ impl> TryFrom> for TableInfo { } DATAKIND_SEQUENCE => { let mut it = tuple.iter(); - let name = it.next().ok_or_else(gen_err)??.get_str().ok_or_else(gen_err)?.to_string(); + let name = it + .next() + .ok_or_else(gen_err)?? + .get_str() + .ok_or_else(gen_err)? + .to_string(); let tid = it.next().ok_or_else(gen_err)??; let tid = TableId::try_from(&tid)?; - Ok(TableInfo::Sequence(SequenceInfo { - name, - tid, - })) + Ok(TableInfo::Sequence(SequenceInfo { name, tid })) } - _ => Err(gen_err()) + _ => Err(gen_err()), } } } @@ -204,7 +246,12 @@ impl> TryFrom> for TableInfo { impl From<&TableInfo> for OwnTuple { fn from(ti: &TableInfo) -> Self { match ti { - TableInfo::Node(NodeInfo { name, tid, keys, vals }) => { + TableInfo::Node(NodeInfo { + name, + tid, + keys, + vals, + }) => { let mut target = OwnTuple::with_data_prefix(DataKind::Node); target.push_str(name); target.push_value(&Value::from(*tid)); @@ -214,7 +261,14 @@ impl From<&TableInfo> for OwnTuple { target.push_values_as_list(vals); target } - TableInfo::Edge(EdgeInfo { name, tid, src_id, dst_id, keys, vals, }) => { + TableInfo::Edge(EdgeInfo { + name, + tid, + src_id, + dst_id, + keys, + vals, + }) => { let mut target = OwnTuple::with_data_prefix(DataKind::Edge); target.push_str(name); target.push_value(&Value::from(*tid)); @@ -226,7 +280,12 @@ impl From<&TableInfo> for OwnTuple { target.push_value(&Value::from(*dst_id)); target } - TableInfo::Assoc(AssocInfo { name, tid, src_id, vals }) => { + TableInfo::Assoc(AssocInfo { + name, + tid, + src_id, + vals, + }) => { let mut target = OwnTuple::with_data_prefix(DataKind::Assoc); target.push_str(name); target.push_value(&Value::from(*tid)); @@ -235,7 +294,13 @@ impl From<&TableInfo> for OwnTuple { target.push_value(&Value::from(*src_id)); target } - TableInfo::Index(IndexInfo { name, tid, src_id, assoc_ids, index }) => { + TableInfo::Index(IndexInfo { + name, + tid, + src_id, + assoc_ids, + index, + }) => { let mut target = OwnTuple::with_data_prefix(DataKind::Index); target.push_str(name); target.push_value(&Value::from(*tid)); @@ -264,7 +329,6 @@ pub(crate) struct NodeInfo { pub(crate) vals: Vec, } - #[derive(Debug, Clone)] pub(crate) struct EdgeInfo { pub(crate) name: String, @@ -293,7 +357,7 @@ impl From for StaticValue { fn from(ic: IndexCol) -> Self { match ic { IndexCol::Expr(expr) => StaticValue::from(expr), - IndexCol::Col(c) => StaticValue::from(Expr::TupleSetIdx(c)) + IndexCol::Col(c) => StaticValue::from(Expr::TupleSetIdx(c)), } } } @@ -304,7 +368,7 @@ impl<'a> TryFrom> for IndexCol { fn try_from(value: Value<'a>) -> result::Result { Ok(match Expr::try_from(value)? { Expr::TupleSetIdx(tidx) => IndexCol::Col(tidx), - expr => IndexCol::Expr(expr.to_static()) + expr => IndexCol::Expr(expr.to_static()), }) } } @@ -326,41 +390,65 @@ pub(crate) struct SequenceInfo { pub(crate) trait DdlContext { fn gen_table_id(&mut self) -> Result; - fn table_id_by_name>(&self, name: &str, kind: I, for_derivation: bool) -> Result; - fn table_by_name>(&self, name: &str, kind: I, for_derivation: bool) -> Result { - let id = self.table_id_by_name(name, kind, for_derivation)?; - self.table_by_id(id) + fn table_id_by_name(&self, name: &str) -> Result; + fn table_by_name>( + &self, + name: &str, + kind: I, + ) -> Result { + let id = self.table_id_by_name(name)?; + let table = self.table_by_id(id)?; + let set = kind.into_iter().collect::>(); + if set.contains(&table.data_kind()) { + Ok(table) + } else { + Err(DdlReifyError::WrongDataKind(id)) + } } fn table_by_id(&self, tid: TableId) -> Result; fn assoc_ids_by_main_id(&self, id: TableId) -> Result>; fn assocs_by_main_id(&self, id: TableId) -> Result> { - self.assoc_ids_by_main_id(id)?.into_iter().map(|id| { - match self.table_by_id(id) { + self.assoc_ids_by_main_id(id)? + .into_iter() + .map(|id| match self.table_by_id(id) { Err(e) => Err(e), Ok(TableInfo::Assoc(a)) => Ok(a), - Ok(t) => Err(DdlReifyError::WrongTableKind(id)) - } - }).collect::>() + Ok(t) => Err(DdlReifyError::WrongDataKind(id)), + }) + .collect::>() } fn edge_ids_by_main_id(&self, id: TableId) -> Result>; fn edges_by_main_id(&self, id: TableId) -> Result> { - self.edge_ids_by_main_id(id)?.into_iter().map(|id| { - match self.table_by_id(id) { + self.edge_ids_by_main_id(id)? + .into_iter() + .map(|id| match self.table_by_id(id) { Err(e) => Err(e), Ok(TableInfo::Edge(a)) => Ok(a), - Ok(t) => Err(DdlReifyError::WrongTableKind(id)) - } - }).collect::>() + Ok(t) => Err(DdlReifyError::WrongDataKind(id)), + }) + .collect::>() + } + fn bwd_edge_ids_by_main_id(&self, id: TableId) -> Result>; + fn bwd_edges_by_main_id(&self, id: TableId) -> Result> { + self.bwd_edge_ids_by_main_id(id)? + .into_iter() + .map(|id| match self.table_by_id(id) { + Err(e) => Err(e), + Ok(TableInfo::Edge(a)) => Ok(a), + Ok(t) => Err(DdlReifyError::WrongDataKind(id)), + }) + .collect::>() } fn index_ids_by_main_id(&self, id: TableId) -> Result>; fn indices_by_main_id(&self, id: TableId) -> Result> { - self.index_ids_by_main_id(id)?.into_iter().map(|id| { - match self.table_by_id(id) { + self.index_ids_by_main_id(id)? + .into_iter() + .map(|id| match self.table_by_id(id) { Err(e) => Err(e), Ok(TableInfo::Index(a)) => Ok(a), - Ok(t) => Err(DdlReifyError::WrongTableKind(id)) - } - }).collect::>() + Ok(t) => Err(DdlReifyError::WrongDataKind(id)), + }) + .collect::>() } fn build_table(&mut self, schema: DdlSchema) -> Result<()> { match schema { @@ -368,7 +456,7 @@ pub(crate) trait DdlContext { DdlSchema::Edge(e) => self.build_edge(e)?, DdlSchema::Assoc(a) => self.build_assoc(a)?, DdlSchema::Index(i) => self.build_index(i)?, - DdlSchema::Sequence(s) => self.build_sequence(s)? + DdlSchema::Sequence(s) => self.build_sequence(s)?, }; Ok(()) } @@ -387,15 +475,19 @@ pub(crate) trait DdlContext { let info = EdgeInfo { name: schema.name, tid: self.gen_table_id()?, - src_id: self.table_id_by_name(&schema.src_name, [TableKind::Node], true)?, - dst_id: self.table_id_by_name(&schema.dst_name, [TableKind::Node], true)?, + src_id: self + .table_by_name(&schema.src_name, [DataKind::Node])? + .table_id(), + dst_id: self + .table_by_name(&schema.dst_name, [DataKind::Node])? + .table_id(), keys: eval_defaults(schema.keys)?, vals: eval_defaults(schema.vals)?, }; self.store_table(TableInfo::Edge(info)) } fn build_assoc(&mut self, schema: AssocSchema) -> Result<()> { - let src_info = self.table_by_name(&schema.src_name, [TableKind::Node, TableKind::Edge], true)?; + let src_info = self.table_by_name(&schema.src_name, [DataKind::Node, DataKind::Edge])?; let src_id = src_info.table_id(); let associates = self.assocs_by_main_id(src_id)?; let mut names_to_check: Vec<_> = associates.iter().map(|ai| &ai.vals).collect(); @@ -410,9 +502,12 @@ pub(crate) trait DdlContext { self.store_table(TableInfo::Assoc(info)) } fn build_index(&mut self, schema: IndexSchema) -> Result<()> { - let src_schema = self.table_by_name(&schema.src_name, [TableKind::Node, TableKind::Edge], true)?; + let src_schema = self.table_by_name(&schema.src_name, [DataKind::Node, DataKind::Edge])?; let associates = self.assocs_by_main_id(src_schema.table_id())?; - let assoc_vals = associates.iter().map(|v| v.vals.as_slice()).collect::>(); + let assoc_vals = associates + .iter() + .map(|v| v.vals.as_slice()) + .collect::>(); let index_exprs = match &src_schema { TableInfo::Node(node_info) => { let ctx = NodeDefEvalCtx { @@ -420,25 +515,27 @@ pub(crate) trait DdlContext { vals: &node_info.vals, assoc_vals: &assoc_vals, }; - schema.index.into_iter().map(|ex| - ex.partial_eval(&ctx).map(|ex| { - match ex { + schema + .index + .into_iter() + .map(|ex| { + ex.partial_eval(&ctx).map(|ex| match ex { Expr::TupleSetIdx(tidx) => IndexCol::Col(tidx), - ex => IndexCol::Expr(ex.to_static()) - } - })) + ex => IndexCol::Expr(ex.to_static()), + }) + }) .collect::, _>>()? } TableInfo::Edge(edge_info) => { let src_info = self.table_by_id(edge_info.src_id)?; let src_keys = match &src_info { TableInfo::Node(n) => &n.keys, - _ => unreachable!() + _ => unreachable!(), }; let dst_info = self.table_by_id(edge_info.dst_id)?; let dst_keys = match &dst_info { TableInfo::Node(n) => &n.keys, - _ => unreachable!() + _ => unreachable!(), }; let ctx = EdgeDefEvalCtx { keys: &edge_info.keys, @@ -447,24 +544,31 @@ pub(crate) trait DdlContext { dst_keys, assoc_vals: &assoc_vals, }; - schema.index.into_iter().map(|ex| - ex.partial_eval(&ctx).map(|ex| { - match ex { + schema + .index + .into_iter() + .map(|ex| { + ex.partial_eval(&ctx).map(|ex| match ex { Expr::TupleSetIdx(tidx) => IndexCol::Col(tidx), - ex => IndexCol::Expr(ex.to_static()) - } - })) + ex => IndexCol::Expr(ex.to_static()), + }) + }) .collect::, _>>()? } - _ => unreachable!() + _ => unreachable!(), }; let info = IndexInfo { name: schema.name, tid: self.gen_table_id()?, src_id: src_schema.table_id(), - assoc_ids: schema.assoc_names.iter().map(|n| - self.table_id_by_name(n, [TableKind::Assoc], true)) + assoc_ids: schema + .assoc_names + .iter() + .map(|n| { + self.table_by_name(n, [DataKind::Assoc]) + .map(|t| t.table_id()) + }) .collect::>>()?, index: index_exprs, }; @@ -481,7 +585,9 @@ pub(crate) trait DdlContext { fn commit(&mut self) -> Result<()>; } -fn check_name_clash<'a, I: IntoIterator, II: IntoIterator>(kvs: I) -> Result<()> { +fn check_name_clash<'a, I: IntoIterator, II: IntoIterator>( + kvs: I, +) -> Result<()> { let mut seen: BTreeSet<&str> = BTreeSet::new(); for it in kvs.into_iter() { for el in it.into_iter() { @@ -494,15 +600,22 @@ fn check_name_clash<'a, I: IntoIterator, II: IntoIterator) -> Result> { - cols.into_iter().map(|ColSchema { name, typing, default }| - match default.partial_eval(&()) { - Ok(default) => Ok(ColSchema { - name, - typing, - default, - }), - Err(e) => Err(e.into()) - }).collect::>>() + cols.into_iter() + .map( + |ColSchema { + name, + typing, + default, + }| match default.partial_eval(&()) { + Ok(default) => Ok(ColSchema { + name, + typing, + default, + }), + Err(e) => Err(e.into()), + }, + ) + .collect::>>() } pub(crate) struct NodeDefEvalCtx<'a> { @@ -552,7 +665,6 @@ impl<'a> PartialEvalContext for NodeDefEvalCtx<'a> { } } - pub(crate) struct EdgeDefEvalCtx<'a> { keys: &'a [ColSchema], vals: &'a [ColSchema], @@ -624,45 +736,134 @@ impl<'a> PartialEvalContext for EdgeDefEvalCtx<'a> { } } - struct MainDbContext<'a> { sess: &'a Session, txn: TransactionPtr, } +fn get_related_table_ids_in_stack( + stack_map: &TableAssocMap, + tid: TableId, + tag: DataKind, +) -> Result> { + match stack_map.get(&tag) { + None => Ok(vec![]), + Some(t) => match t.get(&tid) { + None => Ok(vec![]), + Some(found) => Ok(found + .iter() + .map(|v| TableId { + in_root: false, + id: *v, + }) + .collect()), + }, + } +} + +fn get_related_table_ids_in_main( + txn: &TransactionPtr, + id: u32, + tag: DataKind, +) -> Result> { + let mut key = OwnTuple::with_prefix(0); + key.push_int(id as i64); + key.push_int(tag as i64); + let assocs = txn.get_for_update_owned(&default_read_options(), &key)?; + if let Some(slice) = assocs { + let mut ret = vec![]; + let tuple = Tuple::new(slice); + for val in tuple.iter() { + let val = val?; + let tid = val + .get_int() + .ok_or_else(|| DdlReifyError::Corruption(tuple.to_owned()))?; + ret.push(TableId { + in_root: true, + id: tid as u32, + }) + } + Ok(ret) + } else { + Ok(vec![]) + } +} + +fn find_table_in_main(txn: &TransactionPtr, name: &str) -> Result { + let mut name_key = OwnTuple::with_prefix(0); + name_key.push_str(name); + + match txn.get_for_update_owned(&default_read_options(), &name_key)? { + None => Err(DdlReifyError::TableNameNotFound(name.to_string())), + Some(slice) => { + let tuple = Tuple::new(slice); + let id = tuple.get_int(0)?; + Ok(TableId { + in_root: true, + id: id as u32, + }) + } + } +} + +fn find_table_by_id_in_main(txn: &TransactionPtr, id: u32) -> Result { + let mut idx_key = OwnTuple::with_prefix(0); + idx_key.push_int(id as i64); + let res = txn + .get_owned(&default_read_options(), &idx_key)? + .ok_or(DdlReifyError::TableNotFound(TableId { id, in_root: true }))?; + let info = TableInfo::try_from(Tuple::new(res))?; + Ok(info) +} + impl<'a> DdlContext for MainDbContext<'a> { fn gen_table_id(&mut self) -> Result { let id = self.sess.get_next_main_table_id()?; Ok(TableId { in_root: true, id }) } - fn table_id_by_name>(&self, name: &str, kind: I, for_derivation: bool) -> Result { - todo!() + fn table_id_by_name(&self, name: &str) -> Result { + find_table_in_main(&self.txn, name) } fn table_by_id(&self, TableId { id, in_root }: TableId) -> Result { if !in_root { return Err(DdlReifyError::TableNotFound(TableId { id, in_root })); + } else { + find_table_by_id_in_main(&self.txn, id) + } + } + + fn assoc_ids_by_main_id(&self, tid: TableId) -> Result> { + if tid.in_root { + get_related_table_ids_in_main(&self.txn, tid.id, DataKind::Assoc) + } else { + Ok(vec![]) } - let mut idx_key = OwnTuple::with_prefix(0); - idx_key.push_int(id as i64); - let res = self.txn - .get_owned(&default_read_options(), &idx_key)? - .ok_or(DdlReifyError::TableNotFound(TableId { id, in_root }))?; - let info = TableInfo::try_from(Tuple::new(res))?; - Ok(info) } - fn assoc_ids_by_main_id(&self, id: TableId) -> Result> { - todo!() + fn edge_ids_by_main_id(&self, tid: TableId) -> Result> { + if tid.in_root { + get_related_table_ids_in_main(&self.txn, tid.id, DataKind::Edge) + } else { + Ok(vec![]) + } } - fn edge_ids_by_main_id(&self, id: TableId) -> Result> { - todo!() + fn bwd_edge_ids_by_main_id(&self, tid: TableId) -> Result> { + if tid.in_root { + get_related_table_ids_in_main(&self.txn, tid.id, DataKind::EdgeBwd) + } else { + Ok(vec![]) + } } - fn index_ids_by_main_id(&self, id: TableId) -> Result> { - todo!() + fn index_ids_by_main_id(&self, tid: TableId) -> Result> { + if tid.in_root { + get_related_table_ids_in_main(&self.txn, tid.id, DataKind::Index) + } else { + Ok(vec![]) + } } fn store_table(&mut self, info: TableInfo) -> Result<()> { @@ -672,8 +873,16 @@ impl<'a> DdlContext for MainDbContext<'a> { let mut name_key = OwnTuple::with_prefix(0); name_key.push_str(tname); - if !matches!(self.txn.get_for_update_owned(&default_read_options(), &name_key)?, None) { - return Err(NameConflict(tname.to_string()).into()); + if let Some(existing) = self + .txn + .get_for_update_owned(&default_read_options(), &name_key)? + { + return if Tuple::new(existing) == Tuple::from(&info) { + // exactly the same thing already exists, nothing to do! + Ok(()) + } else { + Err(NameConflict(tname.to_string()).into()) + }; } let mut idx_key = OwnTuple::with_prefix(0); @@ -688,7 +897,7 @@ impl<'a> DdlContext for MainDbContext<'a> { key.push_int(DataKind::Edge as i64); let mut current = match self.txn.get_for_update_owned(&read_opts, &key)? { Some(v) => OwnTuple::new(v.as_ref().to_vec()), - None => OwnTuple::with_prefix(0) + None => OwnTuple::with_prefix(0), }; current.push_int(tid as i64); self.txn.put(&key, ¤t)?; @@ -698,7 +907,7 @@ impl<'a> DdlContext for MainDbContext<'a> { key.push_int(DataKind::EdgeBwd as i64); let mut current = match self.txn.get_for_update_owned(&read_opts, &key)? { Some(v) => OwnTuple::new(v.as_ref().to_vec()), - None => OwnTuple::with_prefix(0) + None => OwnTuple::with_prefix(0), }; current.push_int(tid as i64); self.txn.put(&key, ¤t)?; @@ -709,7 +918,7 @@ impl<'a> DdlContext for MainDbContext<'a> { key.push_int(DataKind::Assoc as i64); let mut current = match self.txn.get_for_update_owned(&read_opts, &key)? { Some(v) => OwnTuple::new(v.as_ref().to_vec()), - None => OwnTuple::with_prefix(0) + None => OwnTuple::with_prefix(0), }; current.push_int(tid as i64); self.txn.put(&key, ¤t)?; @@ -720,7 +929,7 @@ impl<'a> DdlContext for MainDbContext<'a> { key.push_int(DataKind::Index as i64); let mut current = match self.txn.get_for_update_owned(&read_opts, &key)? { Some(v) => OwnTuple::new(v.as_ref().to_vec()), - None => OwnTuple::with_prefix(0) + None => OwnTuple::with_prefix(0), }; current.push_int(tid as i64); self.txn.put(&key, ¤t)?; @@ -741,31 +950,66 @@ impl<'a> DdlContext for MainDbContext<'a> { } } -// impl<'a> DdlContext for TempDbContext<'a> { fn gen_table_id(&mut self) -> Result { let id = self.sess.get_next_temp_table_id(); Ok(TableId { in_root: false, id }) } - fn table_id_by_name>(&self, name: &str, kind: I, for_derivation: bool) -> Result { - todo!() + fn table_id_by_name(&self, name: &str) -> Result { + for frame in self.sess.stack.iter().rev() { + if let Some(found) = frame.get(name) { + return if let SessionDefinable::Table(id) = found { + Ok(TableId { + in_root: false, + id: *id, + }) + } else { + Err(DdlReifyError::NameClash(name.to_string())) + }; + } + } + find_table_in_main(&self.txn, name) } - fn table_by_id(&self, tid: TableId) -> Result { - todo!() + fn table_by_id(&self, TableId { id, in_root }: TableId) -> Result { + if !in_root { + self.sess + .tables + .get(&id) + .cloned() + .ok_or(DdlReifyError::TableNotFound(TableId { id, in_root })) + } else { + find_table_by_id_in_main(&self.txn, id) + } + } + + fn assoc_ids_by_main_id(&self, tid: TableId) -> Result> { + let tag = DataKind::Assoc; + let mut found = get_related_table_ids_in_stack(&self.sess.table_assocs, tid, tag)?; + found.extend(get_related_table_ids_in_main(&self.txn, tid.id, tag)?); + Ok(found) } - fn assoc_ids_by_main_id(&self, id: TableId) -> Result> { - todo!() + fn edge_ids_by_main_id(&self, tid: TableId) -> Result> { + let tag = DataKind::Edge; + let mut found = get_related_table_ids_in_stack(&self.sess.table_assocs, tid, tag)?; + found.extend(get_related_table_ids_in_main(&self.txn, tid.id, tag)?); + Ok(found) } - fn edge_ids_by_main_id(&self, id: TableId) -> Result> { - todo!() + fn bwd_edge_ids_by_main_id(&self, tid: TableId) -> Result> { + let tag = DataKind::EdgeBwd; + let mut found = get_related_table_ids_in_stack(&self.sess.table_assocs, tid, tag)?; + found.extend(get_related_table_ids_in_main(&self.txn, tid.id, tag)?); + Ok(found) } - fn index_ids_by_main_id(&self, id: TableId) -> Result> { - todo!() + fn index_ids_by_main_id(&self, tid: TableId) -> Result> { + let tag = DataKind::Index; + let mut found = get_related_table_ids_in_stack(&self.sess.table_assocs, tid, tag)?; + found.extend(get_related_table_ids_in_main(&self.txn, tid.id, tag)?); + Ok(found) } fn store_table(&mut self, info: TableInfo) -> Result<()> { @@ -778,21 +1022,39 @@ impl<'a> DdlContext for TempDbContext<'a> { } else { match &info { TableInfo::Edge(info) => { - let edge_assocs = self.sess.table_assocs.entry(DataKind::Edge).or_insert(Default::default()); + let edge_assocs = self + .sess + .table_assocs + .entry(DataKind::Edge) + .or_insert(Default::default()); let src_assocs = edge_assocs.entry(info.src_id).or_insert(Default::default()); src_assocs.insert(tid); - let back_edge_assocs = self.sess.table_assocs.entry(DataKind::EdgeBwd).or_insert(Default::default()); - let dst_assocs = back_edge_assocs.entry(info.dst_id).or_insert(Default::default()); + let back_edge_assocs = self + .sess + .table_assocs + .entry(DataKind::EdgeBwd) + .or_insert(Default::default()); + let dst_assocs = back_edge_assocs + .entry(info.dst_id) + .or_insert(Default::default()); dst_assocs.insert(tid); } TableInfo::Assoc(info) => { - let assocs = self.sess.table_assocs.entry(DataKind::Assoc).or_insert(Default::default()); + let assocs = self + .sess + .table_assocs + .entry(DataKind::Assoc) + .or_insert(Default::default()); let src_assocs = assocs.entry(info.src_id).or_insert(Default::default()); src_assocs.insert(tid); } TableInfo::Index(info) => { - let idx_assocs = self.sess.table_assocs.entry(DataKind::Index).or_insert(Default::default()); + let idx_assocs = self + .sess + .table_assocs + .entry(DataKind::Index) + .or_insert(Default::default()); let src_assocs = idx_assocs.entry(info.src_id).or_insert(Default::default()); src_assocs.insert(tid); } @@ -813,18 +1075,17 @@ impl<'a> DdlContext for TempDbContext<'a> { struct TempDbContext<'a> { sess: &'a mut Session, + txn: TransactionPtr, } impl Session { fn main_ctx(&self) -> MainDbContext { - MainDbContext { - sess: self, - txn: self.txn(None), - } + let txn = self.txn(None); + txn.set_snapshot(); + MainDbContext { sess: self, txn } } fn temp_ctx(&mut self) -> TempDbContext { - TempDbContext { - sess: self - } + let txn = self.txn(None); + TempDbContext { sess: self, txn } } -} \ No newline at end of file +} diff --git a/src/lib.rs b/src/lib.rs index 8fa39622..c2ba9201 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,8 +1,8 @@ +pub(crate) mod algebra; pub(crate) mod data; +pub(crate) mod ddl; pub(crate) mod logger; pub(crate) mod parser; pub(crate) mod runtime; -pub(crate) mod algebra; -pub(crate) mod ddl; pub use runtime::instance::DbInstance; diff --git a/src/runtime.rs b/src/runtime.rs index ddf122bd..a4bb24f6 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -1,3 +1,3 @@ pub(crate) mod instance; -pub(crate) mod session; pub(crate) mod options; +pub(crate) mod session; diff --git a/src/runtime/instance.rs b/src/runtime/instance.rs index 3be0a165..c86a7bde 100644 --- a/src/runtime/instance.rs +++ b/src/runtime/instance.rs @@ -1,11 +1,11 @@ +use crate::data::tuple::TupleError; use crate::data::tuple_set::MIN_TABLE_ID_BOUND; use crate::runtime::options::*; +use crate::runtime::session::Session; use cozorocks::*; use log::error; use std::sync::{Arc, Mutex, RwLock}; use std::{mem, result}; -use crate::data::tuple::TupleError; -use crate::runtime::session::Session; #[derive(thiserror::Error, Debug)] pub enum DbInstanceError { @@ -28,7 +28,7 @@ pub enum DbInstanceError { TableDoesNotExist(u32), #[error("Name conflict {0}")] - NameConflict(String) + NameConflict(String), } type Result = result::Result; @@ -133,7 +133,7 @@ impl DbInstance { params: Default::default(), table_locks: self.table_locks.clone(), tables: Default::default(), - table_assocs: Default::default() + table_assocs: Default::default(), }) } @@ -189,7 +189,6 @@ impl Drop for DbInstance { } } - #[cfg(test)] mod tests { use super::*; diff --git a/src/runtime/session.rs b/src/runtime/session.rs index 94a48334..a9d6175c 100644 --- a/src/runtime/session.rs +++ b/src/runtime/session.rs @@ -1,18 +1,18 @@ -use std::collections::{BTreeMap, BTreeSet}; -use std::result; -use std::sync::{Arc, Mutex, RwLockReadGuard, RwLockWriteGuard}; -use std::sync::atomic::{AtomicU32, Ordering}; -use lazy_static::lazy_static; -use log::error; -use cozorocks::{DbPtr, ReadOptionsPtr, TransactionPtr, WriteOptionsPtr}; use crate::data::expr::StaticExpr; use crate::data::tuple::{DataKind, OwnTuple, Tuple}; -use crate::data::tuple_set::{MIN_TABLE_ID_BOUND, TableId}; +use crate::data::tuple_set::{TableId, MIN_TABLE_ID_BOUND}; use crate::data::typing::Typing; -use crate::data::value::{Value, StaticValue}; +use crate::data::value::{StaticValue, Value}; use crate::ddl::reify::TableInfo; use crate::runtime::instance::{DbInstanceError, SessionHandle, SessionStatus, TableLock}; use crate::runtime::options::{default_txn_options, default_write_options}; +use cozorocks::{DbPtr, ReadOptionsPtr, TransactionPtr, WriteOptionsPtr}; +use lazy_static::lazy_static; +use log::error; +use std::collections::{BTreeMap, BTreeSet}; +use std::result; +use std::sync::atomic::{AtomicU32, Ordering}; +use std::sync::{Arc, Mutex, RwLockReadGuard, RwLockWriteGuard}; type Result = result::Result; @@ -20,11 +20,11 @@ pub(crate) enum SessionDefinable { Value(StaticValue), Expr(StaticExpr), Typing(Typing), - Table(u32) - // TODO + Table(u32), // TODO } pub(crate) type SessionStackFrame = BTreeMap; +pub(crate) type TableAssocMap = BTreeMap>>; pub struct Session { pub(crate) main: DbPtr, @@ -40,7 +40,7 @@ pub struct Session { pub(crate) session_handle: Arc>, pub(crate) table_locks: TableLock, pub(crate) tables: BTreeMap, - pub(crate) table_assocs: BTreeMap>> + pub(crate) table_assocs: TableAssocMap, } pub(crate) struct InterpretContext<'a> { @@ -156,4 +156,3 @@ impl Drop for Session { } } } -