1use super::{Column, ColumnCoercionError, ColumnType, OwnedColumnError, OwnedColumnResult};
6use crate::base::{
7 math::{
8 decimal::Precision,
9 permutation::{Permutation, PermutationError},
10 },
11 posql_time::{PoSQLTimeUnit, PoSQLTimeZone},
12 scalar::Scalar,
13 slice_ops::{inner_product_ref_cast, inner_product_with_bytes},
14};
15use alloc::{
16 string::{String, ToString},
17 vec::Vec,
18};
19use itertools::Itertools;
20use serde::{Deserialize, Serialize};
21
22#[derive(Debug, PartialEq, Clone, Eq, Serialize, Deserialize)]
23#[non_exhaustive]
24#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
25pub enum OwnedColumn<S: Scalar> {
27 Boolean(Vec<bool>),
29 Uint8(Vec<u8>),
31 TinyInt(Vec<i8>),
33 SmallInt(Vec<i16>),
35 Int(Vec<i32>),
37 BigInt(Vec<i64>),
39 Int128(Vec<i128>),
41 VarChar(Vec<String>),
43 #[cfg_attr(test, proptest(skip))]
45 Decimal75(Precision, i8, Vec<S>),
46 #[cfg_attr(test, proptest(skip))]
48 TimestampTZ(PoSQLTimeUnit, PoSQLTimeZone, Vec<i64>),
49 #[cfg_attr(test, proptest(skip))]
51 Scalar(Vec<S>),
52 VarBinary(Vec<Vec<u8>>),
54}
55
56impl<S: Scalar> OwnedColumn<S> {
57 pub(crate) fn inner_product(&self, vec: &[S]) -> S {
59 match self {
60 OwnedColumn::Boolean(col) => inner_product_ref_cast(col, vec),
61 OwnedColumn::Uint8(col) => inner_product_ref_cast(col, vec),
62 OwnedColumn::TinyInt(col) => inner_product_ref_cast(col, vec),
63 OwnedColumn::SmallInt(col) => inner_product_ref_cast(col, vec),
64 OwnedColumn::Int(col) => inner_product_ref_cast(col, vec),
65 OwnedColumn::BigInt(col) | OwnedColumn::TimestampTZ(_, _, col) => {
66 inner_product_ref_cast(col, vec)
67 }
68 OwnedColumn::VarChar(col) => inner_product_ref_cast(col, vec),
69 OwnedColumn::VarBinary(col) => inner_product_with_bytes(col, vec),
70 OwnedColumn::Int128(col) => inner_product_ref_cast(col, vec),
71 OwnedColumn::Decimal75(_, _, col) | OwnedColumn::Scalar(col) => {
72 inner_product_ref_cast(col, vec)
73 }
74 }
75 }
76
77 #[must_use]
79 pub fn len(&self) -> usize {
80 match self {
81 OwnedColumn::Boolean(col) => col.len(),
82 OwnedColumn::TinyInt(col) => col.len(),
83 OwnedColumn::Uint8(col) => col.len(),
84 OwnedColumn::SmallInt(col) => col.len(),
85 OwnedColumn::Int(col) => col.len(),
86 OwnedColumn::BigInt(col) | OwnedColumn::TimestampTZ(_, _, col) => col.len(),
87 OwnedColumn::VarChar(col) => col.len(),
88 OwnedColumn::VarBinary(col) => col.len(),
89 OwnedColumn::Int128(col) => col.len(),
90 OwnedColumn::Decimal75(_, _, col) | OwnedColumn::Scalar(col) => col.len(),
91 }
92 }
93
94 pub fn try_permute(&self, permutation: &Permutation) -> Result<Self, PermutationError> {
96 Ok(match self {
97 OwnedColumn::Boolean(col) => OwnedColumn::Boolean(permutation.try_apply(col)?),
98 OwnedColumn::TinyInt(col) => OwnedColumn::TinyInt(permutation.try_apply(col)?),
99 OwnedColumn::Uint8(col) => OwnedColumn::Uint8(permutation.try_apply(col)?),
100 OwnedColumn::SmallInt(col) => OwnedColumn::SmallInt(permutation.try_apply(col)?),
101 OwnedColumn::Int(col) => OwnedColumn::Int(permutation.try_apply(col)?),
102 OwnedColumn::BigInt(col) => OwnedColumn::BigInt(permutation.try_apply(col)?),
103 OwnedColumn::VarChar(col) => OwnedColumn::VarChar(permutation.try_apply(col)?),
104 OwnedColumn::VarBinary(col) => OwnedColumn::VarBinary(permutation.try_apply(col)?),
105 OwnedColumn::Int128(col) => OwnedColumn::Int128(permutation.try_apply(col)?),
106 OwnedColumn::Decimal75(precision, scale, col) => {
107 OwnedColumn::Decimal75(*precision, *scale, permutation.try_apply(col)?)
108 }
109 OwnedColumn::Scalar(col) => OwnedColumn::Scalar(permutation.try_apply(col)?),
110 OwnedColumn::TimestampTZ(tu, tz, col) => {
111 OwnedColumn::TimestampTZ(*tu, *tz, permutation.try_apply(col)?)
112 }
113 })
114 }
115
116 #[must_use]
118 pub fn slice(&self, start: usize, end: usize) -> Self {
119 match self {
120 OwnedColumn::Boolean(col) => OwnedColumn::Boolean(col[start..end].to_vec()),
121 OwnedColumn::TinyInt(col) => OwnedColumn::TinyInt(col[start..end].to_vec()),
122 OwnedColumn::Uint8(col) => OwnedColumn::Uint8(col[start..end].to_vec()),
123 OwnedColumn::SmallInt(col) => OwnedColumn::SmallInt(col[start..end].to_vec()),
124 OwnedColumn::Int(col) => OwnedColumn::Int(col[start..end].to_vec()),
125 OwnedColumn::BigInt(col) => OwnedColumn::BigInt(col[start..end].to_vec()),
126 OwnedColumn::VarChar(col) => OwnedColumn::VarChar(col[start..end].to_vec()),
127 OwnedColumn::VarBinary(col) => OwnedColumn::VarBinary(col[start..end].to_vec()),
128 OwnedColumn::Int128(col) => OwnedColumn::Int128(col[start..end].to_vec()),
129 OwnedColumn::Decimal75(precision, scale, col) => {
130 OwnedColumn::Decimal75(*precision, *scale, col[start..end].to_vec())
131 }
132 OwnedColumn::Scalar(col) => OwnedColumn::Scalar(col[start..end].to_vec()),
133 OwnedColumn::TimestampTZ(tu, tz, col) => {
134 OwnedColumn::TimestampTZ(*tu, *tz, col[start..end].to_vec())
135 }
136 }
137 }
138
139 #[must_use]
141 pub fn is_empty(&self) -> bool {
142 match self {
143 OwnedColumn::Boolean(col) => col.is_empty(),
144 OwnedColumn::TinyInt(col) => col.is_empty(),
145 OwnedColumn::Uint8(col) => col.is_empty(),
146 OwnedColumn::SmallInt(col) => col.is_empty(),
147 OwnedColumn::Int(col) => col.is_empty(),
148 OwnedColumn::BigInt(col) | OwnedColumn::TimestampTZ(_, _, col) => col.is_empty(),
149 OwnedColumn::VarChar(col) => col.is_empty(),
150 OwnedColumn::VarBinary(col) => col.is_empty(),
151 OwnedColumn::Int128(col) => col.is_empty(),
152 OwnedColumn::Scalar(col) | OwnedColumn::Decimal75(_, _, col) => col.is_empty(),
153 }
154 }
155 #[must_use]
157 pub fn column_type(&self) -> ColumnType {
158 match self {
159 OwnedColumn::Boolean(_) => ColumnType::Boolean,
160 OwnedColumn::TinyInt(_) => ColumnType::TinyInt,
161 OwnedColumn::Uint8(_) => ColumnType::Uint8,
162 OwnedColumn::SmallInt(_) => ColumnType::SmallInt,
163 OwnedColumn::Int(_) => ColumnType::Int,
164 OwnedColumn::BigInt(_) => ColumnType::BigInt,
165 OwnedColumn::VarChar(_) => ColumnType::VarChar,
166 OwnedColumn::VarBinary(_) => ColumnType::VarBinary,
167 OwnedColumn::Int128(_) => ColumnType::Int128,
168 OwnedColumn::Scalar(_) => ColumnType::Scalar,
169 OwnedColumn::Decimal75(precision, scale, _) => {
170 ColumnType::Decimal75(*precision, *scale)
171 }
172 OwnedColumn::TimestampTZ(tu, tz, _) => ColumnType::TimestampTZ(*tu, *tz),
173 }
174 }
175
176 pub fn try_from_scalars(scalars: &[S], column_type: ColumnType) -> OwnedColumnResult<Self> {
178 match column_type {
179 ColumnType::Boolean => Ok(OwnedColumn::Boolean(
180 scalars
181 .iter()
182 .map(|s| -> Result<bool, _> { TryInto::<bool>::try_into(*s) })
183 .collect::<Result<Vec<_>, _>>()
184 .map_err(|_| OwnedColumnError::ScalarConversionError {
185 error: "Overflow in scalar conversions".to_string(),
186 })?,
187 )),
188 ColumnType::Uint8 => Ok(OwnedColumn::Uint8(
189 scalars
190 .iter()
191 .map(|s| -> Result<u8, _> { TryInto::<u8>::try_into(*s) })
192 .collect::<Result<Vec<_>, _>>()
193 .map_err(|_| OwnedColumnError::ScalarConversionError {
194 error: "Overflow in scalar conversions".to_string(),
195 })?,
196 )),
197 ColumnType::TinyInt => Ok(OwnedColumn::TinyInt(
198 scalars
199 .iter()
200 .map(|s| -> Result<i8, _> { TryInto::<i8>::try_into(*s) })
201 .collect::<Result<Vec<_>, _>>()
202 .map_err(|_| OwnedColumnError::ScalarConversionError {
203 error: "Overflow in scalar conversions".to_string(),
204 })?,
205 )),
206 ColumnType::SmallInt => Ok(OwnedColumn::SmallInt(
207 scalars
208 .iter()
209 .map(|s| -> Result<i16, _> { TryInto::<i16>::try_into(*s) })
210 .collect::<Result<Vec<_>, _>>()
211 .map_err(|_| OwnedColumnError::ScalarConversionError {
212 error: "Overflow in scalar conversions".to_string(),
213 })?,
214 )),
215 ColumnType::Int => Ok(OwnedColumn::Int(
216 scalars
217 .iter()
218 .map(|s| -> Result<i32, _> { TryInto::<i32>::try_into(*s) })
219 .collect::<Result<Vec<_>, _>>()
220 .map_err(|_| OwnedColumnError::ScalarConversionError {
221 error: "Overflow in scalar conversions".to_string(),
222 })?,
223 )),
224 ColumnType::BigInt => Ok(OwnedColumn::BigInt(
225 scalars
226 .iter()
227 .map(|s| -> Result<i64, _> { TryInto::<i64>::try_into(*s) })
228 .collect::<Result<Vec<_>, _>>()
229 .map_err(|_| OwnedColumnError::ScalarConversionError {
230 error: "Overflow in scalar conversions".to_string(),
231 })?,
232 )),
233 ColumnType::Int128 => Ok(OwnedColumn::Int128(
234 scalars
235 .iter()
236 .map(|s| -> Result<i128, _> { TryInto::<i128>::try_into(*s) })
237 .collect::<Result<Vec<_>, _>>()
238 .map_err(|_| OwnedColumnError::ScalarConversionError {
239 error: "Overflow in scalar conversions".to_string(),
240 })?,
241 )),
242 ColumnType::Scalar => Ok(OwnedColumn::Scalar(scalars.to_vec())),
243 ColumnType::Decimal75(precision, scale) => {
244 Ok(OwnedColumn::Decimal75(precision, scale, scalars.to_vec()))
245 }
246 ColumnType::TimestampTZ(tu, tz) => {
247 let raw_values: Vec<i64> = scalars
248 .iter()
249 .map(|s| -> Result<i64, _> { TryInto::<i64>::try_into(*s) })
250 .collect::<Result<Vec<_>, _>>()
251 .map_err(|_| OwnedColumnError::ScalarConversionError {
252 error: "Overflow in scalar conversions".to_string(),
253 })?;
254 Ok(OwnedColumn::TimestampTZ(tu, tz, raw_values))
255 }
256 ColumnType::VarChar | ColumnType::VarBinary => Err(OwnedColumnError::TypeCastError {
258 from_type: ColumnType::Scalar,
259 to_type: ColumnType::VarChar,
260 }),
261 }
262 }
263
264 pub fn try_from_option_scalars(
266 option_scalars: &[Option<S>],
267 column_type: ColumnType,
268 ) -> OwnedColumnResult<Self> {
269 let scalars = option_scalars
270 .iter()
271 .copied()
272 .collect::<Option<Vec<_>>>()
273 .ok_or(OwnedColumnError::Unsupported {
274 error: "NULL is not supported yet".to_string(),
275 })?;
276 Self::try_from_scalars(&scalars, column_type)
277 }
278 #[cfg(test)]
279 pub fn u8_iter(&self) -> impl Iterator<Item = &u8> {
282 match self {
283 OwnedColumn::Uint8(col) => col.iter(),
284 _ => panic!("Expected Uint8 column"),
285 }
286 }
287 #[cfg(test)]
288 pub fn i8_iter(&self) -> impl Iterator<Item = &i8> {
291 match self {
292 OwnedColumn::TinyInt(col) => col.iter(),
293 _ => panic!("Expected TinyInt column"),
294 }
295 }
296 #[cfg(test)]
297 pub fn i16_iter(&self) -> impl Iterator<Item = &i16> {
300 match self {
301 OwnedColumn::SmallInt(col) => col.iter(),
302 _ => panic!("Expected SmallInt column"),
303 }
304 }
305 #[cfg(test)]
306 pub fn i32_iter(&self) -> impl Iterator<Item = &i32> {
309 match self {
310 OwnedColumn::Int(col) => col.iter(),
311 _ => panic!("Expected Int column"),
312 }
313 }
314 #[cfg(test)]
315 pub fn i64_iter(&self) -> impl Iterator<Item = &i64> {
318 match self {
319 OwnedColumn::TimestampTZ(_, _, col) | OwnedColumn::BigInt(col) => col.iter(),
320 _ => panic!("Expected TimestampTZ or BigInt column"),
321 }
322 }
323 #[cfg(test)]
324 pub fn i128_iter(&self) -> impl Iterator<Item = &i128> {
327 match self {
328 OwnedColumn::Int128(col) => col.iter(),
329 _ => panic!("Expected Int128 column"),
330 }
331 }
332 #[cfg(test)]
333 pub fn bool_iter(&self) -> impl Iterator<Item = &bool> {
336 match self {
337 OwnedColumn::Boolean(col) => col.iter(),
338 _ => panic!("Expected Boolean column"),
339 }
340 }
341 #[cfg(test)]
342 pub fn scalar_iter(&self) -> impl Iterator<Item = &S> {
345 match self {
346 OwnedColumn::Decimal75(_, _, col) | OwnedColumn::Scalar(col) => col.iter(),
347 _ => panic!("Expected Scalar or Decimal75 column"),
348 }
349 }
350 #[cfg(test)]
351 pub fn string_iter(&self) -> impl Iterator<Item = &String> {
354 match self {
355 OwnedColumn::VarChar(col) => col.iter(),
356 _ => panic!("Expected VarChar column"),
357 }
358 }
359}
360
361impl<'a, S: Scalar> From<&Column<'a, S>> for OwnedColumn<S> {
362 fn from(col: &Column<'a, S>) -> Self {
363 match col {
364 Column::Boolean(col) => OwnedColumn::Boolean(col.to_vec()),
365 Column::TinyInt(col) => OwnedColumn::TinyInt(col.to_vec()),
366 Column::Uint8(col) => OwnedColumn::Uint8(col.to_vec()),
367 Column::SmallInt(col) => OwnedColumn::SmallInt(col.to_vec()),
368 Column::Int(col) => OwnedColumn::Int(col.to_vec()),
369 Column::BigInt(col) => OwnedColumn::BigInt(col.to_vec()),
370 Column::VarChar((col, _)) => {
371 OwnedColumn::VarChar(col.iter().map(ToString::to_string).collect())
372 }
373 Column::VarBinary((col, _)) => {
374 OwnedColumn::VarBinary(col.iter().map(|slice| slice.to_vec()).collect())
375 }
376 Column::Int128(col) => OwnedColumn::Int128(col.to_vec()),
377 Column::Decimal75(precision, scale, col) => {
378 OwnedColumn::Decimal75(*precision, *scale, col.to_vec())
379 }
380 Column::Scalar(col) => OwnedColumn::Scalar(col.to_vec()),
381 Column::TimestampTZ(tu, tz, col) => OwnedColumn::TimestampTZ(*tu, *tz, col.to_vec()),
382 }
383 }
384}
385
386impl<S: Scalar> OwnedColumn<S> {
387 pub(crate) fn try_coerce_scalar_to_numeric(
408 self,
409 to_type: ColumnType,
410 ) -> Result<Self, ColumnCoercionError> {
411 if self.column_type() == to_type {
412 Ok(self)
413 } else if let OwnedColumn::Scalar(vec) = self {
414 match to_type {
415 ColumnType::Uint8 => vec
416 .into_iter()
417 .map(TryInto::try_into)
418 .try_collect()
419 .map_err(|_| ColumnCoercionError::Overflow)
420 .map(OwnedColumn::Uint8),
421 ColumnType::TinyInt => vec
422 .into_iter()
423 .map(TryInto::try_into)
424 .try_collect()
425 .map_err(|_| ColumnCoercionError::Overflow)
426 .map(OwnedColumn::TinyInt),
427 ColumnType::SmallInt => vec
428 .into_iter()
429 .map(TryInto::try_into)
430 .try_collect()
431 .map_err(|_| ColumnCoercionError::Overflow)
432 .map(OwnedColumn::SmallInt),
433 ColumnType::Int => vec
434 .into_iter()
435 .map(TryInto::try_into)
436 .try_collect()
437 .map_err(|_| ColumnCoercionError::Overflow)
438 .map(OwnedColumn::Int),
439 ColumnType::BigInt => vec
440 .into_iter()
441 .map(TryInto::try_into)
442 .try_collect()
443 .map_err(|_| ColumnCoercionError::Overflow)
444 .map(OwnedColumn::BigInt),
445 ColumnType::Int128 => vec
446 .into_iter()
447 .map(TryInto::try_into)
448 .try_collect()
449 .map_err(|_| ColumnCoercionError::Overflow)
450 .map(OwnedColumn::Int128),
451 ColumnType::Decimal75(precision, scale) => {
452 Ok(OwnedColumn::Decimal75(precision, scale, vec))
453 }
454 _ => Err(ColumnCoercionError::InvalidTypeCoercion),
455 }
456 } else {
457 Err(ColumnCoercionError::InvalidTypeCoercion)
458 }
459 }
460}
461
462#[cfg(test)]
463mod test {
464 use super::*;
465 use crate::base::{
466 math::decimal::Precision,
467 scalar::{test_scalar::TestScalar, ScalarExt},
468 };
469 use alloc::vec;
470 use bumpalo::Bump;
471
472 #[test]
473 fn we_can_slice_a_column() {
474 let col: OwnedColumn<TestScalar> = OwnedColumn::Int128(vec![1, 2, 3, 4, 5]);
475 assert_eq!(col.slice(1, 4), OwnedColumn::Int128(vec![2, 3, 4]));
476 }
477
478 #[test]
479 fn we_can_permute_a_column() {
480 let col: OwnedColumn<TestScalar> = OwnedColumn::Int128(vec![1, 2, 3, 4, 5]);
481 let permutation = Permutation::try_new(vec![1, 3, 4, 0, 2]).unwrap();
482 assert_eq!(
483 col.try_permute(&permutation).unwrap(),
484 OwnedColumn::Int128(vec![2, 4, 5, 1, 3])
485 );
486 }
487
488 #[test]
489 fn we_can_convert_columns_to_owned_columns_round_trip() {
490 let alloc = Bump::new();
491 let col: Column<'_, TestScalar> = Column::Int128(&[1, 2, 3, 4, 5]);
493 let owned_col: OwnedColumn<TestScalar> = (&col).into();
494 assert_eq!(owned_col, OwnedColumn::Int128(vec![1, 2, 3, 4, 5]));
495 let new_col = Column::<TestScalar>::from_owned_column(&owned_col, &alloc);
496 assert_eq!(col, new_col);
497
498 let col: Column<'_, TestScalar> = Column::Boolean(&[true, false, true, false, true]);
500 let owned_col: OwnedColumn<TestScalar> = (&col).into();
501 assert_eq!(
502 owned_col,
503 OwnedColumn::Boolean(vec![true, false, true, false, true])
504 );
505 let new_col = Column::<TestScalar>::from_owned_column(&owned_col, &alloc);
506 assert_eq!(col, new_col);
507
508 let strs = [
510 "Space and Time",
511 "מרחב וזמן",
512 "Χώρος και Χρόνος",
513 "Տարածություն և ժամանակ",
514 "ቦታ እና ጊዜ",
515 "სივრცე და დრო",
516 ];
517 let scalars = strs.iter().map(TestScalar::from).collect::<Vec<_>>();
518 let col: Column<'_, TestScalar> = Column::VarChar((&strs, &scalars));
519 let owned_col: OwnedColumn<TestScalar> = (&col).into();
520 assert_eq!(
521 owned_col,
522 OwnedColumn::VarChar(
523 strs.iter()
524 .map(ToString::to_string)
525 .collect::<Vec<String>>()
526 )
527 );
528 let new_col = Column::<TestScalar>::from_owned_column(&owned_col, &alloc);
529 assert_eq!(col, new_col);
530
531 let scalars: Vec<TestScalar> = [1, 2, 3, 4, 5].iter().map(TestScalar::from).collect();
533 let col: Column<'_, TestScalar> =
534 Column::Decimal75(Precision::new(75).unwrap(), -128, &scalars);
535 let owned_col: OwnedColumn<TestScalar> = (&col).into();
536 assert_eq!(
537 owned_col,
538 OwnedColumn::Decimal75(Precision::new(75).unwrap(), -128, scalars.clone())
539 );
540 let new_col = Column::<TestScalar>::from_owned_column(&owned_col, &alloc);
541 assert_eq!(col, new_col);
542 }
543
544 #[test]
545 fn we_can_convert_scalars_to_owned_columns() {
546 let scalars = [1, 2, 3, 4, 5]
548 .iter()
549 .map(TestScalar::from)
550 .collect::<Vec<_>>();
551 let column_type = ColumnType::Int128;
552 let owned_col = OwnedColumn::try_from_scalars(&scalars, column_type).unwrap();
553 assert_eq!(owned_col, OwnedColumn::Int128(vec![1, 2, 3, 4, 5]));
554
555 let scalars = [true, false, true, false, true]
557 .iter()
558 .map(TestScalar::from)
559 .collect::<Vec<_>>();
560 let column_type = ColumnType::Boolean;
561 let owned_col = OwnedColumn::try_from_scalars(&scalars, column_type).unwrap();
562 assert_eq!(
563 owned_col,
564 OwnedColumn::Boolean(vec![true, false, true, false, true])
565 );
566
567 let scalars = [1, 2, 3, 4, 5]
569 .iter()
570 .map(TestScalar::from)
571 .collect::<Vec<_>>();
572 let column_type = ColumnType::Decimal75(Precision::new(75).unwrap(), -128);
573 let owned_col = OwnedColumn::try_from_scalars(&scalars, column_type).unwrap();
574 assert_eq!(
575 owned_col,
576 OwnedColumn::Decimal75(Precision::new(75).unwrap(), -128, scalars)
577 );
578 }
579
580 #[test]
581 fn we_cannot_convert_scalars_to_owned_columns_if_varchar() {
582 let scalars = ["a", "b", "c", "d", "e"]
583 .iter()
584 .map(TestScalar::from)
585 .collect::<Vec<_>>();
586 let column_type = ColumnType::VarChar;
587 let res = OwnedColumn::try_from_scalars(&scalars, column_type);
588 assert!(matches!(res, Err(OwnedColumnError::TypeCastError { .. })));
589 }
590
591 #[test]
592 fn we_cannot_convert_scalars_to_owned_columns_if_overflow() {
593 let scalars = [i128::MAX, i128::MAX, i128::MAX, i128::MAX, i128::MAX]
595 .iter()
596 .map(TestScalar::from)
597 .collect::<Vec<_>>();
598 let column_type = ColumnType::BigInt;
599 let res = OwnedColumn::try_from_scalars(&scalars, column_type);
600 assert!(matches!(
601 res,
602 Err(OwnedColumnError::ScalarConversionError { .. })
603 ));
604
605 let scalars = [i128::MAX, i128::MAX, i128::MAX, i128::MAX, i128::MAX]
607 .iter()
608 .map(TestScalar::from)
609 .collect::<Vec<_>>();
610 let column_type = ColumnType::Boolean;
611 let res = OwnedColumn::try_from_scalars(&scalars, column_type);
612 assert!(matches!(
613 res,
614 Err(OwnedColumnError::ScalarConversionError { .. })
615 ));
616 }
617
618 #[test]
619 fn we_can_convert_option_scalars_to_owned_columns() {
620 let option_scalars = [Some(1), Some(2), Some(3), Some(4), Some(5)]
622 .iter()
623 .map(|s| s.map(TestScalar::from))
624 .collect::<Vec<_>>();
625 let column_type = ColumnType::Int128;
626 let owned_col = OwnedColumn::try_from_option_scalars(&option_scalars, column_type).unwrap();
627 assert_eq!(owned_col, OwnedColumn::Int128(vec![1, 2, 3, 4, 5]));
628
629 let option_scalars = [Some(true), Some(false), Some(true), Some(false), Some(true)]
631 .iter()
632 .map(|s| s.map(TestScalar::from))
633 .collect::<Vec<_>>();
634 let column_type = ColumnType::Boolean;
635 let owned_col = OwnedColumn::try_from_option_scalars(&option_scalars, column_type).unwrap();
636 assert_eq!(
637 owned_col,
638 OwnedColumn::Boolean(vec![true, false, true, false, true])
639 );
640
641 let option_scalars = [Some(1), Some(2), Some(3), Some(4), Some(5)]
643 .iter()
644 .map(|s| s.map(TestScalar::from))
645 .collect::<Vec<_>>();
646 let scalars = [1, 2, 3, 4, 5]
647 .iter()
648 .map(|&i| TestScalar::from(i))
649 .collect::<Vec<_>>();
650 let column_type = ColumnType::Decimal75(Precision::new(75).unwrap(), 127);
651 let owned_col = OwnedColumn::try_from_option_scalars(&option_scalars, column_type).unwrap();
652 assert_eq!(
653 owned_col,
654 OwnedColumn::Decimal75(Precision::new(75).unwrap(), 127, scalars)
655 );
656 }
657
658 #[test]
659 fn we_cannot_convert_option_scalars_to_owned_columns_if_varchar() {
660 let option_scalars = ["a", "b", "c", "d", "e"]
661 .iter()
662 .map(|s| Some(TestScalar::from(*s)))
663 .collect::<Vec<_>>();
664 let column_type = ColumnType::VarChar;
665 let res = OwnedColumn::try_from_option_scalars(&option_scalars, column_type);
666 assert!(matches!(res, Err(OwnedColumnError::TypeCastError { .. })));
667 }
668
669 #[test]
670 fn we_cannot_convert_option_scalars_to_owned_columns_if_overflow() {
671 let option_scalars = [
673 Some(i128::MAX),
674 Some(i128::MAX),
675 Some(i128::MAX),
676 Some(i128::MAX),
677 Some(i128::MAX),
678 ]
679 .iter()
680 .map(|s| s.map(TestScalar::from))
681 .collect::<Vec<_>>();
682 let column_type = ColumnType::BigInt;
683 let res = OwnedColumn::try_from_option_scalars(&option_scalars, column_type);
684 assert!(matches!(
685 res,
686 Err(OwnedColumnError::ScalarConversionError { .. })
687 ));
688
689 let option_scalars = [
691 Some(i128::MAX),
692 Some(i128::MAX),
693 Some(i128::MAX),
694 Some(i128::MAX),
695 Some(i128::MAX),
696 ]
697 .iter()
698 .map(|s| s.map(TestScalar::from))
699 .collect::<Vec<_>>();
700 let column_type = ColumnType::Boolean;
701 let res = OwnedColumn::try_from_option_scalars(&option_scalars, column_type);
702 assert!(matches!(
703 res,
704 Err(OwnedColumnError::ScalarConversionError { .. })
705 ));
706 }
707
708 #[test]
709 fn we_cannot_convert_option_scalars_to_owned_columns_if_none() {
710 let option_scalars = [Some(1), Some(2), None, Some(4), Some(5)]
712 .iter()
713 .map(|s| s.map(TestScalar::from))
714 .collect::<Vec<_>>();
715 let column_type = ColumnType::Int128;
716 let res = OwnedColumn::try_from_option_scalars(&option_scalars, column_type);
717 assert!(matches!(res, Err(OwnedColumnError::Unsupported { .. })));
718
719 let option_scalars = [Some(true), Some(false), None, Some(false), Some(true)]
721 .iter()
722 .map(|s| s.map(TestScalar::from))
723 .collect::<Vec<_>>();
724 let column_type = ColumnType::Boolean;
725 let res = OwnedColumn::try_from_option_scalars(&option_scalars, column_type);
726 assert!(matches!(res, Err(OwnedColumnError::Unsupported { .. })));
727 }
728
729 #[test]
730 fn we_can_coerce_scalar_to_numeric() {
731 let scalars = vec![
732 TestScalar::from(1),
733 TestScalar::from(2),
734 TestScalar::from(3),
735 ];
736 let col = OwnedColumn::Scalar(scalars.clone());
737
738 let coerced_col = col
740 .clone()
741 .try_coerce_scalar_to_numeric(ColumnType::TinyInt)
742 .unwrap();
743 assert_eq!(coerced_col, OwnedColumn::TinyInt(vec![1, 2, 3]));
744
745 let coerced_col = col
747 .clone()
748 .try_coerce_scalar_to_numeric(ColumnType::SmallInt)
749 .unwrap();
750 assert_eq!(coerced_col, OwnedColumn::SmallInt(vec![1, 2, 3]));
751
752 let coerced_col = col
754 .clone()
755 .try_coerce_scalar_to_numeric(ColumnType::Int)
756 .unwrap();
757 assert_eq!(coerced_col, OwnedColumn::Int(vec![1, 2, 3]));
758
759 let coerced_col = col
761 .clone()
762 .try_coerce_scalar_to_numeric(ColumnType::BigInt)
763 .unwrap();
764 assert_eq!(coerced_col, OwnedColumn::BigInt(vec![1, 2, 3]));
765
766 let coerced_col = col
768 .clone()
769 .try_coerce_scalar_to_numeric(ColumnType::Int128)
770 .unwrap();
771 assert_eq!(coerced_col, OwnedColumn::Int128(vec![1, 2, 3]));
772
773 let coerced_col = col
775 .clone()
776 .try_coerce_scalar_to_numeric(ColumnType::Decimal75(Precision::new(75).unwrap(), 0))
777 .unwrap();
778 assert_eq!(
779 coerced_col,
780 OwnedColumn::Decimal75(Precision::new(75).unwrap(), 0, scalars)
781 );
782 }
783
784 #[test]
785 fn we_cannot_coerce_scalar_to_invalid_type() {
786 let scalars = vec![
787 TestScalar::from(1),
788 TestScalar::from(2),
789 TestScalar::from(3),
790 ];
791 let col = OwnedColumn::Scalar(scalars);
792
793 let res = col
795 .clone()
796 .try_coerce_scalar_to_numeric(ColumnType::VarChar);
797 assert!(matches!(res, Err(ColumnCoercionError::InvalidTypeCoercion)));
798
799 let col = OwnedColumn::<TestScalar>::Int(vec![1, 2, 3]);
801 let res = col.try_coerce_scalar_to_numeric(ColumnType::BigInt);
802 assert!(matches!(res, Err(ColumnCoercionError::InvalidTypeCoercion)));
803 }
804
805 #[test]
806 fn we_cannot_coerce_scalar_to_numeric_if_overflow() {
807 let scalars = vec![TestScalar::from(i128::MAX), -TestScalar::from(i128::MIN)];
808 let col = OwnedColumn::Scalar(scalars);
809
810 let res = col
812 .clone()
813 .try_coerce_scalar_to_numeric(ColumnType::TinyInt);
814 assert!(matches!(res, Err(ColumnCoercionError::Overflow)));
815
816 let res = col
818 .clone()
819 .try_coerce_scalar_to_numeric(ColumnType::SmallInt);
820 assert!(matches!(res, Err(ColumnCoercionError::Overflow)));
821
822 let res = col.clone().try_coerce_scalar_to_numeric(ColumnType::Int);
824 assert!(matches!(res, Err(ColumnCoercionError::Overflow)));
825
826 let res = col.clone().try_coerce_scalar_to_numeric(ColumnType::BigInt);
828 assert!(matches!(res, Err(ColumnCoercionError::Overflow)));
829
830 let res = col.try_coerce_scalar_to_numeric(ColumnType::Int128);
832 assert!(matches!(res, Err(ColumnCoercionError::Overflow)));
833 }
834
835 #[test]
836 fn we_can_slice_and_permute_varbinary_columns() {
837 let col = OwnedColumn::<TestScalar>::VarBinary(vec![
838 b"foo".to_vec(),
839 b"bar".to_vec(),
840 b"baz".to_vec(),
841 b"qux".to_vec(),
842 ]);
843 assert_eq!(
844 col.slice(1, 3),
845 OwnedColumn::VarBinary(vec![b"bar".to_vec(), b"baz".to_vec()])
846 );
847 let permutation = Permutation::try_new(vec![2, 0, 3, 1]).unwrap();
848 assert_eq!(
849 col.try_permute(&permutation).unwrap(),
850 OwnedColumn::VarBinary(vec![
851 b"baz".to_vec(),
852 b"foo".to_vec(),
853 b"qux".to_vec(),
854 b"bar".to_vec()
855 ])
856 );
857 }
858
859 #[test]
860 fn we_can_convert_varbinary_column_round_trip_using_hash() {
861 let raw_bytes = [b"abc".as_ref(), b"xyz".as_ref()];
862
863 let scalars: Vec<TestScalar> = raw_bytes
864 .iter()
865 .map(|&b| TestScalar::from_byte_slice_via_hash(b))
866 .collect();
867
868 let col: Column<'_, TestScalar> =
869 Column::VarBinary((raw_bytes.as_slice(), scalars.as_slice()));
870
871 let owned_col: OwnedColumn<TestScalar> = (&col).into();
872
873 assert_eq!(
874 owned_col,
875 OwnedColumn::VarBinary(vec![b"abc".to_vec(), b"xyz".to_vec()])
876 );
877
878 let bump = bumpalo::Bump::new();
879 let new_col = Column::<TestScalar>::from_owned_column(&owned_col, &bump);
880
881 assert_eq!(col, new_col);
882 }
883
884 #[test]
885 fn we_can_compute_inner_product_with_varbinary_columns_using_hash() {
886 let lhs = OwnedColumn::<TestScalar>::VarBinary(vec![
887 b"foo".to_vec(),
888 b"bar".to_vec(),
889 b"baz".to_vec(),
890 ]);
891
892 let scalars = vec![
893 TestScalar::from(10),
894 TestScalar::from(20),
895 TestScalar::from(30),
896 ];
897
898 let product = lhs.inner_product(&scalars);
899
900 let lhs_hashes: Vec<TestScalar> = [b"foo".as_ref(), b"bar".as_ref(), b"baz".as_ref()]
901 .iter()
902 .map(|&bytes| TestScalar::from_byte_slice_via_hash(bytes))
903 .collect();
904
905 let expected =
906 lhs_hashes[0] * scalars[0] + lhs_hashes[1] * scalars[1] + lhs_hashes[2] * scalars[2];
907
908 assert_eq!(product, expected);
909 }
910}