use arrow::array::{Array, ArrayRef};
use arrow::datatypes::DataType;
use crate::datatype::{ColumnError, LogicalType, RefType, downcast_array, impl_marker_datatype};
pub struct Utf8;
impl_marker_datatype!(
Utf8,
arrow::array::StringArray,
&'a str,
String,
DataType::Utf8
);
pub struct LargeUtf8;
impl_marker_datatype!(
LargeUtf8,
arrow::array::LargeStringArray,
&'a str,
String,
DataType::LargeUtf8
);
pub struct Utf8View;
impl_marker_datatype!(
Utf8View,
arrow::array::StringViewArray,
&'a str,
String,
DataType::Utf8View
);
impl RefType for Utf8 {
type Ref = str;
fn value_ref(typed: &Self::Typed, index: usize) -> &str {
typed.value(index)
}
}
impl RefType for LargeUtf8 {
type Ref = str;
fn value_ref(typed: &Self::Typed, index: usize) -> &str {
typed.value(index)
}
}
impl RefType for Utf8View {
type Ref = str;
fn value_ref(typed: &Self::Typed, index: usize) -> &str {
typed.value(index)
}
}
pub struct AnyUtf8;
#[derive(Clone)]
pub enum AnyTypedUtf8 {
Utf8(arrow::array::StringArray),
LargeUtf8(arrow::array::LargeStringArray),
Utf8View(arrow::array::StringViewArray),
}
impl LogicalType for AnyUtf8 {
type Typed = AnyTypedUtf8;
type Value<'a> = &'a str;
type Owned = String;
fn downcast(array: &dyn Array) -> Result<Self::Typed, ColumnError> {
match array.data_type() {
DataType::Utf8 => Ok(AnyTypedUtf8::Utf8(downcast_array(array, || {
"Utf8".to_owned()
})?)),
DataType::LargeUtf8 => Ok(AnyTypedUtf8::LargeUtf8(downcast_array(array, || {
"LargeUtf8".to_owned()
})?)),
DataType::Utf8View => Ok(AnyTypedUtf8::Utf8View(downcast_array(array, || {
"Utf8View".to_owned()
})?)),
actual => Err(ColumnError::WrongDatatype {
expected: "a string array (Utf8/LargeUtf8/Utf8View)".to_owned(),
actual: actual.clone(),
}),
}
}
#[inline]
fn is_null(typed: &Self::Typed, index: usize) -> bool {
match typed {
AnyTypedUtf8::Utf8(array) => array.is_null(index),
AnyTypedUtf8::LargeUtf8(array) => array.is_null(index),
AnyTypedUtf8::Utf8View(array) => array.is_null(index),
}
}
#[inline]
unsafe fn is_null_unchecked(typed: &Self::Typed, index: usize) -> bool {
unsafe {
match typed {
AnyTypedUtf8::Utf8(array) => crate::datatype::leaf_is_null_unchecked(array, index),
AnyTypedUtf8::LargeUtf8(array) => {
crate::datatype::leaf_is_null_unchecked(array, index)
}
AnyTypedUtf8::Utf8View(array) => {
crate::datatype::leaf_is_null_unchecked(array, index)
}
}
}
}
#[inline]
fn value(typed: &Self::Typed, index: usize) -> Self::Value<'_> {
match typed {
AnyTypedUtf8::Utf8(array) => array.value(index),
AnyTypedUtf8::LargeUtf8(array) => array.value(index),
AnyTypedUtf8::Utf8View(array) => array.value(index),
}
}
#[inline]
unsafe fn value_unchecked(typed: &Self::Typed, index: usize) -> Self::Value<'_> {
unsafe {
match typed {
AnyTypedUtf8::Utf8(array) => array.value_unchecked(index),
AnyTypedUtf8::LargeUtf8(array) => array.value_unchecked(index),
AnyTypedUtf8::Utf8View(array) => array.value_unchecked(index),
}
}
}
fn to_owned_value(value: Self::Value<'_>) -> Self::Owned {
value.to_owned()
}
}
impl RefType for AnyUtf8 {
type Ref = str;
#[inline]
fn value_ref(typed: &Self::Typed, index: usize) -> &str {
Self::value(typed, index)
}
}