From be6f9227381d841136a3e01abc8c3cd4874a03c2 Mon Sep 17 00:00:00 2001 From: Ziyang Hu Date: Sun, 17 Apr 2022 22:53:53 +0800 Subject: [PATCH] mutation statement eval --- src/ast.rs | 2 +- src/definition.rs | 2 +- src/error.rs | 3 +++ src/eval.rs | 40 ++++++++++++++++++++-------------------- src/grammar.pest | 5 ++--- src/mutation.rs | 33 ++++++++++++++++++++++++++++++++- 6 files changed, 59 insertions(+), 26 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index 85df0d32..2538f4c8 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -65,7 +65,7 @@ pub enum Expr<'a> { } pub trait ExprVisitor<'a, T> { - fn visit_expr(&mut self, ex: &Expr<'a>) -> T; + fn visit_expr(&self, ex: &Expr<'a>) -> T; } diff --git a/src/definition.rs b/src/definition.rs index 15f2f4c4..8d45275f 100644 --- a/src/definition.rs +++ b/src/definition.rs @@ -19,7 +19,7 @@ fn parse_ident(pair: Pair) -> String { pair.as_str().to_string() } -fn build_name_in_def(pair: Pair, forbid_underscore: bool) -> Result { +pub fn build_name_in_def(pair: Pair, forbid_underscore: bool) -> Result { let inner = pair.into_inner().next().unwrap(); let name = match inner.as_rule() { Rule::ident => parse_ident(inner), diff --git a/src/error.rs b/src/error.rs index d3d18166..94235e0c 100644 --- a/src/error.rs +++ b/src/error.rs @@ -22,6 +22,9 @@ pub enum CozoError { #[error("Undefined type")] UndefinedType, + #[error("Undefined table")] + UndefinedTable, + #[error("Undefined parameter")] UndefinedParam, diff --git a/src/eval.rs b/src/eval.rs index 00d043b5..731c9fd9 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -52,7 +52,7 @@ impl Default for BareEvaluator { impl<'a, S: Storage> ExprVisitor<'a, Result>> for Evaluator { - fn visit_expr(&mut self, ex: &Expr<'a>) -> Result> { + fn visit_expr(&self, ex: &Expr<'a>) -> Result> { match ex { Apply(op, args) => { match op { @@ -96,7 +96,7 @@ impl<'a, S: Storage> ExprVisitor<'a, Result>> for Evaluator { } impl Evaluator { - fn add_exprs<'a>(&mut self, exprs: &[Expr<'a>]) -> Result> { + fn add_exprs<'a>(&self, exprs: &[Expr<'a>]) -> Result> { match exprs { [a, b] => { let a = self.visit_expr(a)?; @@ -125,7 +125,7 @@ impl Evaluator { } } - fn sub_exprs<'a>(&mut self, exprs: &[Expr<'a>]) -> Result> { + fn sub_exprs<'a>(&self, exprs: &[Expr<'a>]) -> Result> { match exprs { [a, b] => { let a = self.visit_expr(a)?; @@ -150,7 +150,7 @@ impl Evaluator { } } - fn mul_exprs<'a>(&mut self, exprs: &[Expr<'a>]) -> Result> { + fn mul_exprs<'a>(&self, exprs: &[Expr<'a>]) -> Result> { match exprs { [a, b] => { let a = self.visit_expr(a)?; @@ -175,7 +175,7 @@ impl Evaluator { } } - fn div_exprs<'a>(&mut self, exprs: &[Expr<'a>]) -> Result> { + fn div_exprs<'a>(&self, exprs: &[Expr<'a>]) -> Result> { match exprs { [a, b] => { let a = self.visit_expr(a)?; @@ -200,7 +200,7 @@ impl Evaluator { } } - fn mod_exprs<'a>(&mut self, exprs: &[Expr<'a>]) -> Result> { + fn mod_exprs<'a>(&self, exprs: &[Expr<'a>]) -> Result> { match exprs { [a, b] => { let a = self.visit_expr(a)?; @@ -222,7 +222,7 @@ impl Evaluator { } } - fn eq_exprs<'a>(&mut self, exprs: &[Expr<'a>]) -> Result> { + fn eq_exprs<'a>(&self, exprs: &[Expr<'a>]) -> Result> { match exprs { [a, b] => { let a = self.visit_expr(a)?; @@ -239,7 +239,7 @@ impl Evaluator { } } - fn ne_exprs<'a>(&mut self, exprs: &[Expr<'a>]) -> Result> { + fn ne_exprs<'a>(&self, exprs: &[Expr<'a>]) -> Result> { match exprs { [a, b] => { let a = self.visit_expr(a)?; @@ -256,7 +256,7 @@ impl Evaluator { } } - fn gt_exprs<'a>(&mut self, exprs: &[Expr<'a>]) -> Result> { + fn gt_exprs<'a>(&self, exprs: &[Expr<'a>]) -> Result> { match exprs { [a, b] => { let a = self.visit_expr(a)?; @@ -281,7 +281,7 @@ impl Evaluator { } } - fn ge_exprs<'a>(&mut self, exprs: &[Expr<'a>]) -> Result> { + fn ge_exprs<'a>(&self, exprs: &[Expr<'a>]) -> Result> { match exprs { [a, b] => { let a = self.visit_expr(a)?; @@ -306,7 +306,7 @@ impl Evaluator { } } - fn lt_exprs<'a>(&mut self, exprs: &[Expr<'a>]) -> Result> { + fn lt_exprs<'a>(&self, exprs: &[Expr<'a>]) -> Result> { match exprs { [a, b] => { let a = self.visit_expr(a)?; @@ -331,7 +331,7 @@ impl Evaluator { } } - fn le_exprs<'a>(&mut self, exprs: &[Expr<'a>]) -> Result> { + fn le_exprs<'a>(&self, exprs: &[Expr<'a>]) -> Result> { match exprs { [a, b] => { let a = self.visit_expr(a)?; @@ -356,7 +356,7 @@ impl Evaluator { } } - fn pow_exprs<'a>(&mut self, exprs: &[Expr<'a>]) -> Result> { + fn pow_exprs<'a>(&self, exprs: &[Expr<'a>]) -> Result> { match exprs { [a, b] => { let a = self.visit_expr(a)?; @@ -381,7 +381,7 @@ impl Evaluator { } } - fn coalesce_exprs<'a>(&mut self, exprs: &[Expr<'a>]) -> Result> { + fn coalesce_exprs<'a>(&self, exprs: &[Expr<'a>]) -> Result> { match exprs { [a, b] => { let a = self.visit_expr(a)?; @@ -401,7 +401,7 @@ impl Evaluator { } } - fn negate_expr<'a>(&mut self, exprs: &[Expr<'a>]) -> Result> { + fn negate_expr<'a>(&self, exprs: &[Expr<'a>]) -> Result> { Ok(match exprs { [a] => { match self.visit_expr(a)? { @@ -424,7 +424,7 @@ impl Evaluator { }) } - fn minus_expr<'a>(&mut self, exprs: &[Expr<'a>]) -> Result> { + fn minus_expr<'a>(&self, exprs: &[Expr<'a>]) -> Result> { Ok(match exprs { [a] => { match self.visit_expr(a)? { @@ -440,7 +440,7 @@ impl Evaluator { }) } - fn test_null_expr<'a>(&mut self, exprs: &[Expr<'a>]) -> Result> { + fn test_null_expr<'a>(&self, exprs: &[Expr<'a>]) -> Result> { Ok(match exprs { [a] => { match self.visit_expr(a)? { @@ -453,7 +453,7 @@ impl Evaluator { }) } - fn not_null_expr<'a>(&mut self, exprs: &[Expr<'a>]) -> Result> { + fn not_null_expr<'a>(&self, exprs: &[Expr<'a>]) -> Result> { Ok(match exprs { [a] => { match self.visit_expr(a)? { @@ -466,7 +466,7 @@ impl Evaluator { }) } - fn or_expr<'a>(&mut self, exprs: &[Expr<'a>]) -> Result> { + fn or_expr<'a>(&self, exprs: &[Expr<'a>]) -> Result> { let mut unevaluated = vec![]; let mut has_null = false; for expr in exprs { @@ -498,7 +498,7 @@ impl Evaluator { } } - fn and_expr<'a>(&mut self, exprs: &[Expr<'a>]) -> Result> { + fn and_expr<'a>(&self, exprs: &[Expr<'a>]) -> Result> { let mut unevaluated = vec![]; let mut no_null = true; for expr in exprs { diff --git a/src/grammar.pest b/src/grammar.pest index 55a6b634..2c704ba8 100644 --- a/src/grammar.pest +++ b/src/grammar.pest @@ -156,9 +156,8 @@ global_def = { "create" ~ definition } local_def = { "local" ~ definition } statement = _{ global_def | local_def } -mutation = { (insert|update|delete) ~ expr ~ ("as" ~ name_in_def)? ~ - ( (exclude ~ name_in_def ~ ("," ~ name_in_def)*) - | (include ~ name_in_def ~ ("," ~ name_in_def)*))? ~ ";" } +mutation = { (insert|update|delete) ~ expr ~ ("as" ~ name_in_def)? ~ mutation_filter? ~ ";" } +mutation_filter = { (exclude|include) ~ name_in_def ~ ("," ~ name_in_def)* } exclude = {"exclude"} include = {"include"} insert = {"insert"} diff --git a/src/mutation.rs b/src/mutation.rs index 71b0b707..8be6d13c 100644 --- a/src/mutation.rs +++ b/src/mutation.rs @@ -1,10 +1,14 @@ +use std::collections::BTreeMap; use pest::iterators::Pair; use crate::ast::{build_expr, Expr, ExprVisitor}; -use crate::error::CozoError::ValueRequired; +use crate::definition::build_name_in_def; +use crate::env::Env; +use crate::error::CozoError::{UndefinedTable, ValueRequired}; use crate::eval::Evaluator; use crate::storage::{RocksStorage}; use crate::error::Result; use crate::parser::{Parser, Rule}; +use crate::typing::Structured; use crate::value::Value; impl Evaluator { @@ -12,6 +16,28 @@ impl Evaluator { let mut pairs = pair.into_inner(); let op = pairs.next().unwrap().as_rule(); let expr = pairs.next().unwrap(); + let main_target; + // let filters; + match pairs.next() { + None => { + main_target = None; + // filters = None; + } + 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); + } + Rule::mutation_filter => { + main_target = None; + todo!() + } + _ => unreachable!() + } + } + } let expr = build_expr(expr)?; let expr = self.visit_expr(&expr)?; let val = match expr { @@ -19,8 +45,13 @@ impl Evaluator { _ => return Err(ValueRequired) }; println!("{:#?}", val); + let coerced_values = self.coerce_table_values(&val, main_target); Ok(()) } + + fn coerce_table_values(&self, values: &Value, table: Option<&Structured>) -> BTreeMap<&Structured, Vec> { + todo!() + } }