diff --git a/lykiadb-lang/src/ast/expr.rs b/lykiadb-lang/src/ast/expr.rs index 5c0b1f0..8c5fb72 100644 --- a/lykiadb-lang/src/ast/expr.rs +++ b/lykiadb-lang/src/ast/expr.rs @@ -565,7 +565,10 @@ impl Display for Expr { } impl Expr { - pub fn walk(&self, visitor: &mut impl FnMut(&Expr) -> Option>) -> Option> { + pub fn walk( + &self, + visitor: &mut impl FnMut(&Expr) -> Option>, + ) -> Option> { let result = visitor(self); if result.is_none() { return None; @@ -595,7 +598,10 @@ impl Expr { // Expr::Call { callee, args, .. } => { let rcallee = callee.walk(visitor); - let rargs = args.iter().map(|x| x.walk(visitor)).fold(None, |acc, x| acc.or(x)); + let rargs = args + .iter() + .map(|x| x.walk(visitor)) + .fold(None, |acc, x| acc.or(x)); rcallee.or(rargs) } diff --git a/lykiadb-server/src/engine/interpreter.rs b/lykiadb-server/src/engine/interpreter.rs index 76a59da..e058519 100644 --- a/lykiadb-server/src/engine/interpreter.rs +++ b/lykiadb-server/src/engine/interpreter.rs @@ -8,9 +8,9 @@ use lykiadb_lang::tokenizer::scanner::Scanner; use lykiadb_lang::Span; use lykiadb_lang::Spanned; use lykiadb_lang::{Literal, Locals, Scopes}; +use pretty_assertions::assert_eq; use rustc_hash::FxHashMap; use serde::{Deserialize, Serialize}; -use pretty_assertions::assert_eq; use super::error::ExecutionError; use super::stdlib::stdlib; @@ -341,7 +341,9 @@ impl VisitorMut for Interpreter { let mut planner = Planner::new(self); // TODO(vck): Use the existing context let plan = planner.build(e)?; if let Some(out) = &self.output { - out.write().unwrap().push(RV::Str(Arc::new(plan.to_string().trim().to_string()))); + out.write() + .unwrap() + .push(RV::Str(Arc::new(plan.to_string().trim().to_string()))); } Ok(RV::Undefined) } @@ -700,7 +702,6 @@ impl Default for Output { } impl Output { - pub fn new() -> Output { Output { out: Vec::new() } } @@ -712,7 +713,10 @@ impl Output { pub fn expect(&mut self, rv: Vec) { if rv.len() == 1 { if let Some(first) = rv.first() { - assert_eq!(self.out.first().unwrap_or(&RV::Undefined).to_string(), first.to_string()); + assert_eq!( + self.out.first().unwrap_or(&RV::Undefined).to_string(), + first.to_string() + ); } } assert_eq!(self.out, rv) diff --git a/lykiadb-server/src/plan/planner.rs b/lykiadb-server/src/plan/planner.rs index 8399dce..48f607f 100644 --- a/lykiadb-server/src/plan/planner.rs +++ b/lykiadb-server/src/plan/planner.rs @@ -8,11 +8,14 @@ use crate::{ value::RV, }; -use lykiadb_lang::{ast::{ - expr::Expr, - sql::{SqlFrom, SqlJoinType, SqlProjection, SqlSelect, SqlSelectCore, SqlSource}, - visitor::VisitorMut, -}, Spanned}; +use lykiadb_lang::{ + ast::{ + expr::Expr, + sql::{SqlFrom, SqlJoinType, SqlProjection, SqlSelect, SqlSelectCore, SqlSource}, + visitor::VisitorMut, + }, + Spanned, +}; use super::{scope::Scope, IntermediateExpr, Node, Plan, PlannerError}; @@ -100,35 +103,34 @@ impl<'a> Planner<'a> { let mut subqueries: Vec = vec![]; let mut overrides = HashMap::new(); - let result = expr.walk::<(), HaltReason>(&mut |e: &Expr| { - match e { - Expr::Get { - id, object, name, .. - } => { - println!("Get {}.({})", object, name); - None - }, - Expr::Variable { name, id, .. } => - { - println!("Variable {}", name); - None - }, - Expr::Call { - callee, args, id, .. - } => { - println!("Call {}({:?})", callee, args); - None - }, - Expr::Select { query, .. } => { - if !allow_subqueries { - return Some(Err(HaltReason::Error(ExecutionError::Plan(PlannerError::SubqueryNotAllowed(expr.get_span()))))); - } - let subquery = self.build_select(query); - subqueries.push(subquery.unwrap()); - None + let result = expr.walk::<(), HaltReason>(&mut |e: &Expr| match e { + Expr::Get { + id, object, name, .. + } => { + println!("Get {}.({})", object, name); + None + } + Expr::Variable { name, id, .. } => { + println!("Variable {}", name); + None + } + Expr::Call { + callee, args, id, .. + } => { + println!("Call {}({:?})", callee, args); + None + } + Expr::Select { query, .. } => { + if !allow_subqueries { + return Some(Err(HaltReason::Error(ExecutionError::Plan( + PlannerError::SubqueryNotAllowed(expr.get_span()), + )))); } - _ => Some(Ok(())), + let subquery = self.build_select(query); + subqueries.push(subquery.unwrap()); + None } + _ => Some(Ok(())), }); if let Some(Err(err)) = result { diff --git a/lykiadb-server/src/value/mod.rs b/lykiadb-server/src/value/mod.rs index a346035..bf0d1a7 100644 --- a/lykiadb-server/src/value/mod.rs +++ b/lykiadb-server/src/value/mod.rs @@ -107,7 +107,7 @@ impl Display for RV { write!(f, "{}", item)?; } write!(f, "]") - }, + } RV::Object(obj) => { let obj = (obj as &RwLock>).read().unwrap(); write!(f, "{{")?; @@ -118,7 +118,7 @@ impl Display for RV { write!(f, "{}: {}", key, value)?; } write!(f, "}}") - }, + } RV::Callable(_) => write!(f, ""), } } diff --git a/lykiadb-server/tests/util.rs b/lykiadb-server/tests/util.rs index 0b4c04e..bba2c76 100644 --- a/lykiadb-server/tests/util.rs +++ b/lykiadb-server/tests/util.rs @@ -1,12 +1,11 @@ +use lykiadb_server::{ + engine::interpreter::test_helpers::{assert_err, assert_out}, + value::RV, +}; use std::sync::Arc; -use lykiadb_server::{engine::interpreter::test_helpers::{assert_err, assert_out}, value::RV}; fn expect_plan(query: &str, expected_plan: &str) { - assert_out(query, - vec![ - RV::Str(Arc::new(expected_plan.to_string())), - ], - ); + assert_out(query, vec![RV::Str(Arc::new(expected_plan.to_string()))]); } pub fn run_test(input: &str) { @@ -23,23 +22,25 @@ pub fn run_test(input: &str) { .trim() .to_string(); - let flags = directives_and_input[..directives_end - 1].trim().split(",").map(|flag| { - let kv: Vec<&str> = flag.split("=").collect(); - return (kv[0].trim(), kv[1].trim()); - }).fold(std::collections::HashMap::new(), |mut acc, (k, v)| { - acc.insert(k, v); - acc - }); + let flags = directives_and_input[..directives_end - 1] + .trim() + .split(",") + .map(|flag| { + let kv: Vec<&str> = flag.split("=").collect(); + return (kv[0].trim(), kv[1].trim()); + }) + .fold(std::collections::HashMap::new(), |mut acc, (k, v)| { + acc.insert(k, v); + acc + }); let io_parts: Vec<&str> = rest.split("---").collect(); - + if flags.get("expect") == Some(&"error") { - assert_err(io_parts[0].trim(), - io_parts[1].trim() - ); + assert_err(io_parts[0].trim(), io_parts[1].trim()); continue; } - + expect_plan(io_parts[0].trim(), io_parts[1].trim()); } }