1use super::{LiteralValue, OwnedColumn, TableRef};
2use crate::base::{
3 math::decimal::Precision,
4 posql_time::{PoSQLTimeUnit, PoSQLTimeZone},
5 scalar::{Scalar, ScalarExt},
6 slice_ops::slice_cast_with,
7};
8use alloc::vec::Vec;
9use bumpalo::Bump;
10use core::{
11 fmt,
12 fmt::{Display, Formatter},
13 mem::size_of,
14};
15use serde::{Deserialize, Serialize};
16use sqlparser::ast::Ident;
17
18#[derive(Debug, Eq, PartialEq, Clone, Copy)]
25#[non_exhaustive]
26pub enum Column<'a, S: Scalar> {
27 Boolean(&'a [bool]),
29 Uint8(&'a [u8]),
31 TinyInt(&'a [i8]),
33 SmallInt(&'a [i16]),
35 Int(&'a [i32]),
37 BigInt(&'a [i64]),
39 Int128(&'a [i128]),
41 Decimal75(Precision, i8, &'a [S]),
44 Scalar(&'a [S]),
46 VarChar((&'a [&'a str], &'a [S])),
50 TimestampTZ(PoSQLTimeUnit, PoSQLTimeZone, &'a [i64]),
55 VarBinary((&'a [&'a [u8]], &'a [S])),
57}
58
59impl<'a, S: Scalar> Column<'a, S> {
60 #[must_use]
62 pub fn column_type(&self) -> ColumnType {
63 match self {
64 Self::Boolean(_) => ColumnType::Boolean,
65 Self::Uint8(_) => ColumnType::Uint8,
66 Self::TinyInt(_) => ColumnType::TinyInt,
67 Self::SmallInt(_) => ColumnType::SmallInt,
68 Self::Int(_) => ColumnType::Int,
69 Self::BigInt(_) => ColumnType::BigInt,
70 Self::VarChar(_) => ColumnType::VarChar,
71 Self::Int128(_) => ColumnType::Int128,
72 Self::Scalar(_) => ColumnType::Scalar,
73 Self::Decimal75(precision, scale, _) => ColumnType::Decimal75(*precision, *scale),
74 Self::TimestampTZ(time_unit, timezone, _) => {
75 ColumnType::TimestampTZ(*time_unit, *timezone)
76 }
77 Self::VarBinary(..) => ColumnType::VarBinary,
78 }
79 }
80 #[must_use]
84 pub fn len(&self) -> usize {
85 match self {
86 Self::Boolean(col) => col.len(),
87 Self::Uint8(col) => col.len(),
88 Self::TinyInt(col) => col.len(),
89 Self::SmallInt(col) => col.len(),
90 Self::Int(col) => col.len(),
91 Self::BigInt(col) | Self::TimestampTZ(_, _, col) => col.len(),
92 Self::VarChar((col, scals)) => {
93 assert_eq!(col.len(), scals.len());
94 col.len()
95 }
96 Self::VarBinary((col, scals)) => {
97 assert_eq!(col.len(), scals.len());
98 col.len()
99 }
100 Self::Int128(col) => col.len(),
101 Self::Scalar(col) | Self::Decimal75(_, _, col) => col.len(),
102 }
103 }
104 #[must_use]
106 pub fn is_empty(&self) -> bool {
107 self.len() == 0
108 }
109
110 pub fn from_literal_with_length(
112 literal: &LiteralValue,
113 length: usize,
114 alloc: &'a Bump,
115 ) -> Self {
116 match literal {
117 LiteralValue::Boolean(value) => {
118 Column::Boolean(alloc.alloc_slice_fill_copy(length, *value))
119 }
120 LiteralValue::Uint8(value) => {
121 Column::Uint8(alloc.alloc_slice_fill_copy(length, *value))
122 }
123 LiteralValue::TinyInt(value) => {
124 Column::TinyInt(alloc.alloc_slice_fill_copy(length, *value))
125 }
126 LiteralValue::SmallInt(value) => {
127 Column::SmallInt(alloc.alloc_slice_fill_copy(length, *value))
128 }
129 LiteralValue::Int(value) => Column::Int(alloc.alloc_slice_fill_copy(length, *value)),
130 LiteralValue::BigInt(value) => {
131 Column::BigInt(alloc.alloc_slice_fill_copy(length, *value))
132 }
133 LiteralValue::Int128(value) => {
134 Column::Int128(alloc.alloc_slice_fill_copy(length, *value))
135 }
136 LiteralValue::Scalar(value) => {
137 Column::Scalar(alloc.alloc_slice_fill_copy(length, (*value).into()))
138 }
139 LiteralValue::Decimal75(precision, scale, value) => Column::Decimal75(
140 *precision,
141 *scale,
142 alloc.alloc_slice_fill_copy(length, value.into_scalar()),
143 ),
144 LiteralValue::TimeStampTZ(tu, tz, value) => {
145 Column::TimestampTZ(*tu, *tz, alloc.alloc_slice_fill_copy(length, *value))
146 }
147 LiteralValue::VarChar(string) => Column::VarChar((
148 alloc.alloc_slice_fill_with(length, |_| alloc.alloc_str(string) as &str),
149 alloc.alloc_slice_fill_copy(length, S::from(string)),
150 )),
151 LiteralValue::VarBinary(bytes) => {
152 let bytes_slice = alloc
154 .alloc_slice_fill_with(length, |_| alloc.alloc_slice_copy(bytes) as &[_]);
155
156 let scalars =
158 alloc.alloc_slice_fill_copy(length, S::from_byte_slice_via_hash(bytes));
159
160 Column::VarBinary((bytes_slice, scalars))
161 }
162 }
163 }
164
165 pub fn rho(length: usize, alloc: &'a Bump) -> Self {
167 let raw_rho = (0..length as i128).collect::<Vec<_>>();
168 let rho = alloc.alloc_slice_copy(raw_rho.as_slice());
169 Column::<S>::Int128(rho as &[_])
170 }
171
172 pub fn from_owned_column(owned_column: &'a OwnedColumn<S>, alloc: &'a Bump) -> Self {
174 match owned_column {
175 OwnedColumn::Boolean(col) => Column::Boolean(col.as_slice()),
176 OwnedColumn::Uint8(col) => Column::Uint8(col.as_slice()),
177 OwnedColumn::TinyInt(col) => Column::TinyInt(col.as_slice()),
178 OwnedColumn::SmallInt(col) => Column::SmallInt(col.as_slice()),
179 OwnedColumn::Int(col) => Column::Int(col.as_slice()),
180 OwnedColumn::BigInt(col) => Column::BigInt(col.as_slice()),
181 OwnedColumn::Int128(col) => Column::Int128(col.as_slice()),
182 OwnedColumn::Decimal75(precision, scale, col) => {
183 Column::Decimal75(*precision, *scale, col.as_slice())
184 }
185 OwnedColumn::Scalar(col) => Column::Scalar(col.as_slice()),
186 OwnedColumn::VarChar(col) => {
187 let scalars = col.iter().map(S::from).collect::<Vec<_>>();
188 let strs = col
189 .iter()
190 .map(|s| s.as_str() as &'a str)
191 .collect::<Vec<_>>();
192 Column::VarChar((
193 alloc.alloc_slice_clone(strs.as_slice()),
194 alloc.alloc_slice_copy(scalars.as_slice()),
195 ))
196 }
197 OwnedColumn::VarBinary(col) => {
198 let scalars = col
199 .iter()
200 .map(|b| S::from_byte_slice_via_hash(b))
201 .collect::<Vec<_>>();
202 let bytes = col.iter().map(|s| s as &'a [u8]).collect::<Vec<_>>();
203 Column::VarBinary((
204 alloc.alloc_slice_clone(&bytes),
205 alloc.alloc_slice_copy(scalars.as_slice()),
206 ))
207 }
208 OwnedColumn::TimestampTZ(tu, tz, col) => Column::TimestampTZ(*tu, *tz, col.as_slice()),
209 }
210 }
211
212 pub(crate) fn as_boolean(&self) -> Option<&'a [bool]> {
214 match self {
215 Self::Boolean(col) => Some(col),
216 _ => None,
217 }
218 }
219
220 pub(crate) fn as_uint8(&self) -> Option<&'a [u8]> {
222 match self {
223 Self::Uint8(col) => Some(col),
224 _ => None,
225 }
226 }
227
228 pub(crate) fn as_tinyint(&self) -> Option<&'a [i8]> {
230 match self {
231 Self::TinyInt(col) => Some(col),
232 _ => None,
233 }
234 }
235
236 pub(crate) fn as_smallint(&self) -> Option<&'a [i16]> {
238 match self {
239 Self::SmallInt(col) => Some(col),
240 _ => None,
241 }
242 }
243
244 pub(crate) fn as_int(&self) -> Option<&'a [i32]> {
246 match self {
247 Self::Int(col) => Some(col),
248 _ => None,
249 }
250 }
251
252 pub(crate) fn as_bigint(&self) -> Option<&'a [i64]> {
254 match self {
255 Self::BigInt(col) => Some(col),
256 _ => None,
257 }
258 }
259
260 pub(crate) fn as_int128(&self) -> Option<&'a [i128]> {
262 match self {
263 Self::Int128(col) => Some(col),
264 _ => None,
265 }
266 }
267
268 pub(crate) fn as_scalar(&self) -> Option<&'a [S]> {
270 match self {
271 Self::Scalar(col) => Some(col),
272 _ => None,
273 }
274 }
275
276 pub(crate) fn as_decimal75(&self) -> Option<&'a [S]> {
278 match self {
279 Self::Decimal75(_, _, col) => Some(col),
280 _ => None,
281 }
282 }
283
284 pub(crate) fn as_varchar(&self) -> Option<(&'a [&'a str], &'a [S])> {
286 match self {
287 Self::VarChar((col, scals)) => Some((col, scals)),
288 _ => None,
289 }
290 }
291
292 pub(crate) fn as_varbinary(&self) -> Option<(&'a [&'a [u8]], &'a [S])> {
294 match self {
295 Self::VarBinary((col, scals)) => Some((col, scals)),
296 _ => None,
297 }
298 }
299
300 pub(crate) fn as_timestamptz(&self) -> Option<&'a [i64]> {
302 match self {
303 Self::TimestampTZ(_, _, col) => Some(col),
304 _ => None,
305 }
306 }
307
308 pub(crate) fn scalar_at(&self, index: usize) -> Option<S> {
312 (index < self.len()).then_some(match self {
313 Self::Boolean(col) => S::from(col[index]),
314 Self::Uint8(col) => S::from(col[index]),
315 Self::TinyInt(col) => S::from(col[index]),
316 Self::SmallInt(col) => S::from(col[index]),
317 Self::Int(col) => S::from(col[index]),
318 Self::BigInt(col) | Self::TimestampTZ(_, _, col) => S::from(col[index]),
319 Self::Int128(col) => S::from(col[index]),
320 Self::Scalar(col) | Self::Decimal75(_, _, col) => col[index],
321 Self::VarChar((_, scals)) | Self::VarBinary((_, scals)) => scals[index],
322 })
323 }
324
325 #[expect(clippy::missing_panics_doc)]
327 pub(crate) fn to_scalar_with_scaling(self, scale: i8) -> Vec<S> {
328 let scale_factor = S::pow10(u8::try_from(scale).expect("Upscale factor is nonnegative"));
329 match self {
330 Self::Boolean(col) => slice_cast_with(col, |b| S::from(b) * scale_factor),
331 Self::Decimal75(_, _, col) => slice_cast_with(col, |s| *s * scale_factor),
332 Self::VarChar((_, values)) => slice_cast_with(values, |s| *s * scale_factor),
333 Self::VarBinary((_, values)) => slice_cast_with(values, |s| *s * scale_factor),
334 Self::Uint8(col) => slice_cast_with(col, |i| S::from(i) * scale_factor),
335 Self::TinyInt(col) => slice_cast_with(col, |i| S::from(i) * scale_factor),
336 Self::SmallInt(col) => slice_cast_with(col, |i| S::from(i) * scale_factor),
337 Self::Int(col) => slice_cast_with(col, |i| S::from(i) * scale_factor),
338 Self::BigInt(col) => slice_cast_with(col, |i| S::from(i) * scale_factor),
339 Self::Int128(col) => slice_cast_with(col, |i| S::from(i) * scale_factor),
340 Self::Scalar(col) => slice_cast_with(col, |i| S::from(i) * scale_factor),
341 Self::TimestampTZ(_, _, col) => slice_cast_with(col, |i| S::from(i) * scale_factor),
342 }
343 }
344}
345
346#[derive(Eq, PartialEq, Debug, Clone, Hash, Serialize, Deserialize, Copy)]
352#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
353pub enum ColumnType {
354 #[serde(alias = "BOOLEAN", alias = "boolean")]
356 Boolean,
357 #[serde(alias = "UINT8", alias = "uint8")]
359 Uint8,
360 #[serde(alias = "TINYINT", alias = "tinyint")]
362 TinyInt,
363 #[serde(alias = "SMALLINT", alias = "smallint")]
365 SmallInt,
366 #[serde(alias = "INT", alias = "int")]
368 Int,
369 #[serde(alias = "BIGINT", alias = "bigint")]
371 BigInt,
372 #[serde(rename = "Decimal", alias = "DECIMAL", alias = "decimal")]
374 Int128,
375 #[serde(alias = "VARCHAR", alias = "varchar")]
377 VarChar,
378 #[serde(rename = "Decimal75", alias = "DECIMAL75", alias = "decimal75")]
380 Decimal75(Precision, i8),
381 #[serde(alias = "TIMESTAMP", alias = "timestamp")]
383 #[cfg_attr(test, proptest(skip))]
384 TimestampTZ(PoSQLTimeUnit, PoSQLTimeZone),
385 #[serde(alias = "SCALAR", alias = "scalar")]
387 #[cfg_attr(test, proptest(skip))]
388 Scalar,
389 #[serde(alias = "BINARY", alias = "BINARY")]
391 VarBinary,
392}
393
394impl ColumnType {
395 #[must_use]
397 pub fn is_numeric(&self) -> bool {
398 matches!(
399 self,
400 ColumnType::Uint8
401 | ColumnType::TinyInt
402 | ColumnType::SmallInt
403 | ColumnType::Int
404 | ColumnType::BigInt
405 | ColumnType::Int128
406 | ColumnType::Scalar
407 | ColumnType::Decimal75(_, _)
408 )
409 }
410
411 #[must_use]
413 pub fn is_integer(&self) -> bool {
414 matches!(
415 self,
416 ColumnType::Uint8
417 | ColumnType::TinyInt
418 | ColumnType::SmallInt
419 | ColumnType::Int
420 | ColumnType::BigInt
421 | ColumnType::Int128
422 )
423 }
424
425 #[must_use]
429 #[cfg_attr(not(test), expect(dead_code))]
430 #[expect(clippy::trivially_copy_pass_by_ref)]
431 fn sqrt_negative_min(&self) -> Option<u64> {
432 match self {
433 ColumnType::TinyInt => Some(11),
434 ColumnType::SmallInt => Some(181),
435 ColumnType::Int => Some(46_340),
436 ColumnType::BigInt => Some(3_037_000_499),
437 ColumnType::Int128 => Some(13_043_817_825_332_782_212),
438 _ => None,
439 }
440 }
441
442 fn to_integer_bits(self) -> Option<usize> {
444 match self {
445 ColumnType::Uint8 | ColumnType::TinyInt => Some(8),
446 ColumnType::SmallInt => Some(16),
447 ColumnType::Int => Some(32),
448 ColumnType::BigInt => Some(64),
449 ColumnType::Int128 => Some(128),
450 _ => None,
451 }
452 }
453
454 fn from_signed_integer_bits(bits: usize) -> Option<Self> {
458 match bits {
459 8 => Some(ColumnType::TinyInt),
460 16 => Some(ColumnType::SmallInt),
461 32 => Some(ColumnType::Int),
462 64 => Some(ColumnType::BigInt),
463 128 => Some(ColumnType::Int128),
464 _ => None,
465 }
466 }
467
468 fn from_unsigned_integer_bits(bits: usize) -> Option<Self> {
472 match bits {
473 8 => Some(ColumnType::Uint8),
474 _ => None,
475 }
476 }
477
478 #[must_use]
482 pub fn max_integer_type(&self, other: &Self) -> Option<Self> {
483 if !self.is_integer() || !other.is_integer() {
485 return None;
486 }
487 self.to_integer_bits().and_then(|self_bits| {
488 other
489 .to_integer_bits()
490 .and_then(|other_bits| Self::from_signed_integer_bits(self_bits.max(other_bits)))
491 })
492 }
493
494 #[must_use]
498 pub fn max_unsigned_integer_type(&self, other: &Self) -> Option<Self> {
499 if !self.is_integer() || !other.is_integer() {
501 return None;
502 }
503 self.to_integer_bits().and_then(|self_bits| {
504 other
505 .to_integer_bits()
506 .and_then(|other_bits| Self::from_unsigned_integer_bits(self_bits.max(other_bits)))
507 })
508 }
509
510 #[must_use]
512 pub fn precision_value(&self) -> Option<u8> {
513 match self {
514 Self::Uint8 | Self::TinyInt => Some(3_u8),
515 Self::SmallInt => Some(5_u8),
516 Self::Int => Some(10_u8),
517 Self::BigInt | Self::TimestampTZ(_, _) => Some(19_u8),
518 Self::Int128 => Some(39_u8),
519 Self::Decimal75(precision, _) => Some(precision.value()),
520 Self::Scalar => Some(0_u8),
523 Self::Boolean | Self::VarChar | Self::VarBinary => None,
524 }
525 }
526 #[must_use]
528 pub fn scale(&self) -> Option<i8> {
529 match self {
530 Self::Decimal75(_, scale) => Some(*scale),
531 Self::TinyInt
532 | Self::Uint8
533 | Self::SmallInt
534 | Self::Int
535 | Self::BigInt
536 | Self::Int128
537 | Self::Scalar => Some(0),
538 Self::Boolean | Self::VarBinary | Self::VarChar => None,
539 Self::TimestampTZ(tu, _) => match tu {
540 PoSQLTimeUnit::Second => Some(0),
541 PoSQLTimeUnit::Millisecond => Some(3),
542 PoSQLTimeUnit::Microsecond => Some(6),
543 PoSQLTimeUnit::Nanosecond => Some(9),
544 },
545 }
546 }
547
548 #[must_use]
550 pub fn byte_size(&self) -> usize {
551 match self {
552 Self::Boolean => size_of::<bool>(),
553 Self::Uint8 => size_of::<u8>(),
554 Self::TinyInt => size_of::<i8>(),
555 Self::SmallInt => size_of::<i16>(),
556 Self::Int => size_of::<i32>(),
557 Self::BigInt | Self::TimestampTZ(_, _) => size_of::<i64>(),
558 Self::Int128 => size_of::<i128>(),
559 Self::Scalar | Self::Decimal75(_, _) | Self::VarBinary | Self::VarChar => {
560 size_of::<[u64; 4]>()
561 }
562 }
563 }
564
565 #[expect(clippy::cast_possible_truncation)]
566 #[must_use]
568 pub fn bit_size(&self) -> u32 {
569 self.byte_size() as u32 * 8
570 }
571
572 #[must_use]
574 pub const fn is_signed(&self) -> bool {
575 match self {
576 Self::TinyInt
577 | Self::SmallInt
578 | Self::Int
579 | Self::BigInt
580 | Self::Int128
581 | Self::TimestampTZ(_, _) => true,
582 Self::Decimal75(_, _)
583 | Self::Scalar
584 | Self::VarBinary
585 | Self::VarChar
586 | Self::Boolean
587 | Self::Uint8 => false,
588 }
589 }
590
591 #[must_use]
593 pub fn min_scalar<S: Scalar>(&self) -> Option<S> {
594 match self {
595 ColumnType::TinyInt => Some(S::from(i8::MIN)),
596 ColumnType::SmallInt => Some(S::from(i16::MIN)),
597 ColumnType::Int => Some(S::from(i32::MIN)),
598 ColumnType::BigInt => Some(S::from(i64::MIN)),
599 ColumnType::Int128 => Some(S::from(i128::MIN)),
600 _ => None,
601 }
602 }
603}
604
605impl Display for ColumnType {
607 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
608 match self {
609 ColumnType::Boolean => write!(f, "BOOLEAN"),
610 ColumnType::Uint8 => write!(f, "UINT8"),
611 ColumnType::TinyInt => write!(f, "TINYINT"),
612 ColumnType::SmallInt => write!(f, "SMALLINT"),
613 ColumnType::Int => write!(f, "INT"),
614 ColumnType::BigInt => write!(f, "BIGINT"),
615 ColumnType::Int128 => write!(f, "DECIMAL"),
616 ColumnType::Decimal75(precision, scale) => {
617 write!(
618 f,
619 "DECIMAL75(PRECISION: {:?}, SCALE: {scale})",
620 precision.value()
621 )
622 }
623 ColumnType::VarChar => write!(f, "VARCHAR"),
624 ColumnType::VarBinary => write!(f, "BINARY"),
625 ColumnType::Scalar => write!(f, "SCALAR"),
626 ColumnType::TimestampTZ(timeunit, timezone) => {
627 write!(f, "TIMESTAMP(TIMEUNIT: {timeunit}, TIMEZONE: {timezone})")
628 }
629 }
630 }
631}
632
633#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)]
635pub struct ColumnRef {
636 column_id: Ident,
637 table_ref: TableRef,
638 column_type: ColumnType,
639}
640
641impl ColumnRef {
642 #[must_use]
644 pub fn new(table_ref: TableRef, column_id: Ident, column_type: ColumnType) -> Self {
645 Self {
646 column_id,
647 table_ref,
648 column_type,
649 }
650 }
651
652 #[must_use]
654 pub fn table_ref(&self) -> TableRef {
655 self.table_ref.clone()
656 }
657
658 #[must_use]
660 pub fn column_id(&self) -> Ident {
661 self.column_id.clone()
662 }
663
664 #[must_use]
666 pub fn column_type(&self) -> &ColumnType {
667 &self.column_type
668 }
669}
670
671#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)]
676pub struct ColumnField {
677 name: Ident,
678 data_type: ColumnType,
679}
680
681impl ColumnField {
682 #[must_use]
684 pub fn new(name: Ident, data_type: ColumnType) -> ColumnField {
685 ColumnField { name, data_type }
686 }
687
688 #[must_use]
690 pub fn name(&self) -> Ident {
691 self.name.clone()
692 }
693
694 #[must_use]
696 pub fn data_type(&self) -> ColumnType {
697 self.data_type
698 }
699}
700
701#[cfg(test)]
702mod tests {
703 use super::*;
704 use crate::{base::scalar::test_scalar::TestScalar, proof_primitive::dory::DoryScalar};
705 use alloc::{string::String, vec};
706
707 #[test]
708 fn column_type_serializes_to_string() {
709 let column_type = ColumnType::TimestampTZ(PoSQLTimeUnit::Second, PoSQLTimeZone::utc());
710 let serialized = serde_json::to_string(&column_type).unwrap();
711 assert_eq!(serialized, r#"{"TimestampTZ":["Second",{"offset":0}]}"#);
712
713 let column_type = ColumnType::Boolean;
714 let serialized = serde_json::to_string(&column_type).unwrap();
715 assert_eq!(serialized, r#""Boolean""#);
716
717 let column_type = ColumnType::TinyInt;
718 let serialized = serde_json::to_string(&column_type).unwrap();
719 assert_eq!(serialized, r#""TinyInt""#);
720
721 let column_type = ColumnType::SmallInt;
722 let serialized = serde_json::to_string(&column_type).unwrap();
723 assert_eq!(serialized, r#""SmallInt""#);
724
725 let column_type = ColumnType::Int;
726 let serialized = serde_json::to_string(&column_type).unwrap();
727 assert_eq!(serialized, r#""Int""#);
728
729 let column_type = ColumnType::BigInt;
730 let serialized = serde_json::to_string(&column_type).unwrap();
731 assert_eq!(serialized, r#""BigInt""#);
732
733 let column_type = ColumnType::Int128;
734 let serialized = serde_json::to_string(&column_type).unwrap();
735 assert_eq!(serialized, r#""Decimal""#);
736
737 let column_type = ColumnType::VarChar;
738 let serialized = serde_json::to_string(&column_type).unwrap();
739 assert_eq!(serialized, r#""VarChar""#);
740
741 let column_type = ColumnType::Scalar;
742 let serialized = serde_json::to_string(&column_type).unwrap();
743 assert_eq!(serialized, r#""Scalar""#);
744
745 let column_type = ColumnType::Decimal75(Precision::new(1).unwrap(), 0);
746 let serialized = serde_json::to_string(&column_type).unwrap();
747 assert_eq!(serialized, r#"{"Decimal75":[1,0]}"#);
748 }
749
750 #[test]
751 fn we_can_deserialize_columns_from_valid_strings() {
752 let expected_column_type =
753 ColumnType::TimestampTZ(PoSQLTimeUnit::Second, PoSQLTimeZone::utc());
754 let deserialized: ColumnType =
755 serde_json::from_str(r#"{"TimestampTZ":["Second",{"offset":0}]}"#).unwrap();
756 assert_eq!(deserialized, expected_column_type);
757
758 let expected_column_type = ColumnType::Boolean;
759 let deserialized: ColumnType = serde_json::from_str(r#""Boolean""#).unwrap();
760 assert_eq!(deserialized, expected_column_type);
761
762 let expected_column_type = ColumnType::TinyInt;
763 let deserialized: ColumnType = serde_json::from_str(r#""TinyInt""#).unwrap();
764 assert_eq!(deserialized, expected_column_type);
765
766 let expected_column_type = ColumnType::SmallInt;
767 let deserialized: ColumnType = serde_json::from_str(r#""SmallInt""#).unwrap();
768 assert_eq!(deserialized, expected_column_type);
769
770 let expected_column_type = ColumnType::Int;
771 let deserialized: ColumnType = serde_json::from_str(r#""Int""#).unwrap();
772 assert_eq!(deserialized, expected_column_type);
773
774 let expected_column_type = ColumnType::BigInt;
775 let deserialized: ColumnType = serde_json::from_str(r#""BigInt""#).unwrap();
776 assert_eq!(deserialized, expected_column_type);
777
778 let expected_column_type = ColumnType::TinyInt;
779 let deserialized: ColumnType = serde_json::from_str(r#""TINYINT""#).unwrap();
780 assert_eq!(deserialized, expected_column_type);
781
782 let expected_column_type = ColumnType::SmallInt;
783 let deserialized: ColumnType = serde_json::from_str(r#""SMALLINT""#).unwrap();
784 assert_eq!(deserialized, expected_column_type);
785
786 let expected_column_type = ColumnType::Int128;
787 let deserialized: ColumnType = serde_json::from_str(r#""DECIMAL""#).unwrap();
788 assert_eq!(deserialized, expected_column_type);
789
790 let expected_column_type = ColumnType::Int128;
791 let deserialized: ColumnType = serde_json::from_str(r#""Decimal""#).unwrap();
792 assert_eq!(deserialized, expected_column_type);
793
794 let expected_column_type = ColumnType::VarChar;
795 let deserialized: ColumnType = serde_json::from_str(r#""VarChar""#).unwrap();
796 assert_eq!(deserialized, expected_column_type);
797
798 let expected_column_type = ColumnType::Scalar;
799 let deserialized: ColumnType = serde_json::from_str(r#""SCALAR""#).unwrap();
800 assert_eq!(deserialized, expected_column_type);
801
802 let expected_column_type = ColumnType::Decimal75(Precision::new(75).unwrap(), i8::MAX);
803 let deserialized: ColumnType = serde_json::from_str(r#"{"Decimal75":[75, 127]}"#).unwrap();
804 assert_eq!(deserialized, expected_column_type);
805
806 let expected_column_type =
807 ColumnType::Decimal75(Precision::new(u8::MIN + 1).unwrap(), i8::MIN);
808 let deserialized: ColumnType = serde_json::from_str(r#"{"Decimal75":[1, -128]}"#).unwrap();
809 assert_eq!(deserialized, expected_column_type);
810
811 let expected_column_type = ColumnType::Decimal75(Precision::new(1).unwrap(), 0);
812 let deserialized: ColumnType = serde_json::from_str(r#"{"Decimal75":[1, 0]}"#).unwrap();
813 assert_eq!(deserialized, expected_column_type);
814 }
815
816 #[test]
817 fn we_can_deserialize_columns_from_lowercase_or_uppercase_strings() {
818 assert_eq!(
819 serde_json::from_str::<ColumnType>(r#""boolean""#).unwrap(),
820 ColumnType::Boolean
821 );
822 assert_eq!(
823 serde_json::from_str::<ColumnType>(r#""BOOLEAN""#).unwrap(),
824 ColumnType::Boolean
825 );
826
827 assert_eq!(
828 serde_json::from_str::<ColumnType>(r#""bigint""#).unwrap(),
829 ColumnType::BigInt
830 );
831 assert_eq!(
832 serde_json::from_str::<ColumnType>(r#""BIGINT""#).unwrap(),
833 ColumnType::BigInt
834 );
835 assert_eq!(
836 serde_json::from_str::<ColumnType>(r#""TINYINT""#).unwrap(),
837 ColumnType::TinyInt
838 );
839 assert_eq!(
840 serde_json::from_str::<ColumnType>(r#""tinyint""#).unwrap(),
841 ColumnType::TinyInt
842 );
843 assert_eq!(
844 serde_json::from_str::<ColumnType>(r#""SMALLINT""#).unwrap(),
845 ColumnType::SmallInt
846 );
847 assert_eq!(
848 serde_json::from_str::<ColumnType>(r#""smallint""#).unwrap(),
849 ColumnType::SmallInt
850 );
851 assert_eq!(
852 serde_json::from_str::<ColumnType>(r#""int""#).unwrap(),
853 ColumnType::Int
854 );
855 assert_eq!(
856 serde_json::from_str::<ColumnType>(r#""INT""#).unwrap(),
857 ColumnType::Int
858 );
859 assert_eq!(
860 serde_json::from_str::<ColumnType>(r#""decimal""#).unwrap(),
861 ColumnType::Int128
862 );
863 assert_eq!(
864 serde_json::from_str::<ColumnType>(r#""DECIMAL""#).unwrap(),
865 ColumnType::Int128
866 );
867
868 assert_eq!(
869 serde_json::from_str::<ColumnType>(r#""VARCHAR""#).unwrap(),
870 ColumnType::VarChar
871 );
872 assert_eq!(
873 serde_json::from_str::<ColumnType>(r#""varchar""#).unwrap(),
874 ColumnType::VarChar
875 );
876
877 assert_eq!(
878 serde_json::from_str::<ColumnType>(r#""SCALAR""#).unwrap(),
879 ColumnType::Scalar
880 );
881 assert_eq!(
882 serde_json::from_str::<ColumnType>(r#""scalar""#).unwrap(),
883 ColumnType::Scalar
884 );
885 assert_eq!(
886 serde_json::from_str::<ColumnType>(r#"{"decimal75":[1,0]}"#).unwrap(),
887 ColumnType::Decimal75(Precision::new(1).unwrap(), 0)
888 );
889 assert_eq!(
890 serde_json::from_str::<ColumnType>(r#"{"DECIMAL75":[1,0]}"#).unwrap(),
891 ColumnType::Decimal75(Precision::new(1).unwrap(), 0)
892 );
893
894 assert_eq!(
895 serde_json::from_str::<ColumnType>(r#"{"decimal75":[10,5]}"#).unwrap(),
896 ColumnType::Decimal75(Precision::new(10).unwrap(), 5)
897 );
898
899 assert_eq!(
900 serde_json::from_str::<ColumnType>(r#"{"DECIMAL75":[1,-128]}"#).unwrap(),
901 ColumnType::Decimal75(Precision::new(1).unwrap(), -128)
902 );
903 }
904
905 #[test]
906 fn we_cannot_deserialize_columns_from_invalid_strings() {
907 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""BooLean""#);
908 assert!(deserialized.is_err());
909
910 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""Tinyint""#);
911 assert!(deserialized.is_err());
912
913 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""Smallint""#);
914 assert!(deserialized.is_err());
915
916 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""iNt""#);
917 assert!(deserialized.is_err());
918
919 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""Bigint""#);
920 assert!(deserialized.is_err());
921
922 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""DecImal""#);
923 assert!(deserialized.is_err());
924
925 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""DecImal75""#);
926 assert!(deserialized.is_err());
927
928 let deserialized: Result<ColumnType, _> =
929 serde_json::from_str(r#"{"TimestampTZ":["Utc","Second"]}"#);
930 assert!(deserialized.is_err());
931
932 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""Varchar""#);
933 assert!(deserialized.is_err());
934
935 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""ScaLar""#);
936 assert!(deserialized.is_err());
937 }
938
939 #[test]
940 fn we_can_convert_columntype_to_json_string_and_back() {
941 let boolean = ColumnType::Boolean;
942 let boolean_json = serde_json::to_string(&boolean).unwrap();
943 assert_eq!(boolean_json, "\"Boolean\"");
944 assert_eq!(
945 serde_json::from_str::<ColumnType>(&boolean_json).unwrap(),
946 boolean
947 );
948
949 let tinyint = ColumnType::TinyInt;
950 let tinyint_json = serde_json::to_string(&tinyint).unwrap();
951 assert_eq!(tinyint_json, "\"TinyInt\"");
952 assert_eq!(
953 serde_json::from_str::<ColumnType>(&tinyint_json).unwrap(),
954 tinyint
955 );
956
957 let smallint = ColumnType::SmallInt;
958 let smallint_json = serde_json::to_string(&smallint).unwrap();
959 assert_eq!(smallint_json, "\"SmallInt\"");
960 assert_eq!(
961 serde_json::from_str::<ColumnType>(&smallint_json).unwrap(),
962 smallint
963 );
964
965 let int = ColumnType::Int;
966 let int_json = serde_json::to_string(&int).unwrap();
967 assert_eq!(int_json, "\"Int\"");
968 assert_eq!(serde_json::from_str::<ColumnType>(&int_json).unwrap(), int);
969
970 let bigint = ColumnType::BigInt;
971 let bigint_json = serde_json::to_string(&bigint).unwrap();
972 assert_eq!(bigint_json, "\"BigInt\"");
973 assert_eq!(
974 serde_json::from_str::<ColumnType>(&bigint_json).unwrap(),
975 bigint
976 );
977
978 let int128 = ColumnType::Int128;
979 let int128_json = serde_json::to_string(&int128).unwrap();
980 assert_eq!(int128_json, "\"Decimal\"");
981 assert_eq!(
982 serde_json::from_str::<ColumnType>(&int128_json).unwrap(),
983 int128
984 );
985
986 let varchar = ColumnType::VarChar;
987 let varchar_json = serde_json::to_string(&varchar).unwrap();
988 assert_eq!(varchar_json, "\"VarChar\"");
989 assert_eq!(
990 serde_json::from_str::<ColumnType>(&varchar_json).unwrap(),
991 varchar
992 );
993
994 let scalar = ColumnType::Scalar;
995 let scalar_json = serde_json::to_string(&scalar).unwrap();
996 assert_eq!(scalar_json, "\"Scalar\"");
997 assert_eq!(
998 serde_json::from_str::<ColumnType>(&scalar_json).unwrap(),
999 scalar
1000 );
1001
1002 let decimal75 = ColumnType::Decimal75(Precision::new(75).unwrap(), 0);
1003 let decimal75_json = serde_json::to_string(&decimal75).unwrap();
1004 assert_eq!(decimal75_json, r#"{"Decimal75":[75,0]}"#);
1005 assert_eq!(
1006 serde_json::from_str::<ColumnType>(&decimal75_json).unwrap(),
1007 decimal75
1008 );
1009 }
1010
1011 #[test]
1012 fn we_can_get_the_len_of_a_column() {
1013 let precision = 10;
1014 let scale = 2;
1015
1016 let scalar_values = [
1017 TestScalar::from(1),
1018 TestScalar::from(2),
1019 TestScalar::from(3),
1020 ];
1021
1022 let column = Column::<DoryScalar>::Boolean(&[true, false, true]);
1024 assert_eq!(column.len(), 3);
1025 assert!(!column.is_empty());
1026
1027 let column = Column::<DoryScalar>::TinyInt(&[1, 2, 3]);
1028 assert_eq!(column.len(), 3);
1029 assert!(!column.is_empty());
1030
1031 let column = Column::<TestScalar>::SmallInt(&[1, 2, 3]);
1032 assert_eq!(column.len(), 3);
1033 assert!(!column.is_empty());
1034
1035 let column = Column::<TestScalar>::Int(&[1, 2, 3]);
1036 assert_eq!(column.len(), 3);
1037 assert!(!column.is_empty());
1038
1039 let column = Column::<TestScalar>::BigInt(&[1, 2, 3]);
1040 assert_eq!(column.len(), 3);
1041 assert!(!column.is_empty());
1042
1043 let column = Column::VarChar((&["a", "b", "c"], &scalar_values));
1044 assert_eq!(column.len(), 3);
1045 assert!(!column.is_empty());
1046
1047 let column = Column::<DoryScalar>::Int128(&[1, 2, 3]);
1048 assert_eq!(column.len(), 3);
1049 assert!(!column.is_empty());
1050
1051 let column = Column::Scalar(&scalar_values);
1052 assert_eq!(column.len(), 3);
1053 assert!(!column.is_empty());
1054
1055 let decimal_data = [
1056 TestScalar::from(1),
1057 TestScalar::from(2),
1058 TestScalar::from(3),
1059 ];
1060
1061 let precision = Precision::new(precision).unwrap();
1062 let column = Column::Decimal75(precision, scale, &decimal_data);
1063 assert_eq!(column.len(), 3);
1064 assert!(!column.is_empty());
1065
1066 let column = Column::<DoryScalar>::Boolean(&[]);
1068 assert_eq!(column.len(), 0);
1069 assert!(column.is_empty());
1070
1071 let column = Column::<DoryScalar>::TinyInt(&[]);
1072 assert_eq!(column.len(), 0);
1073 assert!(column.is_empty());
1074
1075 let column = Column::<TestScalar>::SmallInt(&[]);
1076 assert_eq!(column.len(), 0);
1077 assert!(column.is_empty());
1078
1079 let column = Column::<TestScalar>::Int(&[]);
1080 assert_eq!(column.len(), 0);
1081 assert!(column.is_empty());
1082
1083 let column = Column::<TestScalar>::BigInt(&[]);
1084 assert_eq!(column.len(), 0);
1085 assert!(column.is_empty());
1086
1087 let column = Column::<DoryScalar>::VarChar((&[], &[]));
1088 assert_eq!(column.len(), 0);
1089 assert!(column.is_empty());
1090
1091 let column = Column::<TestScalar>::Int128(&[]);
1092 assert_eq!(column.len(), 0);
1093 assert!(column.is_empty());
1094
1095 let column = Column::<DoryScalar>::Scalar(&[]);
1096 assert_eq!(column.len(), 0);
1097 assert!(column.is_empty());
1098
1099 let column: Column<'_, TestScalar> = Column::Decimal75(precision, scale, &[]);
1100 assert_eq!(column.len(), 0);
1101 assert!(column.is_empty());
1102 }
1103
1104 #[test]
1105 fn we_can_convert_owned_columns_to_columns_round_trip() {
1106 let alloc = Bump::new();
1107 let owned_col: OwnedColumn<TestScalar> = OwnedColumn::Int128(vec![1, 2, 3, 4, 5]);
1109 let col = Column::<TestScalar>::from_owned_column(&owned_col, &alloc);
1110 assert_eq!(col, Column::Int128(&[1, 2, 3, 4, 5]));
1111 let new_owned_col = (&col).into();
1112 assert_eq!(owned_col, new_owned_col);
1113
1114 let owned_col: OwnedColumn<TestScalar> =
1116 OwnedColumn::Boolean(vec![true, false, true, false, true]);
1117 let col = Column::<TestScalar>::from_owned_column(&owned_col, &alloc);
1118 assert_eq!(col, Column::Boolean(&[true, false, true, false, true]));
1119 let new_owned_col = (&col).into();
1120 assert_eq!(owned_col, new_owned_col);
1121
1122 let strs = [
1124 "Space and Time",
1125 "Tér és Idő",
1126 "Пространство и время",
1127 "Spațiu și Timp",
1128 "Spazju u Ħin",
1129 ];
1130 let scalars = strs.iter().map(TestScalar::from).collect::<Vec<_>>();
1131 let owned_col = OwnedColumn::VarChar(
1132 strs.iter()
1133 .map(ToString::to_string)
1134 .collect::<Vec<String>>(),
1135 );
1136 let col = Column::<TestScalar>::from_owned_column(&owned_col, &alloc);
1137 assert_eq!(col, Column::VarChar((&strs, &scalars)));
1138 let new_owned_col = (&col).into();
1139 assert_eq!(owned_col, new_owned_col);
1140
1141 let scalars: Vec<TestScalar> = [1, 2, 3, 4, 5].iter().map(TestScalar::from).collect();
1143 let owned_col: OwnedColumn<TestScalar> =
1144 OwnedColumn::Decimal75(Precision::new(75).unwrap(), 127, scalars.clone());
1145 let col = Column::<TestScalar>::from_owned_column(&owned_col, &alloc);
1146 assert_eq!(
1147 col,
1148 Column::Decimal75(Precision::new(75).unwrap(), 127, &scalars)
1149 );
1150 let new_owned_col = (&col).into();
1151 assert_eq!(owned_col, new_owned_col);
1152 }
1153
1154 #[test]
1155 fn we_can_get_the_data_size_of_a_column() {
1156 let column = Column::<DoryScalar>::Boolean(&[true, false, true]);
1157 assert_eq!(column.column_type().byte_size(), 1);
1158 assert_eq!(column.column_type().bit_size(), 8);
1159
1160 let column = Column::<TestScalar>::TinyInt(&[1, 2, 3, 4]);
1161 assert_eq!(column.column_type().byte_size(), 1);
1162 assert_eq!(column.column_type().bit_size(), 8);
1163
1164 let column = Column::<TestScalar>::SmallInt(&[1, 2, 3, 4]);
1165 assert_eq!(column.column_type().byte_size(), 2);
1166 assert_eq!(column.column_type().bit_size(), 16);
1167
1168 let column = Column::<TestScalar>::Int(&[1, 2, 3]);
1169 assert_eq!(column.column_type().byte_size(), 4);
1170 assert_eq!(column.column_type().bit_size(), 32);
1171
1172 let column = Column::<TestScalar>::BigInt(&[1]);
1173 assert_eq!(column.column_type().byte_size(), 8);
1174 assert_eq!(column.column_type().bit_size(), 64);
1175
1176 let column = Column::<DoryScalar>::Int128(&[1, 2]);
1177 assert_eq!(column.column_type().byte_size(), 16);
1178 assert_eq!(column.column_type().bit_size(), 128);
1179
1180 let scalar_values = [
1181 TestScalar::from(1),
1182 TestScalar::from(2),
1183 TestScalar::from(3),
1184 ];
1185
1186 let column = Column::VarChar((&["a", "b", "c", "d", "e"], &scalar_values));
1187 assert_eq!(column.column_type().byte_size(), 32);
1188 assert_eq!(column.column_type().bit_size(), 256);
1189
1190 let column = Column::Scalar(&scalar_values);
1191 assert_eq!(column.column_type().byte_size(), 32);
1192 assert_eq!(column.column_type().bit_size(), 256);
1193
1194 let precision = 10;
1195 let scale = 2;
1196 let decimal_data = [
1197 TestScalar::from(1),
1198 TestScalar::from(2),
1199 TestScalar::from(3),
1200 ];
1201
1202 let precision = Precision::new(precision).unwrap();
1203 let column = Column::Decimal75(precision, scale, &decimal_data);
1204 assert_eq!(column.column_type().byte_size(), 32);
1205 assert_eq!(column.column_type().bit_size(), 256);
1206
1207 let column: Column<'_, DoryScalar> =
1208 Column::TimestampTZ(PoSQLTimeUnit::Second, PoSQLTimeZone::utc(), &[1, 2, 3]);
1209 assert_eq!(column.column_type().byte_size(), 8);
1210 assert_eq!(column.column_type().bit_size(), 64);
1211 }
1212
1213 #[test]
1214 fn we_can_get_length_of_varbinary_column() {
1215 let raw_bytes: &[&[u8]] = &[b"foo", b"bar", b""];
1216 let scalars: Vec<TestScalar> = raw_bytes
1217 .iter()
1218 .map(|b| TestScalar::from_le_bytes_mod_order(b))
1219 .collect();
1220
1221 let column = Column::VarBinary((raw_bytes, &scalars));
1222 assert_eq!(column.len(), 3);
1223 assert!(!column.is_empty());
1224 assert_eq!(column.column_type(), ColumnType::VarBinary);
1225 }
1226
1227 #[test]
1228 fn we_can_convert_varbinary_owned_column_to_column_and_back() {
1229 use bumpalo::Bump;
1230 let alloc = Bump::new();
1231
1232 let owned_varbinary = OwnedColumn::VarBinary(vec![b"abc".to_vec(), b"xyz".to_vec()]);
1233
1234 let column = Column::<TestScalar>::from_owned_column(&owned_varbinary, &alloc);
1235 match column {
1236 Column::VarBinary((bytes, scalars)) => {
1237 assert_eq!(bytes.len(), 2);
1238 assert_eq!(scalars.len(), 2);
1239 assert_eq!(bytes[0], b"abc");
1240 assert_eq!(bytes[1], b"xyz");
1241 }
1242 _ => panic!("Expected VarBinary column"),
1243 }
1244
1245 let round_trip_owned: OwnedColumn<TestScalar> = (&column).into();
1246 assert_eq!(owned_varbinary, round_trip_owned);
1247 }
1248
1249 #[test]
1250 fn we_can_get_min_scalar() {
1251 assert_eq!(
1252 ColumnType::TinyInt.min_scalar(),
1253 Some(TestScalar::from(i8::MIN))
1254 );
1255 assert_eq!(
1256 ColumnType::SmallInt.min_scalar(),
1257 Some(TestScalar::from(i16::MIN))
1258 );
1259 assert_eq!(
1260 ColumnType::Int.min_scalar(),
1261 Some(TestScalar::from(i32::MIN))
1262 );
1263 assert_eq!(
1264 ColumnType::BigInt.min_scalar(),
1265 Some(TestScalar::from(i64::MIN))
1266 );
1267 assert_eq!(
1268 ColumnType::Int128.min_scalar(),
1269 Some(TestScalar::from(i128::MIN))
1270 );
1271 assert_eq!(ColumnType::Uint8.min_scalar::<TestScalar>(), None);
1272 assert_eq!(ColumnType::Scalar.min_scalar::<TestScalar>(), None);
1273 assert_eq!(ColumnType::Boolean.min_scalar::<TestScalar>(), None);
1274 assert_eq!(ColumnType::VarBinary.min_scalar::<TestScalar>(), None);
1275 assert_eq!(
1276 ColumnType::TimestampTZ(PoSQLTimeUnit::Second, PoSQLTimeZone::new(0))
1277 .min_scalar::<TestScalar>(),
1278 None
1279 );
1280 assert_eq!(
1281 ColumnType::Decimal75(Precision::new(1).unwrap(), 1).min_scalar::<TestScalar>(),
1282 None
1283 );
1284 assert_eq!(ColumnType::VarChar.min_scalar::<TestScalar>(), None);
1285 }
1286
1287 #[test]
1288 fn we_can_get_sqrt_negative_min() {
1289 for column_type in [
1290 ColumnType::TinyInt,
1291 ColumnType::SmallInt,
1292 ColumnType::Int,
1293 ColumnType::BigInt,
1294 ColumnType::Int128,
1295 ] {
1296 let floor = TestScalar::from(column_type.sqrt_negative_min().unwrap());
1297 let ceiling = floor + TestScalar::ONE;
1298 let floor_squared = floor * floor;
1299 let ceiling_squared = ceiling * ceiling;
1300 let negative_min_scalar = -column_type.min_scalar::<TestScalar>().unwrap();
1301 assert!(floor_squared <= negative_min_scalar);
1302 assert!(negative_min_scalar < ceiling_squared);
1303 }
1304 for column_type in [
1305 ColumnType::Uint8,
1306 ColumnType::Scalar,
1307 ColumnType::Boolean,
1308 ColumnType::VarBinary,
1309 ColumnType::TimestampTZ(PoSQLTimeUnit::Second, PoSQLTimeZone::new(1)),
1310 ColumnType::Decimal75(Precision::new(1).unwrap(), 1),
1311 ColumnType::VarChar,
1312 ] {
1313 assert_eq!(column_type.sqrt_negative_min(), None);
1314 }
1315 }
1316}