main
Ziyang Hu 2 years ago
parent 8ed1d1ab02
commit dd39abffc2

@ -217,9 +217,6 @@ impl AttributeIndex {
pub(crate) fn is_unique_index(&self) -> bool { pub(crate) fn is_unique_index(&self) -> bool {
matches!(self, AttributeIndex::Identity | AttributeIndex::Unique) matches!(self, AttributeIndex::Identity | AttributeIndex::Unique)
} }
pub(crate) fn is_non_unique_index(&self) -> bool {
*self == AttributeIndex::Indexed
}
pub(crate) fn should_index(&self) -> bool { pub(crate) fn should_index(&self) -> bool {
*self != AttributeIndex::None *self != AttributeIndex::None
} }
@ -285,11 +282,6 @@ impl Attribute {
self.serialize(&mut Serializer::new(&mut inner)).unwrap(); self.serialize(&mut Serializer::new(&mut inner)).unwrap();
EncodedVec { inner } EncodedVec { inner }
} }
pub(crate) fn encode(&self) -> EncodedVec<ATTR_VEC_SIZE> {
let mut inner = SmallVec::<[u8; ATTR_VEC_SIZE]>::new();
self.serialize(&mut Serializer::new(&mut inner)).unwrap();
EncodedVec { inner }
}
pub(crate) fn decode(data: &[u8]) -> Result<Self> { pub(crate) fn decode(data: &[u8]) -> Result<Self> {
Ok(rmp_serde::from_slice(data)?) Ok(rmp_serde::from_slice(data)?)
} }

@ -3,8 +3,8 @@ use std::time::{SystemTime, UNIX_EPOCH};
use chrono::{DateTime, TimeZone, Utc}; use chrono::{DateTime, TimeZone, Utc};
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use crate::data::json::JsonValue;
use crate::data::json::JsonValue;
use crate::data::triple::StoreOp; use crate::data::triple::StoreOp;
#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Deserialize, Serialize, Hash)] #[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Deserialize, Serialize, Hash)]
@ -88,7 +88,6 @@ impl Debug for Validity {
pub struct EntityId(pub u64); pub struct EntityId(pub u64);
impl EntityId { impl EntityId {
pub(crate) const MAX_SYS: EntityId = EntityId(1000);
pub(crate) const MAX_TEMP: EntityId = EntityId(10_000_000); pub(crate) const MAX_TEMP: EntityId = EntityId(10_000_000);
pub const MIN_PERM: EntityId = EntityId(10_000_001); pub const MIN_PERM: EntityId = EntityId(10_000_001);
pub const MAX_PERM: EntityId = EntityId(0x00ff_ffff_ff00_0000); pub const MAX_PERM: EntityId = EntityId(0x00ff_ffff_ff00_0000);
@ -122,7 +121,6 @@ impl Debug for EntityId {
pub struct AttrId(pub u64); pub struct AttrId(pub u64);
impl AttrId { impl AttrId {
pub(crate) const MAX_SYS: AttrId = AttrId(1000);
pub(crate) const MAX_TEMP: AttrId = AttrId(10_000_000); pub(crate) const MAX_TEMP: AttrId = AttrId(10_000_000);
pub(crate) const MIN_PERM: AttrId = AttrId(10_000_001); pub(crate) const MIN_PERM: AttrId = AttrId(10_000_001);
pub(crate) const MAX_PERM: AttrId = AttrId(0x00ff_ffff_ff00_0000); pub(crate) const MAX_PERM: AttrId = AttrId(0x00ff_ffff_ff00_0000);
@ -157,10 +155,7 @@ impl Debug for AttrId {
pub struct TxId(pub u64); pub struct TxId(pub u64);
impl TxId { impl TxId {
pub(crate) const ZERO: TxId = TxId(0);
pub(crate) const NO_HISTORY: TxId = TxId(1000);
pub(crate) const MAX_SYS: TxId = TxId(10000); pub(crate) const MAX_SYS: TxId = TxId(10000);
pub(crate) const MIN_USER: TxId = TxId(10001);
pub(crate) const MAX_USER: TxId = TxId(0x00ff_ffff_ffff_ffff); pub(crate) const MAX_USER: TxId = TxId(0x00ff_ffff_ffff_ffff);
pub(crate) fn from_bytes(b: &[u8]) -> Self { pub(crate) fn from_bytes(b: &[u8]) -> Self {

@ -93,12 +93,6 @@ impl<'a> Value<'a> {
ret.into() ret.into()
} }
pub(crate) fn encode(&self) -> EncodedVec<INLINE_VAL_SIZE_LIMIT> {
let mut ret = SmallVec::<[u8; INLINE_VAL_SIZE_LIMIT]>::new();
self.serialize(&mut Serializer::new(&mut ret)).unwrap();
ret.into()
}
pub(crate) fn get_entity_id(&self) -> Result<EntityId, ValueError> { pub(crate) fn get_entity_id(&self) -> Result<EntityId, ValueError> {
match self { match self {
Value::EnId(id) => Ok(*id), Value::EnId(id) => Ok(*id),

@ -31,7 +31,7 @@ impl AttrTxItem {
req.clone(), req.clone(),
"'attrs' cannot be empty".to_string(), "'attrs' cannot be empty".to_string(),
) )
.into()); .into());
} }
let res = items.iter().map(AttrTxItem::try_from).try_collect()?; let res = items.iter().map(AttrTxItem::try_from).try_collect()?;
Ok((res, comment)) Ok((res, comment))
@ -56,7 +56,7 @@ impl TryFrom<&'_ JsonValue> for AttrTxItem {
value.clone(), value.clone(),
"object must have exactly one field".to_string(), "object must have exactly one field".to_string(),
) )
.into()); .into());
} }
let (k, v) = map.into_iter().next().unwrap(); let (k, v) = map.into_iter().next().unwrap();
let op = match k as &str { let op = match k as &str {

@ -21,10 +21,13 @@ pub enum PullError {
impl SessionTx { impl SessionTx {
pub(crate) fn parse_pull(&mut self, desc: &JsonValue, depth: usize) -> Result<PullSpecs> { pub(crate) fn parse_pull(&mut self, desc: &JsonValue, depth: usize) -> Result<PullSpecs> {
if let Some(inner) = desc.as_array() { if let Some(inner) = desc.as_array() {
inner let mut ret: PullSpecs = inner
.iter() .iter()
.map(|v| self.parse_pull_element(v, depth)) .map(|v| self.parse_pull_element(v, depth))
.try_collect() .try_collect()?;
// the sort is necessary to put recursive queries last
ret.sort();
Ok(ret)
} else { } else {
Err(PullError::InvalidFormat(desc.clone(), "expect array".to_string()).into()) Err(PullError::InvalidFormat(desc.clone(), "expect array".to_string()).into())
} }
@ -123,7 +126,7 @@ impl SessionTx {
JsonValue::Object(desc.clone()), JsonValue::Object(desc.clone()),
"expect boolean or number".to_string(), "expect boolean or number".to_string(),
) )
.into()); .into());
} }
recursive = true; recursive = true;
} }
@ -141,7 +144,7 @@ impl SessionTx {
JsonValue::Object(desc.clone()), JsonValue::Object(desc.clone()),
"expect array".to_string(), "expect array".to_string(),
) )
.into()); .into());
} }
}; };
} }
@ -150,7 +153,7 @@ impl SessionTx {
v.into(), v.into(),
"unexpected spec key".to_string(), "unexpected spec key".to_string(),
) )
.into()) .into());
} }
} }
} }
@ -166,7 +169,7 @@ impl SessionTx {
JsonValue::Object(desc.clone()), JsonValue::Object(desc.clone()),
"expect target key".to_string(), "expect target key".to_string(),
) )
.into()); .into());
} }
let input_kw = input_kw.unwrap(); let input_kw = input_kw.unwrap();

