Migrate to the newer datacell impl

next
Sayan Nandan 2 years ago
parent 5d9851a427
commit 8d789bd166
No known key found for this signature in database
GPG Key ID: 42EEDF4AE9D96B54

@ -35,6 +35,8 @@ use {
std::sync::Arc,
};
pub use model::cell::Datacell;
/// Use this for now since it substitutes for a file lock (and those syscalls are expensive),
/// but something better is in the offing
type RWLIdx<K, V> = RwLock<IndexST<K, V>>;

@ -29,7 +29,11 @@ use core::mem;
use {
crate::engine::{
self,
data::tag::TagClass,
data::{
lit::{Lit, LitIR},
spec::{Dataspec1D, DataspecMeta1D},
tag::{DataTag, TagClass},
},
mem::{NativeQword, SystemDword},
},
core::{fmt, mem::ManuallyDrop, slice, str},
@ -182,6 +186,51 @@ direct_from! {
}
}
impl<'a> From<LitIR<'a>> for Datacell {
fn from(l: LitIR<'a>) -> Self {
match l.kind().tag_class() {
tag if tag < TagClass::Bin => unsafe {
let [a, b] = l.data().load_fat();
Datacell::new(
l.kind().tag_class(),
DataRaw::word(SystemDword::store_fat(a, b)),
)
},
tag @ (TagClass::Bin | TagClass::Str) => unsafe {
let mut bin = ManuallyDrop::new(l.read_bin_uck().to_owned().into_boxed_slice());
Datacell::new(
tag,
DataRaw::word(SystemDword::store((bin.as_mut_ptr(), bin.len()))),
)
},
_ => unreachable!(),
}
}
}
#[cfg(test)]
impl From<i32> for Datacell {
fn from(i: i32) -> Self {
if i.is_negative() {
Self::new_sint(i as _)
} else {
Self::new_uint(i as _)
}
}
}
impl<'a> From<Lit<'a>> for Datacell {
fn from(l: Lit<'a>) -> Self {
Self::from(l.as_ir())
}
}
impl<const N: usize> From<[Datacell; N]> for Datacell {
fn from(l: [Datacell; N]) -> Self {
Self::new_list(l.into())
}
}
impl Datacell {
unsafe fn new(tag: TagClass, data: DataRaw) -> Self {
Self { tag, data }
@ -189,6 +238,9 @@ impl Datacell {
fn checked_tag<T>(&self, tag: TagClass, f: impl FnOnce() -> T) -> Option<T> {
(self.tag == tag).then_some(f())
}
pub fn kind(&self) -> TagClass {
self.tag
}
}
impl fmt::Debug for Datacell {

@ -24,7 +24,7 @@
*
*/
mod cell;
pub mod cell;
// FIXME(@ohsayan): update this!

@ -26,10 +26,10 @@
use crate::engine::{
core::{
model::cell::Datacell,
space::{Space, SpaceMeta},
GlobalNS,
},
data::HSData,
error::DatabaseError,
};
@ -45,7 +45,7 @@ fn alter_add_prop_env_var() {
space.unwrap(),
&Space::new(
into_dict!(),
SpaceMeta::with_env(into_dict! ("MY_NEW_PROP" => HSData::UnsignedInt(100)))
SpaceMeta::with_env(into_dict! ("MY_NEW_PROP" => Datacell::new_uint(100)))
)
)
},
@ -61,7 +61,7 @@ fn alter_update_prop_env_var() {
|space| {
assert_eq!(
space.unwrap().meta.env.read().get("MY_NEW_PROP").unwrap(),
&(HSData::UnsignedInt(100).into())
&(Datacell::new_uint(100).into())
)
},
);
@ -73,7 +73,7 @@ fn alter_update_prop_env_var() {
space.unwrap(),
&Space::new(
into_dict!(),
SpaceMeta::with_env(into_dict! ("MY_NEW_PROP" => HSData::UnsignedInt(200)))
SpaceMeta::with_env(into_dict! ("MY_NEW_PROP" => Datacell::new_uint(200)))
)
)
},
@ -89,7 +89,7 @@ fn alter_remove_prop_env_var() {
|space| {
assert_eq!(
space.unwrap().meta.env.read().get("MY_NEW_PROP").unwrap(),
&(HSData::UnsignedInt(100).into())
&(Datacell::new_uint(100).into())
)
},
);
@ -124,7 +124,7 @@ fn alter_remove_all_env() {
|space| {
assert_eq!(
space.unwrap().meta.env.read().get("MY_NEW_PROP").unwrap(),
&(HSData::UnsignedInt(100).into())
&(Datacell::new_uint(100).into())
)
},
);

@ -26,10 +26,10 @@
use crate::engine::{
core::{
model::cell::Datacell,
space::{Space, SpaceMeta},
GlobalNS,
},
data::HSData,
error::DatabaseError,
};
@ -57,7 +57,7 @@ fn exec_create_space_with_env() {
&Space::new(
into_dict! {},
SpaceMeta::with_env(into_dict! {
"MAX_MODELS" => HSData::UnsignedInt(100)
"MAX_MODELS" => Datacell::new_uint(100)
})
)
);

@ -26,10 +26,8 @@
use {
crate::engine::{
data::{
lit::{Lit, LitIR},
HSData,
},
core::Datacell,
data::lit::{Lit, LitIR},
idx::STIndex,
},
std::collections::HashMap,
@ -47,7 +45,7 @@ pub type DictGeneric = HashMap<Box<str>, Option<DictEntryGeneric>>;
#[derive(Debug, PartialEq)]
/// A generic dict entry: either a literal or a recursive dictionary
pub enum DictEntryGeneric {
Lit(HSData),
Lit(Datacell),
Map(DictGeneric),
}
@ -55,7 +53,7 @@ pub enum DictEntryGeneric {
#[cfg_attr(test, derive(Clone))]
/// A metadata dictionary
pub enum MetaDictEntry {
Data(HSData),
Data(Datacell),
Map(MetaDict),
}
@ -67,7 +65,7 @@ pub enum MetaDictEntry {
struct MetaDictPatch(HashMap<Box<str>, Option<MetaDictPatchEntry>>);
#[derive(Debug, PartialEq)]
enum MetaDictPatchEntry {
Data(HSData),
Data(Datacell),
Map(MetaDictPatch),
}
@ -208,26 +206,26 @@ fn rmerge_metadata_prepare_patch(
impl<'a> From<LitIR<'a>> for DictEntryGeneric {
fn from(l: LitIR<'a>) -> Self {
Self::Lit(HSData::from(l))
Self::Lit(Datacell::from(l))
}
}
impl<'a> From<Lit<'a>> for DictEntryGeneric {
fn from(value: Lit<'a>) -> Self {
Self::Lit(HSData::from(value))
Self::Lit(Datacell::from(value))
}
}
direct_from! {
DictEntryGeneric => {
HSData as Lit,
Datacell as Lit,
DictGeneric as Map,
}
}
direct_from! {
MetaDictEntry => {
HSData as Data,
Datacell as Data,
MetaDict as Map,
}
}

@ -33,132 +33,8 @@ pub mod tag;
#[cfg(test)]
mod tests;
use crate::engine::mem::AStr;
pub use md_dict::{DictEntryGeneric, DictGeneric, MetaDict};
use {
self::lit::Lit,
crate::engine::{data::lit::LitIR, mem::AStr},
std::mem::{self, Discriminant},
};
const IDENT_MX: usize = 64;
pub type ItemID = AStr<IDENT_MX>;
/// A [`DataType`] represents the underlying data-type, although this enumeration when used in a collection will always
/// be of one type.
// TODO(@ohsayan): Change the underlying structures, there are just rudimentary ones used during integration with the QL
#[derive(Debug, PartialEq)]
#[cfg_attr(test, derive(Clone))]
#[repr(u8)]
pub enum HSData {
/// An UTF-8 string
String(Box<str>) = DataKind::STR_BX.d(),
/// Bytes
Binary(Box<[u8]>) = DataKind::BIN_BX.d(),
/// An unsigned integer
///
/// **NOTE:** This is the default evaluated type for unsigned integers by the query processor. It is the
/// responsibility of the executor to ensure integrity checks depending on actual type width in the declared
/// schema (if any)
UnsignedInt(u64) = DataKind::UINT64.d(),
/// A signed integer
///
/// **NOTE:** This is the default evaluated type for signed integers by the query processor. It is the
/// responsibility of the executor to ensure integrity checks depending on actual type width in the declared
/// schema (if any)
SignedInt(i64) = DataKind::SINT64.d(),
/// A boolean
Boolean(bool) = DataKind::BOOL.d(),
/// A float (64-bit)
Float(f64) = DataKind::FLOAT64.d(),
/// A single-type list. Note, you **need** to keep up the invariant that the [`DataType`] disc. remains the same for all
/// elements to ensure correctness in this specific context
/// FIXME(@ohsayan): Try enforcing this somehow
List(Vec<Self>) = DataKind::LIST.d(),
}
direct_from! {
HSData => {
String as String,
Vec<u8> as Binary,
u64 as UnsignedInt,
bool as Boolean,
Vec<Self> as List,
&'static str as String,
}
}
impl HSData {
#[inline(always)]
pub(super) fn clone_from_lit(lit: Lit) -> Self {
match_data!(match lit {
Lit::Str(s) => HSData::String(s.to_string().into_boxed_str()),
Lit::Bool(b) => HSData::Boolean(b),
Lit::UnsignedInt(u) => HSData::UnsignedInt(u),
Lit::SignedInt(i) => HSData::SignedInt(i),
Lit::Float(f) => HSData::Float(f),
Lit::Bin(l) => HSData::Binary(l.to_vec().into_boxed_slice()),
TagClass::List(_) => unreachable!("found 2D data in 1D"),
})
}
#[inline(always)]
pub(super) fn clone_from_litir<'a>(lit: LitIR<'a>) -> Self {
match_data!(match lit {
LitIR::Str(s) => Self::String(s.to_owned().into_boxed_str()),
LitIR::Bin(b) => Self::Binary(b.to_owned().into_boxed_slice()),
LitIR::Float(f) => Self::Float(f),
LitIR::SignedInt(s) => Self::SignedInt(s),
LitIR::UnsignedInt(u) => Self::UnsignedInt(u),
LitIR::Bool(b) => Self::Boolean(b),
TagClass::List(_) => unreachable!("found 2D data in 1D"),
})
}
fn kind(&self) -> Discriminant<Self> {
mem::discriminant(&self)
}
}
impl<'a> From<Lit<'a>> for HSData {
fn from(l: Lit<'a>) -> Self {
Self::clone_from_lit(l)
}
}
impl<'a> From<LitIR<'a>> for HSData {
fn from(l: LitIR<'a>) -> Self {
Self::clone_from_litir(l)
}
}
impl<const N: usize> From<[HSData; N]> for HSData {
fn from(f: [HSData; N]) -> Self {
Self::List(f.into())
}
}
flags! {
#[derive(PartialEq, Eq, Clone, Copy)]
pub struct DataKind: u8 {
// primitive: integer unsigned
UINT8 = 0,
UINT16 = 1,
UINT32 = 2,
UINT64 = 3,
// primitive: integer unsigned
SINT8 = 4,
SINT16 = 5,
SINT32 = 6,
SINT64 = 7,
// primitive: misc
BOOL = 8,
// primitive: floating point
FLOAT32 = 9,
FLOAT64 = 10,
// compound: flat
STR = 11,
STR_BX = DataKind::_BASE_HB | DataKind::STR.d(),
BIN = 12,
BIN_BX = DataKind::_BASE_HB | DataKind::BIN.d(),
// compound: recursive
LIST = 13,
}
}

@ -24,19 +24,19 @@
*
*/
use crate::engine::data::{
md_dict::{self, DictEntryGeneric, DictGeneric, MetaDict, MetaDictEntry},
HSData,
use crate::engine::{
core::Datacell,
data::md_dict::{self, DictEntryGeneric, DictGeneric, MetaDict, MetaDictEntry},
};
#[test]
fn t_simple_flatten() {
let generic_dict: DictGeneric = into_dict! {
"a_valid_key" => Some(DictEntryGeneric::Lit(100.into())),
"a_valid_key" => Some(DictEntryGeneric::Lit(100u64.into())),
"a_null_key" => None,
};
let expected: MetaDict = into_dict!(
"a_valid_key" => HSData::UnsignedInt(100)
"a_valid_key" => Datacell::new_uint(100)
);
let ret = md_dict::rflatten_metadata(generic_dict);
assert_eq!(ret, expected);
@ -45,18 +45,18 @@ fn t_simple_flatten() {
#[test]
fn t_simple_patch() {
let mut current: MetaDict = into_dict! {
"a" => HSData::UnsignedInt(2),
"b" => HSData::UnsignedInt(3),
"z" => HSData::SignedInt(-100),
"a" => Datacell::new_uint(2),
"b" => Datacell::new_uint(3),
"z" => Datacell::new_sint(-100),
};
let new: DictGeneric = into_dict! {
"a" => Some(HSData::UnsignedInt(1).into()),
"b" => Some(HSData::UnsignedInt(2).into()),
"a" => Some(Datacell::new_uint(1).into()),
"b" => Some(Datacell::new_uint(2).into()),
"z" => None,
};
let expected: MetaDict = into_dict! {
"a" => HSData::UnsignedInt(1),
"b" => HSData::UnsignedInt(2),
"a" => Datacell::new_uint(1),
"b" => Datacell::new_uint(2),
};
assert!(md_dict::rmerge_metadata(&mut current, new));
assert_eq!(current, expected);
@ -65,15 +65,15 @@ fn t_simple_patch() {
#[test]
fn t_bad_patch() {
let mut current: MetaDict = into_dict! {
"a" => HSData::UnsignedInt(2),
"b" => HSData::UnsignedInt(3),
"z" => HSData::SignedInt(-100),
"a" => Datacell::new_uint(2),
"b" => Datacell::new_uint(3),
"z" => Datacell::new_sint(-100),
};
let backup = current.clone();
let new: DictGeneric = into_dict! {
"a" => Some(HSData::UnsignedInt(1).into()),
"b" => Some(HSData::UnsignedInt(2).into()),
"z" => Some(HSData::String("omg".into()).into()),
"a" => Some(Datacell::new_uint(1).into()),
"b" => Some(Datacell::new_uint(2).into()),
"z" => Some(Datacell::new_str("omg".into()).into()),
};
assert!(!md_dict::rmerge_metadata(&mut current, new));
assert_eq!(current, backup);
@ -82,20 +82,20 @@ fn t_bad_patch() {
#[test]
fn patch_null_out_dict() {
let mut current: MetaDict = into_dict! {
"a" => HSData::UnsignedInt(2),
"b" => HSData::UnsignedInt(3),
"a" => Datacell::new_uint(2),
"b" => Datacell::new_uint(3),
"z" => MetaDictEntry::Map(into_dict!(
"c" => HSData::UnsignedInt(1),
"d" => HSData::UnsignedInt(2)
"c" => Datacell::new_uint(1),
"d" => Datacell::new_uint(2)
)),
};
let expected: MetaDict = into_dict! {
"a" => HSData::UnsignedInt(2),
"b" => HSData::UnsignedInt(3),
"a" => Datacell::new_uint(2),
"b" => Datacell::new_uint(3),
};
let new: DictGeneric = into_dict! {
"a" => Some(HSData::UnsignedInt(2).into()),
"b" => Some(HSData::UnsignedInt(3).into()),
"a" => Some(Datacell::new_uint(2).into()),
"b" => Some(Datacell::new_uint(3).into()),
"z" => None,
};
assert!(md_dict::rmerge_metadata(&mut current, new));

@ -36,7 +36,8 @@ use {
},
crate::{
engine::{
data::{lit::LitIR, HSData},
core::Datacell,
data::lit::LitIR,
error::{LangError, LangResult},
},
util::{compiler, MaybeInit},
@ -238,7 +239,7 @@ impl<'a, Qd: QueryData<'a>> State<'a, Qd> {
///
/// Caller should have checked that the token matches a lit signature and that enough data is available
/// in the data source. (ideally should run `can_read_lit_from` or `can_read_lit_rounded`)
pub unsafe fn read_lit_into_data_type_unchecked_from(&mut self, tok: &'a Token) -> HSData {
pub unsafe fn read_lit_into_data_type_unchecked_from(&mut self, tok: &'a Token) -> Datacell {
self.d.read_data_type(tok)
}
#[inline(always)]
@ -280,7 +281,7 @@ pub trait QueryData<'a> {
///
/// ## Safety
/// The current token must match the signature of a lit
unsafe fn read_data_type(&mut self, tok: &'a Token) -> HSData;
unsafe fn read_data_type(&mut self, tok: &'a Token) -> Datacell;
/// Returns true if the data source has enough data
fn nonzero(&self) -> bool;
}
@ -304,8 +305,8 @@ impl<'a> QueryData<'a> for InplaceData {
extract!(tok, Token::Lit(l) => l.as_ir())
}
#[inline(always)]
unsafe fn read_data_type(&mut self, tok: &'a Token) -> HSData {
HSData::from(extract!(tok, Token::Lit(ref l) => l.to_owned()))
unsafe fn read_data_type(&mut self, tok: &'a Token) -> Datacell {
Datacell::from(extract!(tok, Token::Lit(ref l) => l.to_owned()))
}
#[inline(always)]
fn nonzero(&self) -> bool {
@ -337,11 +338,11 @@ impl<'a> QueryData<'a> for SubstitutedData<'a> {
ret
}
#[inline(always)]
unsafe fn read_data_type(&mut self, tok: &'a Token) -> HSData {
unsafe fn read_data_type(&mut self, tok: &'a Token) -> Datacell {
debug_assert!(Token![?].eq(tok));
let ret = self.data[0].clone();
self.data = &self.data[1..];
HSData::from(ret)
Datacell::from(ret)
}
#[inline(always)]
fn nonzero(&self) -> bool {

@ -28,7 +28,7 @@ use {
super::read_ident,
crate::{
engine::{
data::HSData,
core::Datacell,
error::{LangError, LangResult},
ql::{
ast::{Entity, QueryData, State},
@ -37,10 +37,7 @@ use {
},
util::{compiler, MaybeInit},
},
core::{
cmp,
mem::{discriminant, Discriminant},
},
core::cmp,
std::{
collections::HashMap,
time::{Duration, SystemTime, UNIX_EPOCH},
@ -56,7 +53,7 @@ pub const T_UUIDSTR: &str = "4593264b-0231-43e9-b0aa-50784f14e204";
pub const T_UUIDBIN: &[u8] = T_UUIDSTR.as_bytes();
pub const T_TIMESEC: u64 = 1673187839_u64;
type ProducerFn = fn() -> HSData;
type ProducerFn = fn() -> Datacell;
// base
#[inline(always)]
@ -77,16 +74,16 @@ fn pfnbase_uuid() -> Uuid {
}
// impl
#[inline(always)]
fn pfn_timesec() -> HSData {
HSData::UnsignedInt(pfnbase_time().as_secs())
fn pfn_timesec() -> Datacell {
Datacell::new_uint(pfnbase_time().as_secs())
}
#[inline(always)]
fn pfn_uuidstr() -> HSData {
HSData::String(pfnbase_uuid().to_string().into_boxed_str())
fn pfn_uuidstr() -> Datacell {
Datacell::new_str(pfnbase_uuid().to_string().into_boxed_str())
}
#[inline(always)]
fn pfn_uuidbin() -> HSData {
HSData::Binary(pfnbase_uuid().as_bytes().to_vec().into_boxed_slice())
fn pfn_uuidbin() -> Datacell {
Datacell::new_bin(pfnbase_uuid().as_bytes().to_vec().into_boxed_slice())
}
static PRODUCER_G: [u8; 4] = [0, 2, 3, 0];
@ -141,8 +138,8 @@ unsafe fn ldfunc_unchecked(func: &[u8]) -> ProducerFn {
/// - If tt length is less than 1
pub(super) fn parse_list<'a, Qd: QueryData<'a>>(
state: &mut State<'a, Qd>,
list: &mut Vec<HSData>,
) -> Option<Discriminant<HSData>> {
list: &mut Vec<Datacell>,
) -> Option<TagClass> {
let mut stop = state.cursor_eq(Token![close []]);
state.cursor_ahead_if(stop);
let mut overall_dscr = None;
@ -169,7 +166,7 @@ pub(super) fn parse_list<'a, Qd: QueryData<'a>>(
if prev_nlist_dscr.is_none() && nlist_dscr.is_some() {
prev_nlist_dscr = nlist_dscr;
}
HSData::List(nested_list)
Datacell::new_list(nested_list)
}
Token![@] if state.cursor_signature_match_fn_arity0_rounded() => match unsafe {
// UNSAFE(@ohsayan): Just verified at guard
@ -187,8 +184,8 @@ pub(super) fn parse_list<'a, Qd: QueryData<'a>>(
break;
}
};
state.poison_if_not(list.is_empty() || discriminant(&d) == discriminant(&list[0]));
overall_dscr = Some(discriminant(&d));
state.poison_if_not(list.is_empty() || d.kind() == list[0].kind());
overall_dscr = Some(d.kind());
list.push(d);
let nx_comma = state.cursor_rounded_eq(Token![,]);
let nx_csqrb = state.cursor_rounded_eq(Token![close []]);
@ -202,7 +199,7 @@ pub(super) fn parse_list<'a, Qd: QueryData<'a>>(
#[inline(always)]
/// ## Safety
/// - Cursor must match arity(0) function signature
unsafe fn handle_func_sub<'a, Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> Option<HSData> {
unsafe fn handle_func_sub<'a, Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> Option<Datacell> {
let func = read_ident(state.fw_read());
state.cursor_ahead_by(2); // skip tt:paren
ldfunc(func).map(move |f| f())
@ -212,7 +209,7 @@ unsafe fn handle_func_sub<'a, Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> O
/// - If tt is empty
pub(super) fn parse_data_tuple_syntax<'a, Qd: QueryData<'a>>(
state: &mut State<'a, Qd>,
) -> Vec<Option<HSData>> {
) -> Vec<Option<Datacell>> {
let mut stop = state.cursor_eq(Token![() close]);
state.cursor_ahead_if(stop);
let mut data = Vec::new();
@ -259,7 +256,7 @@ pub(super) fn parse_data_tuple_syntax<'a, Qd: QueryData<'a>>(
/// Panics if tt is empty
pub(super) fn parse_data_map_syntax<'a, Qd: QueryData<'a>>(
state: &mut State<'a, Qd>,
) -> HashMap<Ident<'a>, Option<HSData>> {
) -> HashMap<Ident<'a>, Option<Datacell>> {
let mut stop = state.cursor_eq(Token![close {}]);
state.cursor_ahead_if(stop);
let mut data = HashMap::with_capacity(2);
@ -313,18 +310,18 @@ pub(super) fn parse_data_map_syntax<'a, Qd: QueryData<'a>>(
#[derive(Debug, PartialEq)]
pub enum InsertData<'a> {
Ordered(Vec<Option<HSData>>),
Map(HashMap<Ident<'a>, Option<HSData>>),
Ordered(Vec<Option<Datacell>>),
Map(HashMap<Ident<'a>, Option<Datacell>>),
}
impl<'a> From<Vec<Option<HSData>>> for InsertData<'a> {
fn from(v: Vec<Option<HSData>>) -> Self {
impl<'a> From<Vec<Option<Datacell>>> for InsertData<'a> {
fn from(v: Vec<Option<Datacell>>) -> Self {
Self::Ordered(v)
}
}
impl<'a> From<HashMap<Ident<'static>, Option<HSData>>> for InsertData<'a> {
fn from(m: HashMap<Ident<'static>, Option<HSData>>) -> Self {
impl<'a> From<HashMap<Ident<'static>, Option<Datacell>>> for InsertData<'a> {
fn from(m: HashMap<Ident<'static>, Option<Datacell>>) -> Self {
Self::Map(m)
}
}
@ -392,6 +389,8 @@ impl<'a> InsertStatement<'a> {
#[cfg(test)]
pub use impls::test::{DataMap, DataTuple, List};
use crate::engine::data::tag::TagClass;
mod impls {
use {
super::InsertStatement,
@ -409,7 +408,7 @@ mod impls {
pub mod test {
use {
super::super::{
parse_data_map_syntax, parse_data_tuple_syntax, parse_list, HSData, HashMap,
parse_data_map_syntax, parse_data_tuple_syntax, parse_list, Datacell, HashMap,
},
crate::engine::{
error::LangResult,
@ -417,7 +416,7 @@ mod impls {
},
};
#[derive(sky_macros::Wrapper, Debug)]
pub struct List(Vec<HSData>);
pub struct List(Vec<Datacell>);
impl<'a> ASTNode<'a> for List {
// important: upstream must verify this
const VERIFY: bool = true;
@ -428,7 +427,7 @@ mod impls {
}
}
#[derive(sky_macros::Wrapper, Debug)]
pub struct DataTuple(Vec<Option<HSData>>);
pub struct DataTuple(Vec<Option<Datacell>>);
impl<'a> ASTNode<'a> for DataTuple {
// important: upstream must verify this
const VERIFY: bool = true;
@ -438,7 +437,7 @@ mod impls {
}
}
#[derive(sky_macros::Wrapper, Debug)]
pub struct DataMap(HashMap<Box<str>, Option<HSData>>);
pub struct DataMap(HashMap<Box<str>, Option<Datacell>>);
impl<'a> ASTNode<'a> for DataMap {
// important: upstream must verify this
const VERIFY: bool = true;

@ -27,7 +27,7 @@
use {
super::lex::{InsecureLexer, SafeLexer, Symbol, Token},
crate::{
engine::{data::HSData, error::LexResult},
engine::{core::Datacell, error::LexResult},
util::test_utils,
},
rand::{self, Rng},
@ -54,24 +54,24 @@ pub trait NullableData<T> {
fn data(self) -> Option<T>;
}
impl<T> NullableData<HSData> for T
impl<T> NullableData<Datacell> for T
where
T: Into<HSData>,
T: Into<Datacell>,
{
fn data(self) -> Option<HSData> {
fn data(self) -> Option<Datacell> {
Some(self.into())
}
}
struct Null;
impl NullableData<HSData> for Null {
fn data(self) -> Option<HSData> {
impl NullableData<Datacell> for Null {
fn data(self) -> Option<Datacell> {
None
}
}
fn nullable_datatype(v: impl NullableData<HSData>) -> Option<HSData> {
fn nullable_datatype(v: impl NullableData<Datacell>) -> Option<Datacell> {
v.data()
}

@ -436,9 +436,16 @@ mod stmt_insert {
let r = parse_ast_node_full::<InsertStatement>(&x[1..]).unwrap();
let e = InsertStatement::new(
Entity::Full(Ident::from("twitter"), Ident::from("users")),
into_array_nullable!["sayan", "Sayan", "sayan@example.com", true, 12345, 67890]
.to_vec()
.into(),
into_array_nullable![
"sayan",
"Sayan",
"sayan@example.com",
true,
12345,
67890
]
.to_vec()
.into(),
);
assert_eq!(e, r);
}

Loading…
Cancel
Save