Enable fpath on nullable data

next
Sayan Nandan 2 years ago
parent 188f9ecbb4
commit a88319b8b9
No known key found for this signature in database
GPG Key ID: 42EEDF4AE9D96B54

@ -74,13 +74,16 @@ static LUT: [(&str, FullTag); 14] = [
];
#[derive(Debug, PartialEq, Clone)]
pub struct LayerView(VInline<1, Layer>);
pub struct LayerView {
layers: VInline<1, Layer>,
nullable: bool,
}
impl LayerView {
pub fn layers(&self) -> &[Layer] {
&self.0
&self.layers
}
pub fn parse_layers(spec: Vec<LayerSpec>) -> DatabaseResult<Self> {
pub fn parse_layers(spec: Vec<LayerSpec>, nullable: bool) -> DatabaseResult<Self> {
let mut layers = spec.into_iter().rev();
let mut okay = true;
let mut fin = false;
@ -98,17 +101,29 @@ impl LayerView {
}
okay &= fin & (layers.len() == 0);
if okay {
Ok(Self(layerview))
Ok(Self {
layers: layerview,
nullable,
})
} else {
Err(DatabaseError::DdlModelInvalidTypeDefinition)
}
}
#[inline(always)]
fn single_pass_for(&self, dc: &Datacell) -> bool {
((self.layers().len() == 1) & (self.layers()[0].tag.tag_class() == dc.kind()))
| (self.nullable & dc.is_null())
}
#[inline(always)]
fn compute_index(&self, dc: &Datacell) -> usize {
// escape check if it makes sense to
!(self.nullable & dc.is_null()) as usize * self.layers()[0].tag.tag_class().word()
}
pub fn validate_data_fpath(&self, data: &Datacell) -> bool {
if (self.layers().len() == 1) & (self.layers()[0].tag.tag_class() == data.kind()) {
// if someone sends a PR with an added check, I'll come home and throw a brick on your head
// if someone sends a PR with an added check, I'll personally come to your house and throw a brick on your head
if self.single_pass_for(data) {
layertrace("fpath");
let l = self.layers()[0];
unsafe { LVERIFY[l.tag.tag_class().word()](l, data) }
unsafe { LVERIFY[self.compute_index(data)](self.layers()[0], data) }
} else {
Self::rverify_layers(self.layers(), data)
}
@ -188,6 +203,10 @@ impl Layer {
}
impl Layer {
#[inline(always)]
fn compute_index(&self, dc: &Datacell) -> usize {
self.tag.tag_class().word() * (dc.is_null() as usize)
}
const fn new(tag: FullTag, config: [usize; 2]) -> Self {
Self { tag, config }
}
@ -228,7 +247,7 @@ static LVERIFY: [unsafe fn(Layer, &Datacell) -> bool; 7] = [
#[cfg(test)]
thread_local! {
pub static LAYER_TRACE: RefCell<Vec<Box<str>>> = RefCell::new(Vec::new());
static LAYER_TRACE: RefCell<Vec<Box<str>>> = RefCell::new(Vec::new());
}
#[inline(always)]

@ -30,10 +30,13 @@ use crate::engine::{
ql::{ast::parse_ast_node_multiple_full, tests::lex_insecure},
};
fn layerview(layer_def: &str) -> DatabaseResult<LayerView> {
fn layerview_nullable(layer_def: &str, nullable: bool) -> DatabaseResult<LayerView> {
let tok = lex_insecure(layer_def.as_bytes()).unwrap();
let spec = parse_ast_node_multiple_full(&tok).unwrap();
LayerView::parse_layers(spec)
LayerView::parse_layers(spec, nullable)
}
fn layerview(layer_def: &str) -> DatabaseResult<LayerView> {
layerview_nullable(layer_def, false)
}
mod layer_spec_validation {
@ -76,7 +79,7 @@ mod layer_spec_validation {
mod layer_data_validation {
use {
super::layerview,
super::{layerview, layerview_nullable},
crate::engine::core::model::{self, cell::Datacell},
};
#[test]
@ -203,4 +206,16 @@ mod layer_data_validation {
["list", "string", "string", "string"]
);
}
#[test]
fn nullval_fpath() {
let layer = layerview_nullable("string", true).unwrap();
assert!(layer.validate_data_fpath(&Datacell::null()));
assert_vecstreq_exact!(model::layer_traces(), ["fpath", "bool"]);
}
#[test]
fn nullval_nested_but_fpath() {
let layer = layerview_nullable("list { type: string }", true).unwrap();
assert!(layer.validate_data_fpath(&Datacell::null()));
assert_vecstreq_exact!(model::layer_traces(), ["fpath", "bool"]);
}
}

Loading…
Cancel
Save