@ -179,7 +179,7 @@ impl SessionTx {
JsonValue::Object(item.clone()), JsonValue::Object(item.clone()),
"expect any of the keys 'put', 'retract', 'erase', 'ensure'".to_string(), "expect any of the keys 'put', 'retract', 'erase', 'ensure'".to_string(),
) )
.into()); .into());
} }
}; };
let since = match item.get("since") { let since = match item.get("since") {
@ -229,7 +229,7 @@ impl SessionTx {
action, action,
"using temp id instead of perm id".to_string(), "using temp id instead of perm id".to_string(),
) )
.into()); .into());
} }
let v = if let JsonValue::Object(inner) = value { let v = if let JsonValue::Object(inner) = value {
@ -264,7 +264,7 @@ impl SessionTx {
action, action,
"component shorthand cannot be used".to_string(), "component shorthand cannot be used".to_string(),
) )
.into()); .into());
} }
let (eid, has_unique_attr) = let (eid, has_unique_attr) =
self.parse_tx_request_obj(comp, true, action, since, temp_id_ctx, collected)?; self.parse_tx_request_obj(comp, true, action, since, temp_id_ctx, collected)?;
@ -289,7 +289,7 @@ impl SessionTx {
action, action,
"singlet only allowed for 'retract'".to_string(), "singlet only allowed for 'retract'".to_string(),
) )
.into()); .into());
} }
let eid = eid.as_u64().ok_or_else(|| { let eid = eid.as_u64().ok_or_else(|| {
TxError::Decoding(eid.clone(), "cannot parse as entity id".to_string()) TxError::Decoding(eid.clone(), "cannot parse as entity id".to_string())
@ -317,7 +317,7 @@ impl SessionTx {
action, action,
"doublet only allowed for 'retract'".to_string(), "doublet only allowed for 'retract'".to_string(),
) )
.into()); .into());
} }
let kw: Keyword = attr.try_into()?; let kw: Keyword = attr.try_into()?;
let attr = self.attr_by_kw(&kw)?.ok_or(TxError::AttrNotFound(kw))?; let attr = self.attr_by_kw(&kw)?.ok_or(TxError::AttrNotFound(kw))?;
@ -399,7 +399,7 @@ impl SessionTx {
id.0, id.0,
"conflicting id for identity value".into(), "conflicting id for identity value".into(),
) )
.into()); .into());
} }
id id
} else if eid.is_string() { } else if eid.is_string() {
@ -407,7 +407,7 @@ impl SessionTx {
existing_id.0, existing_id.0,
"specifying temp_id string together with unique constraint".into(), "specifying temp_id string together with unique constraint".into(),
) )
.into()); .into());
} else { } else {
existing_id existing_id
} }
@ -479,7 +479,7 @@ impl SessionTx {
existing_eid.0, existing_eid.0,
"conflicting entity id given".to_string(), "conflicting entity id given".to_string(),
) )
.into()); .into());
} }
} }
eid = Some(existing_eid) eid = Some(existing_eid)
@ -502,7 +502,7 @@ impl SessionTx {
given_id.0, given_id.0,
"temp id given where perm id is required".to_string(), "temp id given where perm id is required".to_string(),
) )
.into()); .into());
} }
if let Some(prev_id) = eid { if let Some(prev_id) = eid {
if prev_id != given_id { if prev_id != given_id {
@ -510,7 +510,7 @@ impl SessionTx {
given_id.0, given_id.0,
"conflicting entity id given".to_string(), "conflicting entity id given".to_string(),
) )
.into()); .into());
} }
} }
eid = Some(given_id); eid = Some(given_id);
@ -521,7 +521,7 @@ impl SessionTx {
eid_inner.0, eid_inner.0,
"conflicting entity id given".to_string(), "conflicting entity id given".to_string(),
) )
.into()); .into());
} }
let temp_id_str = temp_id.as_str().ok_or_else(|| { let temp_id_str = temp_id.as_str().ok_or_else(|| {
TxError::Decoding( TxError::Decoding(
@ -544,7 +544,7 @@ impl SessionTx {
action, action,
"upsert requires identity attribute present".to_string(), "upsert requires identity attribute present".to_string(),
) )
.into()); .into());
} }
for (attr, v) in pairs { for (attr, v) in pairs {
self.parse_tx_request_inner(eid, &attr, v, action, since, temp_id_ctx, collected)?; self.parse_tx_request_inner(eid, &attr, v, action, since, temp_id_ctx, collected)?;
@ -560,23 +560,10 @@ impl SessionTx {
action, action,
"cannot use non-unique fields to specify entity".to_string(), "cannot use non-unique fields to specify entity".to_string(),
) )
.into()); .into());
} }
} }
} }
Ok((eid, has_unique_attr)) Ok((eid, has_unique_attr))
} }
} }
fn assert_absence_of_keys(m: &Map<String, JsonValue>, keys: &[&str]) -> Result<()> {
for k in keys {
if m.contains_key(*k) {
return Err(TxError::Decoding(
JsonValue::Object(m.clone()),
format!("object must not contain key {}", k),
)
.into());
}
}
Ok(())
}

