No UInt nonsense

main
Ziyang Hu 2 years ago
parent 832431c70f
commit 2fca50db90

@ -17,7 +17,7 @@ use crate::parser::text_identifier::build_name_in_def;
use crate::relation::value;
pub trait Environment<'t, T: AsRef<[u8]>> where Self: Sized {
fn get_next_storage_id(&mut self, in_root: bool) -> Result<u32>;
fn get_next_storage_id(&mut self, in_root: bool) -> Result<i64>;
fn get_stack_depth(&self) -> i32;
fn push_env(&mut self);
fn pop_env(&mut self) -> Result<()>;
@ -112,7 +112,7 @@ pub trait Environment<'t, T: AsRef<[u8]>> where Self: Sized {
}
let mut tuple = Tuple::with_data_prefix(DataKind::Associate);
tuple.push_bool(src_global);
tuple.push_uint(src_id);
tuple.push_int(src_id);
tuple.push_str(vals_typing.to_string());
Ok((name, tuple))
}
@ -155,9 +155,9 @@ pub trait Environment<'t, T: AsRef<[u8]>> where Self: Sized {
};
let mut tuple = Tuple::with_data_prefix(DataKind::Edge);
tuple.push_bool(src_global);
tuple.push_uint(src_id);
tuple.push_int(src_id);
tuple.push_bool(dst_global);
tuple.push_uint(dst_id);
tuple.push_int(dst_id);
tuple.push_str(keys_typing.to_string());
tuple.push_str(vals_typing.to_string());
tuple.push_null(); // TODO default values for keys
@ -165,7 +165,7 @@ pub trait Environment<'t, T: AsRef<[u8]>> where Self: Sized {
Ok((name, tuple))
}
fn extract_table_id(src_tbl: Tuple<T>) -> Result<(DataKind, bool, u64)> {
fn extract_table_id(src_tbl: Tuple<T>) -> Result<(DataKind, bool, i64)> {
let kind = src_tbl.data_kind()?;
match kind {
DataKind::DataTuple | DataKind::Value | DataKind::TypeAlias => return Err(CozoError::UnexpectedDataKind(kind)),
@ -176,7 +176,7 @@ pub trait Environment<'t, T: AsRef<[u8]>> where Self: Sized {
_ => panic!("Data corrupt")
};
let table_id = match src_tbl.get(1).expect("Data corrupt") {
Value::UInt(u) => u,
Value::Int(u) => u,
_ => panic!("Data corrupt")
};
Ok((kind, is_global, table_id))
@ -203,12 +203,8 @@ pub trait Environment<'t, T: AsRef<[u8]>> where Self: Sized {
pair.into_inner().next().unwrap(), in_root,
)?;
if need_id {
let id = self.get_next_storage_id(in_root)?;
let mut new_tuple = Tuple::with_prefix(tuple.get_prefix());
new_tuple.push_bool(in_root);
new_tuple.push_uint(id as u64);
new_tuple.concat_data(&tuple);
tuple = new_tuple;
tuple = tuple.insert_values_at(0, &[in_root.into(),
(self.get_next_storage_id(in_root)?).into()]);
}
self.define_data(&name, tuple, in_root)
}
@ -216,7 +212,6 @@ pub trait Environment<'t, T: AsRef<[u8]>> where Self: Sized {
match value {
v @ (Value::Null |
Value::Bool(_) |
Value::UInt(_) |
Value::Int(_) |
Value::Float(_) |
Value::Uuid(_) |
@ -562,7 +557,6 @@ pub trait Environment<'t, T: AsRef<[u8]>> where Self: Sized {
match cur_val {
Value::Null |
Value::Bool(_) |
Value::UInt(_) |
Value::Int(_) |
Value::Float(_) |
Value::Uuid(_) |
@ -623,7 +617,6 @@ pub trait Environment<'t, T: AsRef<[u8]>> where Self: Sized {
match cur_val {
Value::Null |
Value::Bool(_) |
Value::UInt(_) |
Value::Int(_) |
Value::Float(_) |
Value::Uuid(_) |
@ -664,86 +657,8 @@ pub trait Environment<'t, T: AsRef<[u8]>> where Self: Sized {
}
pub struct MemoryEnv<'a> {
root: BTreeMap<String, OwnTuple>,
stack: Vec<BTreeMap<String, OwnTuple>>,
params: BTreeMap<String, &'a str>,
max_storage_id: u32,
}
impl <'a> Default for MemoryEnv<'a> {
fn default() -> Self {
MemoryEnv { root: BTreeMap::default(), stack: vec![BTreeMap::default()], max_storage_id: 0, params: BTreeMap::default() }
}
}
impl <'t> Environment<'t, Vec<u8>> for MemoryEnv<'t> {
fn get_next_storage_id(&mut self, _in_root: bool) -> Result<u32> {
self.max_storage_id += 1;
Ok(self.max_storage_id)
}
fn get_stack_depth(&self) -> i32 {
-(self.stack.len() as i32)
}
fn push_env(&mut self) {
self.stack.push(BTreeMap::default());
}
fn pop_env(&mut self) -> Result<()> {
if self.stack.len() > 1 {
self.stack.pop();
}
Ok(())
}
fn set_param(&mut self, name: &str, val: &'t str) {
self.params.insert(name.to_string(), val);
}
fn resolve(&self, name: &str) -> Result<Option<OwnTuple>> {
for layer in self.stack.iter() {
if let Some(res) = layer.get(name) {
return Ok(Some(res.clone()));
}
}
Ok(self.root.get(name).cloned())
}
fn resolve_param(&self, name: &str) -> Result<Value> {
let text = self.params.get(name).ok_or_else(|| CozoError::UndefinedParam(name.to_string()))?;
let pair = Parser::parse(Rule::expr, text)?.next().unwrap();
Value::from_pair(pair)
}
fn delete_defined(&mut self, name: &str, in_root: bool) -> Result<()> {
if in_root {
self.root.remove(name);
} else {
for layer in self.stack.iter_mut().rev() {
if let Some(_) = layer.remove(name) {
return Ok(());
}
}
}
Ok(())
}
fn define_data(&mut self, name: &str, data: OwnTuple, in_root: bool) -> Result<()> {
if in_root {
self.root.insert(name.to_string(), data);
} else {
let last = self.stack.last_mut().unwrap();
last.insert(name.to_string(), data);
}
Ok(())
}
}
impl<'a, 't> Environment<'t, SlicePtr> for Session<'a, 't> {
fn get_next_storage_id(&mut self, in_root: bool) -> Result<u32> {
fn get_next_storage_id(&mut self, in_root: bool) -> Result<i64> {
// TODO: deal with wrapping problem
let mut key_entry = Tuple::with_null_prefix();
key_entry.push_null();
@ -753,20 +668,20 @@ impl<'a, 't> Environment<'t, SlicePtr> for Session<'a, 't> {
self.txn.get(false, &self.temp_cf, &key_entry)
};
let u = if let Some(en) = db_res? {
if let Value::UInt(u) = Tuple::new(en).get(0).unwrap() {
if let Value::Int(u) = Tuple::new(en).get(0).unwrap() {
u
} else {
panic!("Unexpected value in storage id");
}
} else { 0 };
let mut new_data = Tuple::with_null_prefix();
new_data.push_uint(u + 1);
new_data.push_int(u + 1);
if in_root {
self.txn.put(true, &self.perm_cf, key_entry, new_data)?;
} else {
self.txn.put(false, &self.temp_cf, key_entry, new_data)?;
}
Ok((u + 1) as u32)
Ok(u + 1)
}
fn get_stack_depth(&self) -> i32 {
@ -872,10 +787,11 @@ impl<'a, 't> Environment<'t, SlicePtr> for Session<'a, 't> {
#[cfg(test)]
mod tests {
use std::fs;
use super::*;
use crate::parser::{Parser, Rule};
use pest::Parser as PestParser;
use crate::db::eval::MemoryEnv;
use crate::db::engine::Engine;
#[test]
fn node() {
@ -897,32 +813,38 @@ mod tests {
email: Text
}
"#;
let mut env = MemoryEnv::default();
let mut parsed = Parser::parse(Rule::file, s).unwrap();
let t = parsed.next().unwrap();
env.run_definition(t).unwrap();
println!("{:?}", env.resolve("Person"));
let t = parsed.next().unwrap();
env.run_definition(t).unwrap();
println!("{:?}", env.resolve("Friend"));
let t = parsed.next().unwrap();
env.run_definition(t).unwrap();
println!("{:?}", env.resolve("XXY"));
let t = parsed.next().unwrap();
env.run_definition(t).unwrap();
println!("{:?}", env.resolve("WorkInfo"));
}
fn parse_expr_from_str(s: &str) -> (bool, Value) {
MemoryEnv::default().partial_eval(Value::from_pair(Parser::parse(Rule::expr, s).unwrap().next().unwrap()).unwrap()).unwrap()
// let mut env = MemoryEnv::default();
// let mut parsed = Parser::parse(Rule::file, s).unwrap();
//
// let t = parsed.next().unwrap();
// env.run_definition(t).unwrap();
// println!("{:?}", env.resolve("Person"));
//
// let t = parsed.next().unwrap();
// env.run_definition(t).unwrap();
// println!("{:?}", env.resolve("Friend"));
//
// let t = parsed.next().unwrap();
// env.run_definition(t).unwrap();
// println!("{:?}", env.resolve("XXY"));
//
// let t = parsed.next().unwrap();
// env.run_definition(t).unwrap();
// println!("{:?}", env.resolve("WorkInfo"));
// println!("{:?}", env.resolve("Person"));
}
#[test]
fn eval_expr() {
let db_path = "_test_db_expr_eval";
let engine = Engine::new(db_path.to_string(), true).unwrap();
let sess = engine.session().unwrap();
let parse_expr_from_str = |s: &str| -> (bool, Value) {
let (b, v) = sess.partial_eval(Value::from_pair(Parser::parse(Rule::expr, s).unwrap().next().unwrap()).unwrap()).unwrap();
(b, v.to_static())
};
assert_eq!((true, Value::from(1024.1)), parse_expr_from_str("1/10+(-2+3)*4^5"));
assert_eq!((true, Value::from(false)), parse_expr_from_str("true && false"));
assert_eq!((true, Value::from(true)), parse_expr_from_str("true || false"));
@ -931,6 +853,9 @@ mod tests {
assert_eq!((true, Value::Null), parse_expr_from_str("true && null"));
let ex = parse_expr_from_str("a + b - 1*2*3*100*c * d");
println!("{:?} {}", ex.0, ex.1);
drop(sess);
drop(engine);
fs::remove_dir_all(db_path).unwrap();
}
}

@ -36,7 +36,7 @@ impl<'a, 't> Session<'a, 't> {
println!("{:?}", default_kind);
println!("{:?}", filters);
let mut coercion_manager = TableCoercionManager::new(self, default_kind);
let mut mutation_manager = MutationManager::new(self, default_kind);
// Coercion
for item in expr {
@ -44,36 +44,21 @@ impl<'a, 't> Session<'a, 't> {
Value::Dict(d) => d,
_ => return Err(LogicError("Must be structs".to_string()))
};
coercion_manager.add(val_map)?;
// let explicit_tbl = val_map.get("_type");
// let tbl = match explicit_tbl {
// None => if let Some(v) = &default_kind {
// v as &str
// } else {
// return Err(LogicError("Cannot determine table kind".to_string()));
// }
// Some(v) => {
// match v {
// Value::Text(t) => t as &str,
// _ => return Err(LogicError("Cannot determine table kind".to_string()))
// }
// }
// };
// coercion_manager.coerce(tbl, val_map);
mutation_manager.add(val_map)?;
}
Ok(())
}
}
struct TableCoercionManager<'a, 'b, 't> {
struct MutationManager<'a, 'b, 't> {
sess: &'a Session<'b, 't>,
cache: BTreeMap<String, ()>,
categorized: BTreeMap<String, BTreeSet<OwnTuple>>,
default_tbl: Option<String>,
}
impl<'a, 'b, 't> TableCoercionManager<'a, 'b, 't> {
impl<'a, 'b, 't> MutationManager<'a, 'b, 't> {
fn new(sess: &'a Session<'b, 't>, default_tbl: Option<String>) -> Self {
Self { sess, cache: BTreeMap::new(), categorized: BTreeMap::new(), default_tbl }
}

@ -79,7 +79,7 @@ impl<T: AsRef<[u8]>> Tuple<T> {
let start = tag_start + 1;
let nxt = match Tag::try_from(data[tag_start]).unwrap() {
Tag::Null | Tag::BoolTrue | Tag::BoolFalse => start,
Tag::Int | Tag::UInt => start + self.parse_varint(start).1,
Tag::Int => start + self.parse_varint(start).1,
Tag::Float => start + 8,
Tag::Uuid => start + 16,
Tag::Text | Tag::Variable => {
@ -141,10 +141,6 @@ impl<T: AsRef<[u8]>> Tuple<T> {
Tag::Null => (start, ().into()),
Tag::BoolTrue => (start, true.into()),
Tag::BoolFalse => (start, false.into()),
Tag::UInt => {
let (u, offset) = self.parse_varint(start);
(start + offset, u.into())
}
Tag::Int => {
let (u, offset) = self.parse_varint(start);
let val = if u & 1 == 0 {
@ -324,12 +320,6 @@ impl OwnTuple {
self.idx_cache.borrow_mut().push(self.data.len());
}
#[inline]
pub fn push_uint(&mut self, u: u64) {
self.push_tag(Tag::UInt);
self.push_varint(u);
self.idx_cache.borrow_mut().push(self.data.len());
}
#[inline]
pub fn push_uuid(&mut self, u: Uuid) {
self.push_tag(Tag::Uuid);
self.data.extend(u.as_bytes());
@ -356,7 +346,6 @@ impl OwnTuple {
match v {
Value::Null => self.push_null(),
Value::Bool(b) => self.push_bool(*b),
Value::UInt(u) => self.push_uint(*u),
Value::Int(i) => self.push_int(*i),
Value::Float(f) => self.push_float(f.into_inner()),
Value::Uuid(u) => self.push_uuid(*u),
@ -441,6 +430,21 @@ impl OwnTuple {
let other_data_part = &other.as_ref()[4..];
self.data.extend_from_slice(other_data_part);
}
#[inline]
pub fn insert_values_at<'a, T: AsRef<[Value<'a>]>>(&self, idx: usize, values: T) -> Self {
let mut new_tuple = Tuple::with_prefix(self.get_prefix());
for v in self.iter().take(idx) {
new_tuple.push_value(&v);
}
for v in values.as_ref() {
new_tuple.push_value(v);
}
for v in self.iter().skip(idx) {
new_tuple.push_value(&v);
}
new_tuple
}
}
impl<'a> Extend<Value<'a>> for OwnTuple {
@ -489,7 +493,7 @@ mod tests {
].into());
t.push_int(-123345);
t.push_value(&BTreeMap::from([]).into());
t.push_uint(12121212);
t.push_int(12121212);
t.push_value(&BTreeMap::from([("yzyz".into(), "fifo".into())]).into());
t.push_float(1e245);
t.push_bool(false);
@ -529,7 +533,7 @@ mod tests {
assert_eq!(Value::from(BTreeMap::new()), t.get(8).unwrap());
t3.get_pos(9);
assert_eq!(t.idx_cache.borrow().last(), t3.idx_cache.borrow().last());
assert_eq!(Value::from(12121212u64), t.get(9).unwrap());
assert_eq!(Value::from(12121212i64), t.get(9).unwrap());
t3.get_pos(10);
assert_eq!(t.idx_cache.borrow().last(), t3.idx_cache.borrow().last());
assert_eq!(Value::from(BTreeMap::from([("yzyz".into(), "fifo".into())])), t.get(10).unwrap());
@ -551,7 +555,7 @@ mod tests {
assert_eq!(Value::from(false), t.get(12).unwrap());
assert_eq!(Value::from(()), t.get(0).unwrap());
assert_eq!(Value::from(false), t.get(2).unwrap());
assert_eq!(Value::from(12121212u64), t.get(9).unwrap());
assert_eq!(Value::from(12121212i64), t.get(9).unwrap());
assert_eq!(Value::from(BTreeMap::new()), t.get(8).unwrap());
assert_eq!(Value::Null, t.get(3).unwrap());
assert_eq!(Value::from("abcdef"), t.get(4).unwrap());

@ -6,7 +6,7 @@ use crate::relation::value::Value;
use pest::Parser as PestParser;
use cozorocks::SlicePtr;
use crate::db::engine::Session;
use crate::db::eval::{Environment, MemoryEnv};
use crate::db::eval::{Environment};
use crate::parser::Parser;
use crate::parser::Rule;
use crate::parser::text_identifier::build_name_in_def;
@ -21,7 +21,6 @@ pub enum Typing {
Float,
Text,
Uuid,
UInt,
Nullable(Box<Typing>),
Homogeneous(Box<Typing>),
UnnamedTuple(Vec<Typing>),
@ -37,7 +36,6 @@ impl Display for Typing {
Typing::Float => write!(f, "Float"),
Typing::Text => write!(f, "Text"),
Typing::Uuid => write!(f, "Uuid"),
Typing::UInt => write!(f, "UInt"),
Typing::Nullable(t) => write!(f, "?{}", t),
Typing::Homogeneous(h) => write!(f, "[{}]", h),
Typing::UnnamedTuple(u) => {
@ -76,7 +74,6 @@ impl Typing {
"Float" => Typing::Float,
"Text" => Typing::Text,
"Uuid" => Typing::Uuid,
"UInt" => Typing::UInt,
t => {
match env {
None => return Err(CozoError::UndefinedType(t.to_string())),
@ -118,7 +115,7 @@ impl TryFrom<&str> for Typing {
fn try_from(value: &str) -> Result<Self> {
let pair = Parser::parse(Rule::typing, value)?.next().unwrap();
Typing::from_pair::<Vec<u8>, MemoryEnv>(pair, None)
Typing::from_pair::<SlicePtr, Session>(pair, None)
}
}
@ -146,7 +143,7 @@ mod tests {
let res: Result<Typing> = "{xzzx : Text}".try_into();
println!("{:#?}", res);
assert!(res.is_ok());
let res: Result<Typing> = "?({x : Text, ppqp: ?UInt}, [Int], ?Uuid)".try_into();
let res: Result<Typing> = "?({x : Text, ppqp: ?Int}, [Int], ?Uuid)".try_into();
println!("{:#?}", res);
assert!(res.is_ok());
let res: Result<Typing> = "??Int".try_into();

@ -22,7 +22,6 @@ pub enum Tag {
Float = 5,
Text = 6,
Uuid = 7,
UInt = 8,
List = 128,
Dict = 129,
@ -45,7 +44,6 @@ impl TryFrom<u8> for Tag {
5 => Float,
6 => Text,
7 => Uuid,
8 => UInt,
128 => List,
129 => Dict,
253 => Variable,
@ -87,7 +85,6 @@ impl TryFrom<u8> for Tag {
pub enum Value<'a> {
Null,
Bool(bool),
UInt(u64),
Int(i64),
Float(OrderedFloat<f64>),
Uuid(Uuid),
@ -107,7 +104,6 @@ impl<'a> Value<'a> {
match self {
Value::Null => Value::from(()),
Value::Bool(b) => Value::from(b),
Value::UInt(u) => Value::from(u),
Value::Int(i) => Value::from(i),
Value::Float(f) => Value::from(f),
Value::Uuid(u) => Value::from(u),
@ -129,7 +125,6 @@ impl<'a> Value<'a> {
match self {
Value::Null |
Value::Bool(_) |
Value::UInt(_) |
Value::Int(_) |
Value::Float(_) |
Value::Uuid(_) |
@ -161,22 +156,6 @@ impl From<bool> for StaticValue {
}
}
impl From<u64> for StaticValue {
#[inline]
fn from(u: u64) -> Self {
Value::UInt(u)
}
}
impl From<u32> for StaticValue {
#[inline]
fn from(u: u32) -> Self {
Value::UInt(u as u64)
}
}
impl From<i64> for StaticValue {
#[inline]
fn from(i: i64) -> Self {
@ -247,10 +226,6 @@ impl<'a> Display for Value<'a> {
match self {
Value::Null => { f.write_str("null")?; }
Value::Bool(b) => { f.write_str(if *b { "true" } else { "false" })?; }
Value::UInt(u) => {
f.write_str(&u.to_string())?;
f.write_str("u")?;
}
Value::Int(i) => { f.write_str(&i.to_string())?; }
Value::Float(n) => { f.write_str(&format!("{:e}", n.into_inner()))?; }
Value::Uuid(u) => { f.write_str(&u.to_string())?; }

Loading…
Cancel
Save