From ba4d10e7a5359da67f0a85fe78209f75348239f2 Mon Sep 17 00:00:00 2001 From: Ziyang Hu Date: Thu, 28 Apr 2022 16:33:46 +0800 Subject: [PATCH] add params support --- src/db/engine.rs | 5 ++++- src/db/eval.rs | 52 ++++++++++++++++++++++++++++++++++++++---------- src/error.rs | 3 +++ 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/src/db/engine.rs b/src/db/engine.rs index c848db9a..e7aa3bff 100644 --- a/src/db/engine.rs +++ b/src/db/engine.rs @@ -2,16 +2,17 @@ // will be shared among threads +use std::collections::BTreeMap; use cozorocks::*; use std::sync::{Arc, Mutex, RwLock}; use std::time::{SystemTime, UNIX_EPOCH}; use uuid::Uuid; use uuid::v1::{Context, Timestamp}; use rand::Rng; -use crate::db::eval::Environment; use crate::error::{CozoError, Result}; use crate::error::CozoError::{Poisoned, SessionErr}; use crate::relation::tuple::Tuple; +use crate::relation::value::{StaticValue, Value}; pub struct EngineOptions { cmp: RustComparatorPtr, @@ -108,6 +109,7 @@ impl Engine { perm_cf: SharedPtr::null(), temp_cf: SharedPtr::null(), handle, + params: BTreeMap::default() }; sess.start()?; Ok(sess) @@ -121,6 +123,7 @@ pub struct Session<'a> { pub txn: TransactionPtr, pub perm_cf: SharedPtr, pub temp_cf: SharedPtr, + pub params: BTreeMap, } // every session has its own column family to play with // metadata are stored in table 0 diff --git a/src/db/eval.rs b/src/db/eval.rs index 139823c6..e60558dd 100644 --- a/src/db/eval.rs +++ b/src/db/eval.rs @@ -8,7 +8,7 @@ use crate::db::engine::{Session}; use crate::relation::table::{Table}; use crate::relation::tuple::{OwnTuple, Tuple}; use crate::relation::typing::Typing; -use crate::relation::value::Value; +use crate::relation::value::{StaticValue, Value}; use crate::error::{CozoError, Result}; use crate::relation::data::DataKind; use crate::parser::Rule; @@ -20,6 +20,7 @@ pub trait Environment> where Self: Sized { fn get_stack_depth(&self) -> i32; fn push_env(&mut self); fn pop_env(&mut self) -> Result<()>; + fn set_param(&mut self, name: &str, val: Value); fn define_variable(&mut self, name: &str, val: &Value, in_root: bool) -> Result<()> { let mut data = Tuple::with_data_prefix(DataKind::Value); data.push_value(val); @@ -29,6 +30,24 @@ pub trait Environment> where Self: Sized { todo!() } fn resolve(&self, name: &str) -> Result>>; + fn resolve_param(&self, name: &str) -> Result; + fn resolve_value(&self, name: &str) -> Result> { + if name.starts_with('&') { + self.resolve_param(name).map(|v| Some(v.clone())) + } else { + match self.resolve(name)? { + None => Ok(None), + Some(t) => { + match t.data_kind()? { + DataKind::Value => Ok(Some(t.get(0) + .ok_or_else(|| CozoError::LogicError("Corrupt".to_string()))? + .to_static())), + k => Err(CozoError::UnexpectedDataKind(k)) + } + } + } + } + } fn delete_defined(&mut self, name: &str, in_root: bool) -> Result<()>; fn define_data(&mut self, name: &str, data: OwnTuple, in_root: bool) -> Result<()>; fn encode_definable_key(&self, name: &str, in_root: bool) -> OwnTuple { @@ -224,21 +243,15 @@ pub trait Environment> where Self: Sized { Ok((is_ev, v.into())) } Value::Variable(v) => { - Ok(match self.resolve(&v)? { + Ok(match self.resolve_value(&v)? { None => (false, Value::Variable(v)), Some(rs) => { - match rs.data_kind() { - Ok(DataKind::Value) => { - let resolved = rs.get(0).ok_or_else(|| CozoError::BadDataFormat(rs.data.as_ref().to_vec()))?; - (resolved.is_evaluated(), resolved.to_static()) - } - _ => (false, Value::Variable(v)) - } + (rs.is_evaluated(), rs.to_static()) } }) } + Value::Apply(op, args) => { - use crate::relation::value; Ok(match op.as_ref() { value::OP_ADD => self.add_values(args)?, value::OP_SUB => self.sub_values(args)?, @@ -653,12 +666,13 @@ pub trait Environment> where Self: Sized { pub struct MemoryEnv { root: BTreeMap, stack: Vec>, + params: BTreeMap, max_storage_id: u32, } impl Default for MemoryEnv { fn default() -> Self { - MemoryEnv { root: BTreeMap::default(), stack: vec![BTreeMap::default()], max_storage_id: 0 } + MemoryEnv { root: BTreeMap::default(), stack: vec![BTreeMap::default()], max_storage_id: 0, params: BTreeMap::default() } } } @@ -683,6 +697,10 @@ impl Environment> for MemoryEnv { Ok(()) } + fn set_param(&mut self, name: &str, val: Value) { + self.params.insert(name.to_string(), val.to_static()); + } + fn resolve(&self, name: &str) -> Result> { for layer in self.stack.iter() { if let Some(res) = layer.get(name) { @@ -692,6 +710,10 @@ impl Environment> for MemoryEnv { Ok(self.root.get(name).cloned()) } + fn resolve_param(&self, name: &str) -> Result { + self.params.get(name).cloned().ok_or_else(|| CozoError::UndefinedParam(name.to_string())) + } + fn delete_defined(&mut self, name: &str, in_root: bool) -> Result<()> { if in_root { self.root.remove(name); @@ -780,6 +802,10 @@ impl<'a> Environment for Session<'a> { Ok(()) } + fn set_param(&mut self, name: &str, val: Value) { + self.params.insert(name.to_string(), val.to_static()); + } + fn resolve(&self, name: &str) -> Result>> { let mut tuple = Tuple::with_null_prefix(); tuple.push_str(name); @@ -796,6 +822,10 @@ impl<'a> Environment for Session<'a> { Ok(res) } + fn resolve_param(&self, name: &str) -> Result { + self.params.get(name).cloned().ok_or_else(|| CozoError::UndefinedParam(name.to_string())) + } + fn delete_defined(&mut self, name: &str, in_root: bool) -> Result<()> { let key = self.encode_definable_key(name, in_root); if in_root { diff --git a/src/error.rs b/src/error.rs index 05acb928..81851183 100644 --- a/src/error.rs +++ b/src/error.rs @@ -39,6 +39,9 @@ pub enum CozoError { #[error("Duplicate names in {0:?}")] DuplicateNames(Vec), + + #[error("Undefined parameter {0}")] + UndefinedParam(String), // // #[error("Undefined table")] // UndefinedTable,