@ -1,7 +1,7 @@
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::fmt::{Debug, Formatter}; use std::fmt::{Debug, Formatter};
use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering};
use std::sync::Arc; use std::sync::Arc;
use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering};
use anyhow::Result; use anyhow::Result;
use itertools::Itertools; use itertools::Itertools;
@ -9,7 +9,8 @@ use serde_json::json;
use cozorocks::{DbBuilder, DbIter, RocksDb}; use cozorocks::{DbBuilder, DbIter, RocksDb};
use crate::data::compare::{rusty_cmp, DB_KEY_PREFIX_LEN}; use crate::AttrTxItem;
use crate::data::compare::{DB_KEY_PREFIX_LEN, rusty_cmp};
use crate::data::encode::{ use crate::data::encode::{
decode_ea_key, decode_value_from_key, decode_value_from_val, encode_eav_key, StorageTag, decode_ea_key, decode_value_from_key, decode_value_from_val, encode_eav_key, StorageTag,
}; };
@ -19,7 +20,6 @@ use crate::data::triple::StoreOp;
use crate::data::value::Value; use crate::data::value::Value;
use crate::runtime::transact::SessionTx; use crate::runtime::transact::SessionTx;
use crate::transact::pull::CurrentPath; use crate::transact::pull::CurrentPath;
use crate::AttrTxItem;
pub struct Db { pub struct Db {
db: RocksDb, db: RocksDb,
@ -132,7 +132,7 @@ impl Db {
spec, spec,
0, 0,
&specs, &specs,
CurrentPath::new(idx), CurrentPath::new(idx)?,
&mut collected, &mut collected,
&mut recursive_seen, &mut recursive_seen,
)?; )?;

@ -17,7 +17,7 @@ use crate::runtime::transact::SessionTx;
pub(crate) type PullSpecs = Vec<PullSpec>; pub(crate) type PullSpecs = Vec<PullSpec>;
#[derive(Debug, Clone)] #[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
pub(crate) enum PullSpec { pub(crate) enum PullSpec {
PullAll, PullAll,
PullId(Keyword), PullId(Keyword),
@ -33,40 +33,40 @@ impl PullSpec {
} }
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
pub(crate) struct AttrPullSpec { pub(crate) struct AttrPullSpec {
pub(crate) recursive: bool,
pub(crate) reverse: bool,
pub(crate) attr: Attribute, pub(crate) attr: Attribute,
pub(crate) default_val: StaticValue, pub(crate) default_val: StaticValue,
pub(crate) reverse: bool,
pub(crate) name: Keyword, pub(crate) name: Keyword,
pub(crate) cardinality: AttributeCardinality, pub(crate) cardinality: AttributeCardinality,
pub(crate) take: Option<usize>, pub(crate) take: Option<usize>,
pub(crate) nested: PullSpecs, pub(crate) nested: PullSpecs,
pub(crate) recursive: bool,
pub(crate) recursion_limit: Option<usize>, pub(crate) recursion_limit: Option<usize>,
pub(crate) recursion_depth: usize, pub(crate) recursion_depth: usize,
} }
#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Debug)] #[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
pub(crate) struct CurrentPath(SmallVec<[usize; 8]>); pub(crate) struct CurrentPath(SmallVec<[u16; 8]>);
impl CurrentPath { impl CurrentPath {
pub(crate) fn new(idx: usize) -> Self { pub(crate) fn new(idx: usize) -> Result<Self> {
Self(smallvec![idx]) Ok(Self(smallvec![idx.try_into()?]))
} }
fn get_from_root<'a>(&self, depth: usize, root: &'a PullSpecs) -> &'a PullSpecs { fn get_from_root<'a>(&self, depth: usize, root: &'a PullSpecs) -> &'a PullSpecs {
let mut current = root; let mut current = root;
let indices = &self.0[..self.0.len() - depth]; let indices = &self.0[..self.0.len() - depth];
for i in indices { for i in indices {
current = &current[*i].as_attr_spec().unwrap().nested; current = &current[*i as usize].as_attr_spec().unwrap().nested;
} }
current current
} }
fn push(&self, idx: usize) -> Self { fn push(&self, idx: usize) -> Result<Self> {
let mut ret = CurrentPath(Default::default()); let mut ret = CurrentPath(Default::default());
ret.0.clone_from(&self.0); ret.0.clone_from(&self.0);
ret.0.push(idx); ret.0.push(idx.try_into()?);
ret Ok(ret)
} }
fn recurse_pop(&self, depth: usize) -> Self { fn recurse_pop(&self, depth: usize) -> Self {
Self(self.0[..self.0.len() + 1 - depth].to_smallvec()) Self(self.0[..self.0.len() + 1 - depth].to_smallvec())
@ -255,7 +255,7 @@ impl SessionTx {
sub_spec, sub_spec,
depth, depth,
root, root,
path.push(idx), path.push(idx)?,
&mut sub_collector, &mut sub_collector,
recursive_seen, recursive_seen,
)?; )?;
@ -334,7 +334,7 @@ impl SessionTx {
sub_spec, sub_spec,
depth, depth,
root, root,
path.push(idx), path.push(idx)?,
&mut sub_collector, &mut sub_collector,
recursive_seen, recursive_seen,
)?; )?;

@ -24,8 +24,6 @@ use crate::utils::swap_option_result;
enum TripleError { enum TripleError {
#[error("use of temp entity id: {0:?}")] #[error("use of temp entity id: {0:?}")]
TempEid(EntityId), TempEid(EntityId),
#[error("use of non-existent entity: {0:?}")]
EidNotFound(EntityId),
#[error("unique constraint violated: {0} {1}")] #[error("unique constraint violated: {0} {1}")]
UniqueConstraintViolated(Keyword, String), UniqueConstraintViolated(Keyword, String),
#[error("triple not found for {0:?} {1:?} {2:?}")] #[error("triple not found for {0:?} {1:?} {2:?}")]

Loading…
Cancel
Save