Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 49 additions & 1 deletion encodings/alp/src/alp_rd/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,17 @@ pub struct ALPRDMetadata {
patches: Option<PatchesMetadata>,
}

impl ALPRDMetadata {
fn get_left_parts_ptype(&self) -> VortexResult<PType> {
PType::try_from(self.left_parts_ptype).map_err(|_| {
vortex_err!(
Serde: "ALPRDMetadata left_parts_ptype must be a known PType, got {}",
self.left_parts_ptype
)
})
}
}

impl ArrayHash for ALPRDData {
fn array_hash<H: Hasher>(&self, state: &mut H, accuracy: EqMode) {
self.left_parts_dictionary.array_hash(state, accuracy);
Expand Down Expand Up @@ -172,14 +183,15 @@ impl VTable for ALPRD {
session: &VortexSession,
) -> VortexResult<ArrayParts<Self>> {
let metadata = ALPRDMetadata::decode(metadata)?;
let left_parts_ptype = metadata.get_left_parts_ptype()?;
if children.len() < 2 {
vortex_bail!(
"Expected at least 2 children for ALPRD encoding, found {}",
children.len()
);
}

let left_parts_dtype = DType::Primitive(metadata.left_parts_ptype(), dtype.nullability());
let left_parts_dtype = DType::Primitive(left_parts_ptype, dtype.nullability());
let left_parts = children.get(0, &left_parts_dtype, len)?;
let left_parts_dictionary: Buffer<u16> = metadata.dict.as_slice()
[0..metadata.dict_len as usize]
Expand Down Expand Up @@ -565,15 +577,22 @@ mod test {

use prost::Message;
use rstest::rstest;
use vortex_array::ArrayRef;
use vortex_array::VortexSessionExecute;
use vortex_array::arrays::PrimitiveArray;
use vortex_array::assert_arrays_eq;
use vortex_array::dtype::DType;
use vortex_array::dtype::NativePType;
use vortex_array::dtype::Nullability;
use vortex_array::dtype::PType;
use vortex_array::patches::PatchesMetadata;
use vortex_array::test_harness::assert_serde_error;
use vortex_array::test_harness::check_metadata;
use vortex_array::vtable::VTable;
use vortex_error::VortexResult;
use vortex_session::VortexSession;

use super::ALPRD;
use super::ALPRDMetadata;
use crate::ALPRDFloat;
use crate::RDEncoderExt;
Expand Down Expand Up @@ -633,4 +652,33 @@ mod test {
.encode_to_vec(),
);
}

#[test]
fn test_deserialize_rejects_unknown_left_parts_ptype() -> VortexResult<()> {
let metadata = ALPRDMetadata {
left_parts_ptype: 11,
..Default::default()
}
.encode_to_vec();
let children: Vec<ArrayRef> = Vec::new();
assert_serde_error(
ALPRD.deserialize(
&DType::Primitive(PType::F64, Nullability::NonNullable),
0,
&metadata,
&[],
&children,
&SESSION,
),
"ALPRDMetadata left_parts_ptype must be a known PType, got 11",
);

let known = ALPRDMetadata {
left_parts_ptype: PType::U32 as i32,
..Default::default()
};
assert_eq!(known.get_left_parts_ptype()?, PType::U32);

Ok(())
}
}
77 changes: 71 additions & 6 deletions encodings/fastlanes/src/rle/vtable/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use vortex_array::vtable::VTable;
use vortex_error::VortexResult;
use vortex_error::vortex_ensure;
use vortex_error::vortex_ensure_eq;
use vortex_error::vortex_err;
use vortex_error::vortex_panic;
use vortex_session::VortexSession;
use vortex_session::registry::CachedId;
Expand Down Expand Up @@ -61,6 +62,26 @@ pub struct RLEMetadata {
pub offset: u64,
}

impl RLEMetadata {
fn get_indices_ptype(&self) -> VortexResult<PType> {
PType::try_from(self.indices_ptype).map_err(|_| {
vortex_err!(
Serde: "RLEMetadata indices_ptype must be a known PType, got {}",
self.indices_ptype
)
})
}

fn get_values_idx_offsets_ptype(&self) -> VortexResult<PType> {
PType::try_from(self.values_idx_offsets_ptype).map_err(|_| {
vortex_err!(
Serde: "RLEMetadata values_idx_offsets_ptype must be a known PType, got {}",
self.values_idx_offsets_ptype
)
})
}
}

impl ArrayHash for RLEData {
fn array_hash<H: Hasher>(&self, state: &mut H, _accuracy: EqMode) {
self.offset.hash(state);
Expand Down Expand Up @@ -161,12 +182,14 @@ impl VTable for RLE {
children: &dyn ArrayChildren,
_session: &VortexSession,
) -> VortexResult<ArrayParts<Self>> {
let metadata = RLEMetadata::decode(metadata)?;
let indices_ptype = metadata.get_indices_ptype()?;
let values_idx_offsets_ptype = metadata.get_values_idx_offsets_ptype()?;
vortex_ensure!(
buffers.is_empty(),
"RLEArray expects 0 buffers, got {}",
buffers.len()
);
let metadata = RLEMetadata::decode(metadata)?;
let values = children.get(
0,
&DType::Primitive(dtype.as_ptype(), Nullability::NonNullable),
Expand All @@ -175,16 +198,13 @@ impl VTable for RLE {

let indices = children.get(
1,
&DType::Primitive(metadata.indices_ptype(), dtype.nullability()),
&DType::Primitive(indices_ptype, dtype.nullability()),
usize::try_from(metadata.indices_len)?,
)?;

let values_idx_offsets = children.get(
2,
&DType::Primitive(
metadata.values_idx_offsets_ptype(),
Nullability::NonNullable,
),
&DType::Primitive(values_idx_offsets_ptype, Nullability::NonNullable),
usize::try_from(metadata.values_idx_offsets_len)?,
)?;

Expand Down Expand Up @@ -328,9 +348,19 @@ fn validate_parts(
#[cfg(test)]
mod tests {
use prost::Message;
use rstest::rstest;
use vortex_array::ArrayRef;
use vortex_array::dtype::DType;
use vortex_array::dtype::Nullability;
use vortex_array::dtype::PType;
use vortex_array::test_harness::assert_serde_error;
use vortex_array::test_harness::check_metadata;
use vortex_array::vtable::VTable;
use vortex_error::VortexResult;

use super::RLE;
use super::RLEMetadata;
use crate::test::SESSION;

#[cfg_attr(miri, ignore)]
#[test]
Expand All @@ -348,4 +378,39 @@ mod tests {
.encode_to_vec(),
);
}

#[rstest]
#[case::indices_ptype(
|raw| RLEMetadata { indices_ptype: raw, ..Default::default() },
RLEMetadata::get_indices_ptype,
"RLEMetadata indices_ptype must be a known PType, got 11",
)]
#[case::values_idx_offsets_ptype(
|raw| RLEMetadata { values_idx_offsets_ptype: raw, ..Default::default() },
RLEMetadata::get_values_idx_offsets_ptype,
"RLEMetadata values_idx_offsets_ptype must be a known PType, got 11",
)]
fn test_deserialize_rejects_unknown_ptype(
#[case] with_ptype: fn(i32) -> RLEMetadata,
#[case] get_ptype: fn(&RLEMetadata) -> VortexResult<PType>,
#[case] expected: &str,
) -> VortexResult<()> {
let metadata = with_ptype(11).encode_to_vec();
let children: Vec<ArrayRef> = Vec::new();
assert_serde_error(
RLE.deserialize(
&DType::Primitive(PType::U32, Nullability::NonNullable),
0,
&metadata,
&[],
&children,
&SESSION,
),
expected,
);

assert_eq!(get_ptype(&with_ptype(PType::U32 as i32))?, PType::U32);

Ok(())
}
}
49 changes: 48 additions & 1 deletion encodings/runend/src/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ use vortex_error::VortexResult;
use vortex_error::vortex_bail;
use vortex_error::vortex_ensure;
use vortex_error::vortex_ensure_eq;
use vortex_error::vortex_err;
use vortex_error::vortex_panic;
use vortex_session::VortexSession;
use vortex_session::registry::CachedId;
Expand All @@ -69,6 +70,17 @@ pub struct RunEndMetadata {
pub offset: u64,
}

impl RunEndMetadata {
fn get_ends_ptype(&self) -> VortexResult<PType> {
PType::try_from(self.ends_ptype).map_err(|_| {
vortex_err!(
Serde: "RunEndMetadata ends_ptype must be a known PType, got {}",
self.ends_ptype
)
})
}
}

impl ArrayHash for RunEndData {
fn array_hash<H: Hasher>(&self, state: &mut H, _accuracy: EqMode) {
self.offset.hash(state);
Expand Down Expand Up @@ -152,7 +164,8 @@ impl VTable for RunEnd {
session: &VortexSession,
) -> VortexResult<ArrayParts<Self>> {
let metadata = RunEndMetadata::decode(metadata)?;
let ends_dtype = DType::Primitive(metadata.ends_ptype(), Nullability::NonNullable);
let ends_ptype = metadata.get_ends_ptype()?;
let ends_dtype = DType::Primitive(ends_ptype, Nullability::NonNullable);
let runs = usize::try_from(metadata.num_runs).vortex_expect("Must be a valid usize");
let ends = children.get(0, &ends_dtype, runs)?;

Expand Down Expand Up @@ -575,6 +588,8 @@ mod tests {
use std::sync::Arc;
use std::sync::LazyLock;

use prost::Message;
use vortex_array::ArrayRef;
use vortex_array::IntoArray;
use vortex_array::VortexSessionExecute;
use vortex_array::arrays::DecimalArray;
Expand All @@ -590,11 +605,14 @@ mod tests {
use vortex_array::dtype::Nullability;
use vortex_array::dtype::PType;
use vortex_array::dtype::i256;
use vortex_array::test_harness::assert_serde_error;
use vortex_array::validity::Validity;
use vortex_array::vtable::VTable;
use vortex_buffer::buffer;
use vortex_error::VortexResult;
use vortex_session::VortexSession;

use super::RunEndMetadata;
use crate::RunEnd;

static SESSION: LazyLock<VortexSession> = LazyLock::new(|| {
Expand Down Expand Up @@ -934,4 +952,33 @@ mod tests {
assert_arrays_eq!(arr, expected, &mut ctx);
Ok(())
}

#[test]
fn test_deserialize_rejects_unknown_ends_ptype() -> VortexResult<()> {
let metadata = RunEndMetadata {
ends_ptype: 11,
..Default::default()
}
.encode_to_vec();
let children: Vec<ArrayRef> = Vec::new();
assert_serde_error(
RunEnd.deserialize(
&DType::Primitive(PType::I32, Nullability::NonNullable),
0,
&metadata,
&[],
&children,
&SESSION,
),
"RunEndMetadata ends_ptype must be a known PType, got 11",
);

let known = RunEndMetadata {
ends_ptype: PType::U32 as i32,
..Default::default()
};
assert_eq!(known.get_ends_ptype()?, PType::U32);

Ok(())
}
}
Loading
Loading