1use super::{LiteralValue, OwnedColumn, TableRef};
2use crate::base::{
3 math::decimal::Precision,
4 scalar::{Scalar, ScalarExt},
5 slice_ops::slice_cast_with,
6};
7use alloc::vec::Vec;
8use bumpalo::Bump;
9use core::{
10 fmt,
11 fmt::{Display, Formatter},
12 mem::size_of,
13};
14use proof_of_sql_parser::posql_time::{PoSQLTimeUnit, PoSQLTimeZone};
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 }
152 }
153
154 pub fn rho(length: usize, alloc: &'a Bump) -> Self {
156 let raw_rho = (0..length as i128).collect::<Vec<_>>();
157 let rho = alloc.alloc_slice_copy(raw_rho.as_slice());
158 Column::<S>::Int128(rho as &[_])
159 }
160
161 pub fn from_owned_column(owned_column: &'a OwnedColumn<S>, alloc: &'a Bump) -> Self {
163 match owned_column {
164 OwnedColumn::Boolean(col) => Column::Boolean(col.as_slice()),
165 OwnedColumn::Uint8(col) => Column::Uint8(col.as_slice()),
166 OwnedColumn::TinyInt(col) => Column::TinyInt(col.as_slice()),
167 OwnedColumn::SmallInt(col) => Column::SmallInt(col.as_slice()),
168 OwnedColumn::Int(col) => Column::Int(col.as_slice()),
169 OwnedColumn::BigInt(col) => Column::BigInt(col.as_slice()),
170 OwnedColumn::Int128(col) => Column::Int128(col.as_slice()),
171 OwnedColumn::Decimal75(precision, scale, col) => {
172 Column::Decimal75(*precision, *scale, col.as_slice())
173 }
174 OwnedColumn::Scalar(col) => Column::Scalar(col.as_slice()),
175 OwnedColumn::VarChar(col) => {
176 let scalars = col.iter().map(S::from).collect::<Vec<_>>();
177 let strs = col
178 .iter()
179 .map(|s| s.as_str() as &'a str)
180 .collect::<Vec<_>>();
181 Column::VarChar((
182 alloc.alloc_slice_clone(strs.as_slice()),
183 alloc.alloc_slice_copy(scalars.as_slice()),
184 ))
185 }
186 OwnedColumn::VarBinary(col) => {
187 let scalars = col
188 .iter()
189 .map(|b| S::from_byte_slice_via_hash(b))
190 .collect::<Vec<_>>();
191 let bytes = col.iter().map(|s| s as &'a [u8]).collect::<Vec<_>>();
192 Column::VarBinary((
193 alloc.alloc_slice_clone(&bytes),
194 alloc.alloc_slice_copy(scalars.as_slice()),
195 ))
196 }
197 OwnedColumn::TimestampTZ(tu, tz, col) => Column::TimestampTZ(*tu, *tz, col.as_slice()),
198 }
199 }
200
201 pub(crate) fn as_boolean(&self) -> Option<&'a [bool]> {
203 match self {
204 Self::Boolean(col) => Some(col),
205 _ => None,
206 }
207 }
208
209 pub(crate) fn as_uint8(&self) -> Option<&'a [u8]> {
211 match self {
212 Self::Uint8(col) => Some(col),
213 _ => None,
214 }
215 }
216
217 pub(crate) fn as_tinyint(&self) -> Option<&'a [i8]> {
219 match self {
220 Self::TinyInt(col) => Some(col),
221 _ => None,
222 }
223 }
224
225 pub(crate) fn as_smallint(&self) -> Option<&'a [i16]> {
227 match self {
228 Self::SmallInt(col) => Some(col),
229 _ => None,
230 }
231 }
232
233 pub(crate) fn as_int(&self) -> Option<&'a [i32]> {
235 match self {
236 Self::Int(col) => Some(col),
237 _ => None,
238 }
239 }
240
241 pub(crate) fn as_bigint(&self) -> Option<&'a [i64]> {
243 match self {
244 Self::BigInt(col) => Some(col),
245 _ => None,
246 }
247 }
248
249 pub(crate) fn as_int128(&self) -> Option<&'a [i128]> {
251 match self {
252 Self::Int128(col) => Some(col),
253 _ => None,
254 }
255 }
256
257 pub(crate) fn as_scalar(&self) -> Option<&'a [S]> {
259 match self {
260 Self::Scalar(col) => Some(col),
261 _ => None,
262 }
263 }
264
265 pub(crate) fn as_decimal75(&self) -> Option<&'a [S]> {
267 match self {
268 Self::Decimal75(_, _, col) => Some(col),
269 _ => None,
270 }
271 }
272
273 pub(crate) fn as_varchar(&self) -> Option<(&'a [&'a str], &'a [S])> {
275 match self {
276 Self::VarChar((col, scals)) => Some((col, scals)),
277 _ => None,
278 }
279 }
280
281 pub(crate) fn as_varbinary(&self) -> Option<(&'a [&'a [u8]], &'a [S])> {
283 match self {
284 Self::VarBinary((col, scals)) => Some((col, scals)),
285 _ => None,
286 }
287 }
288
289 pub(crate) fn as_timestamptz(&self) -> Option<&'a [i64]> {
291 match self {
292 Self::TimestampTZ(_, _, col) => Some(col),
293 _ => None,
294 }
295 }
296
297 pub(crate) fn scalar_at(&self, index: usize) -> Option<S> {
301 (index < self.len()).then_some(match self {
302 Self::Boolean(col) => S::from(col[index]),
303 Self::Uint8(col) => S::from(col[index]),
304 Self::TinyInt(col) => S::from(col[index]),
305 Self::SmallInt(col) => S::from(col[index]),
306 Self::Int(col) => S::from(col[index]),
307 Self::BigInt(col) | Self::TimestampTZ(_, _, col) => S::from(col[index]),
308 Self::Int128(col) => S::from(col[index]),
309 Self::Scalar(col) | Self::Decimal75(_, _, col) => col[index],
310 Self::VarChar((_, scals)) | Self::VarBinary((_, scals)) => scals[index],
311 })
312 }
313
314 #[allow(clippy::missing_panics_doc)]
316 pub(crate) fn to_scalar_with_scaling(self, scale: i8) -> Vec<S> {
317 let scale_factor = S::pow10(u8::try_from(scale).expect("Upscale factor is nonnegative"));
318 match self {
319 Self::Boolean(col) => slice_cast_with(col, |b| S::from(b) * scale_factor),
320 Self::Decimal75(_, _, col) => slice_cast_with(col, |s| *s * scale_factor),
321 Self::VarChar((_, values)) => slice_cast_with(values, |s| *s * scale_factor),
322 Self::VarBinary((_, values)) => slice_cast_with(values, |s| *s * scale_factor),
323 Self::Uint8(col) => slice_cast_with(col, |i| S::from(i) * scale_factor),
324 Self::TinyInt(col) => slice_cast_with(col, |i| S::from(i) * scale_factor),
325 Self::SmallInt(col) => slice_cast_with(col, |i| S::from(i) * scale_factor),
326 Self::Int(col) => slice_cast_with(col, |i| S::from(i) * scale_factor),
327 Self::BigInt(col) => slice_cast_with(col, |i| S::from(i) * scale_factor),
328 Self::Int128(col) => slice_cast_with(col, |i| S::from(i) * scale_factor),
329 Self::Scalar(col) => slice_cast_with(col, |i| S::from(i) * scale_factor),
330 Self::TimestampTZ(_, _, col) => slice_cast_with(col, |i| S::from(i) * scale_factor),
331 }
332 }
333}
334
335#[derive(Eq, PartialEq, Debug, Clone, Hash, Serialize, Deserialize, Copy)]
341#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
342pub enum ColumnType {
343 #[serde(alias = "BOOLEAN", alias = "boolean")]
345 Boolean,
346 #[serde(alias = "UINT8", alias = "uint8")]
348 Uint8,
349 #[serde(alias = "TINYINT", alias = "tinyint")]
351 TinyInt,
352 #[serde(alias = "SMALLINT", alias = "smallint")]
354 SmallInt,
355 #[serde(alias = "INT", alias = "int")]
357 Int,
358 #[serde(alias = "BIGINT", alias = "bigint")]
360 BigInt,
361 #[serde(rename = "Decimal", alias = "DECIMAL", alias = "decimal")]
363 Int128,
364 #[serde(alias = "VARCHAR", alias = "varchar")]
366 VarChar,
367 #[serde(rename = "Decimal75", alias = "DECIMAL75", alias = "decimal75")]
369 Decimal75(Precision, i8),
370 #[serde(alias = "TIMESTAMP", alias = "timestamp")]
372 #[cfg_attr(test, proptest(skip))]
373 TimestampTZ(PoSQLTimeUnit, PoSQLTimeZone),
374 #[serde(alias = "SCALAR", alias = "scalar")]
376 #[cfg_attr(test, proptest(skip))]
377 Scalar,
378 #[serde(alias = "BINARY", alias = "BINARY")]
380 VarBinary,
381}
382
383impl ColumnType {
384 #[must_use]
386 pub fn is_numeric(&self) -> bool {
387 matches!(
388 self,
389 ColumnType::Uint8
390 | ColumnType::TinyInt
391 | ColumnType::SmallInt
392 | ColumnType::Int
393 | ColumnType::BigInt
394 | ColumnType::Int128
395 | ColumnType::Scalar
396 | ColumnType::Decimal75(_, _)
397 )
398 }
399
400 #[must_use]
402 pub fn is_integer(&self) -> bool {
403 matches!(
404 self,
405 ColumnType::Uint8
406 | ColumnType::TinyInt
407 | ColumnType::SmallInt
408 | ColumnType::Int
409 | ColumnType::BigInt
410 | ColumnType::Int128
411 )
412 }
413
414 fn to_integer_bits(self) -> Option<usize> {
416 match self {
417 ColumnType::Uint8 | ColumnType::TinyInt => Some(8),
418 ColumnType::SmallInt => Some(16),
419 ColumnType::Int => Some(32),
420 ColumnType::BigInt => Some(64),
421 ColumnType::Int128 => Some(128),
422 _ => None,
423 }
424 }
425
426 fn from_signed_integer_bits(bits: usize) -> Option<Self> {
430 match bits {
431 8 => Some(ColumnType::TinyInt),
432 16 => Some(ColumnType::SmallInt),
433 32 => Some(ColumnType::Int),
434 64 => Some(ColumnType::BigInt),
435 128 => Some(ColumnType::Int128),
436 _ => None,
437 }
438 }
439
440 fn from_unsigned_integer_bits(bits: usize) -> Option<Self> {
444 match bits {
445 8 => Some(ColumnType::Uint8),
446 _ => None,
447 }
448 }
449
450 #[must_use]
454 pub fn max_integer_type(&self, other: &Self) -> Option<Self> {
455 if !self.is_integer() || !other.is_integer() {
457 return None;
458 }
459 self.to_integer_bits().and_then(|self_bits| {
460 other
461 .to_integer_bits()
462 .and_then(|other_bits| Self::from_signed_integer_bits(self_bits.max(other_bits)))
463 })
464 }
465
466 #[must_use]
470 pub fn max_unsigned_integer_type(&self, other: &Self) -> Option<Self> {
471 if !self.is_integer() || !other.is_integer() {
473 return None;
474 }
475 self.to_integer_bits().and_then(|self_bits| {
476 other
477 .to_integer_bits()
478 .and_then(|other_bits| Self::from_unsigned_integer_bits(self_bits.max(other_bits)))
479 })
480 }
481
482 #[must_use]
484 pub fn precision_value(&self) -> Option<u8> {
485 match self {
486 Self::Uint8 | Self::TinyInt => Some(3_u8),
487 Self::SmallInt => Some(5_u8),
488 Self::Int => Some(10_u8),
489 Self::BigInt | Self::TimestampTZ(_, _) => Some(19_u8),
490 Self::Int128 => Some(39_u8),
491 Self::Decimal75(precision, _) => Some(precision.value()),
492 Self::Scalar => Some(0_u8),
495 Self::Boolean | Self::VarChar | Self::VarBinary => None,
496 }
497 }
498 #[must_use]
500 pub fn scale(&self) -> Option<i8> {
501 match self {
502 Self::Decimal75(_, scale) => Some(*scale),
503 Self::TinyInt
504 | Self::Uint8
505 | Self::SmallInt
506 | Self::Int
507 | Self::BigInt
508 | Self::Int128
509 | Self::Scalar => Some(0),
510 Self::Boolean | Self::VarBinary | Self::VarChar => None,
511 Self::TimestampTZ(tu, _) => match tu {
512 PoSQLTimeUnit::Second => Some(0),
513 PoSQLTimeUnit::Millisecond => Some(3),
514 PoSQLTimeUnit::Microsecond => Some(6),
515 PoSQLTimeUnit::Nanosecond => Some(9),
516 },
517 }
518 }
519
520 #[must_use]
522 pub fn byte_size(&self) -> usize {
523 match self {
524 Self::Boolean => size_of::<bool>(),
525 Self::Uint8 => size_of::<u8>(),
526 Self::TinyInt => size_of::<i8>(),
527 Self::SmallInt => size_of::<i16>(),
528 Self::Int => size_of::<i32>(),
529 Self::BigInt | Self::TimestampTZ(_, _) => size_of::<i64>(),
530 Self::Int128 => size_of::<i128>(),
531 Self::Scalar | Self::Decimal75(_, _) | Self::VarBinary | Self::VarChar => {
532 size_of::<[u64; 4]>()
533 }
534 }
535 }
536
537 #[allow(clippy::cast_possible_truncation)]
538 #[must_use]
540 pub fn bit_size(&self) -> u32 {
541 self.byte_size() as u32 * 8
542 }
543
544 #[must_use]
546 pub const fn is_signed(&self) -> bool {
547 match self {
548 Self::TinyInt
549 | Self::SmallInt
550 | Self::Int
551 | Self::BigInt
552 | Self::Int128
553 | Self::TimestampTZ(_, _) => true,
554 Self::Decimal75(_, _)
555 | Self::Scalar
556 | Self::VarBinary
557 | Self::VarChar
558 | Self::Boolean
559 | Self::Uint8 => false,
560 }
561 }
562
563 #[must_use]
565 pub fn min_scalar<S: Scalar>(&self) -> Option<S> {
566 match self {
567 ColumnType::TinyInt => Some(S::from(i8::MIN)),
568 ColumnType::SmallInt => Some(S::from(i16::MIN)),
569 ColumnType::Int => Some(S::from(i32::MIN)),
570 ColumnType::BigInt => Some(S::from(i64::MIN)),
571 ColumnType::Int128 => Some(S::from(i128::MIN)),
572 _ => None,
573 }
574 }
575}
576
577impl Display for ColumnType {
579 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
580 match self {
581 ColumnType::Boolean => write!(f, "BOOLEAN"),
582 ColumnType::Uint8 => write!(f, "UINT8"),
583 ColumnType::TinyInt => write!(f, "TINYINT"),
584 ColumnType::SmallInt => write!(f, "SMALLINT"),
585 ColumnType::Int => write!(f, "INT"),
586 ColumnType::BigInt => write!(f, "BIGINT"),
587 ColumnType::Int128 => write!(f, "DECIMAL"),
588 ColumnType::Decimal75(precision, scale) => {
589 write!(
590 f,
591 "DECIMAL75(PRECISION: {:?}, SCALE: {scale})",
592 precision.value()
593 )
594 }
595 ColumnType::VarChar => write!(f, "VARCHAR"),
596 ColumnType::VarBinary => write!(f, "BINARY"),
597 ColumnType::Scalar => write!(f, "SCALAR"),
598 ColumnType::TimestampTZ(timeunit, timezone) => {
599 write!(f, "TIMESTAMP(TIMEUNIT: {timeunit}, TIMEZONE: {timezone})")
600 }
601 }
602 }
603}
604
605#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)]
607pub struct ColumnRef {
608 column_id: Ident,
609 table_ref: TableRef,
610 column_type: ColumnType,
611}
612
613impl ColumnRef {
614 #[must_use]
616 pub fn new(table_ref: TableRef, column_id: Ident, column_type: ColumnType) -> Self {
617 Self {
618 column_id,
619 table_ref,
620 column_type,
621 }
622 }
623
624 #[must_use]
626 pub fn table_ref(&self) -> TableRef {
627 self.table_ref.clone()
628 }
629
630 #[must_use]
632 pub fn column_id(&self) -> Ident {
633 self.column_id.clone()
634 }
635
636 #[must_use]
638 pub fn column_type(&self) -> &ColumnType {
639 &self.column_type
640 }
641}
642
643#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)]
648pub struct ColumnField {
649 name: Ident,
650 data_type: ColumnType,
651}
652
653impl ColumnField {
654 #[must_use]
656 pub fn new(name: Ident, data_type: ColumnType) -> ColumnField {
657 ColumnField { name, data_type }
658 }
659
660 #[must_use]
662 pub fn name(&self) -> Ident {
663 self.name.clone()
664 }
665
666 #[must_use]
668 pub fn data_type(&self) -> ColumnType {
669 self.data_type
670 }
671}
672
673#[cfg(test)]
674mod tests {
675 use super::*;
676 use crate::{base::scalar::test_scalar::TestScalar, proof_primitive::dory::DoryScalar};
677 use alloc::{string::String, vec};
678
679 #[test]
680 fn column_type_serializes_to_string() {
681 let column_type = ColumnType::TimestampTZ(PoSQLTimeUnit::Second, PoSQLTimeZone::utc());
682 let serialized = serde_json::to_string(&column_type).unwrap();
683 assert_eq!(serialized, r#"{"TimestampTZ":["Second",{"offset":0}]}"#);
684
685 let column_type = ColumnType::Boolean;
686 let serialized = serde_json::to_string(&column_type).unwrap();
687 assert_eq!(serialized, r#""Boolean""#);
688
689 let column_type = ColumnType::TinyInt;
690 let serialized = serde_json::to_string(&column_type).unwrap();
691 assert_eq!(serialized, r#""TinyInt""#);
692
693 let column_type = ColumnType::SmallInt;
694 let serialized = serde_json::to_string(&column_type).unwrap();
695 assert_eq!(serialized, r#""SmallInt""#);
696
697 let column_type = ColumnType::Int;
698 let serialized = serde_json::to_string(&column_type).unwrap();
699 assert_eq!(serialized, r#""Int""#);
700
701 let column_type = ColumnType::BigInt;
702 let serialized = serde_json::to_string(&column_type).unwrap();
703 assert_eq!(serialized, r#""BigInt""#);
704
705 let column_type = ColumnType::Int128;
706 let serialized = serde_json::to_string(&column_type).unwrap();
707 assert_eq!(serialized, r#""Decimal""#);
708
709 let column_type = ColumnType::VarChar;
710 let serialized = serde_json::to_string(&column_type).unwrap();
711 assert_eq!(serialized, r#""VarChar""#);
712
713 let column_type = ColumnType::Scalar;
714 let serialized = serde_json::to_string(&column_type).unwrap();
715 assert_eq!(serialized, r#""Scalar""#);
716
717 let column_type = ColumnType::Decimal75(Precision::new(1).unwrap(), 0);
718 let serialized = serde_json::to_string(&column_type).unwrap();
719 assert_eq!(serialized, r#"{"Decimal75":[1,0]}"#);
720 }
721
722 #[test]
723 fn we_can_deserialize_columns_from_valid_strings() {
724 let expected_column_type =
725 ColumnType::TimestampTZ(PoSQLTimeUnit::Second, PoSQLTimeZone::utc());
726 let deserialized: ColumnType =
727 serde_json::from_str(r#"{"TimestampTZ":["Second",{"offset":0}]}"#).unwrap();
728 assert_eq!(deserialized, expected_column_type);
729
730 let expected_column_type = ColumnType::Boolean;
731 let deserialized: ColumnType = serde_json::from_str(r#""Boolean""#).unwrap();
732 assert_eq!(deserialized, expected_column_type);
733
734 let expected_column_type = ColumnType::TinyInt;
735 let deserialized: ColumnType = serde_json::from_str(r#""TinyInt""#).unwrap();
736 assert_eq!(deserialized, expected_column_type);
737
738 let expected_column_type = ColumnType::SmallInt;
739 let deserialized: ColumnType = serde_json::from_str(r#""SmallInt""#).unwrap();
740 assert_eq!(deserialized, expected_column_type);
741
742 let expected_column_type = ColumnType::Int;
743 let deserialized: ColumnType = serde_json::from_str(r#""Int""#).unwrap();
744 assert_eq!(deserialized, expected_column_type);
745
746 let expected_column_type = ColumnType::BigInt;
747 let deserialized: ColumnType = serde_json::from_str(r#""BigInt""#).unwrap();
748 assert_eq!(deserialized, expected_column_type);
749
750 let expected_column_type = ColumnType::TinyInt;
751 let deserialized: ColumnType = serde_json::from_str(r#""TINYINT""#).unwrap();
752 assert_eq!(deserialized, expected_column_type);
753
754 let expected_column_type = ColumnType::SmallInt;
755 let deserialized: ColumnType = serde_json::from_str(r#""SMALLINT""#).unwrap();
756 assert_eq!(deserialized, expected_column_type);
757
758 let expected_column_type = ColumnType::Int128;
759 let deserialized: ColumnType = serde_json::from_str(r#""DECIMAL""#).unwrap();
760 assert_eq!(deserialized, expected_column_type);
761
762 let expected_column_type = ColumnType::Int128;
763 let deserialized: ColumnType = serde_json::from_str(r#""Decimal""#).unwrap();
764 assert_eq!(deserialized, expected_column_type);
765
766 let expected_column_type = ColumnType::VarChar;
767 let deserialized: ColumnType = serde_json::from_str(r#""VarChar""#).unwrap();
768 assert_eq!(deserialized, expected_column_type);
769
770 let expected_column_type = ColumnType::Scalar;
771 let deserialized: ColumnType = serde_json::from_str(r#""SCALAR""#).unwrap();
772 assert_eq!(deserialized, expected_column_type);
773
774 let expected_column_type = ColumnType::Decimal75(Precision::new(75).unwrap(), i8::MAX);
775 let deserialized: ColumnType = serde_json::from_str(r#"{"Decimal75":[75, 127]}"#).unwrap();
776 assert_eq!(deserialized, expected_column_type);
777
778 let expected_column_type =
779 ColumnType::Decimal75(Precision::new(u8::MIN + 1).unwrap(), i8::MIN);
780 let deserialized: ColumnType = serde_json::from_str(r#"{"Decimal75":[1, -128]}"#).unwrap();
781 assert_eq!(deserialized, expected_column_type);
782
783 let expected_column_type = ColumnType::Decimal75(Precision::new(1).unwrap(), 0);
784 let deserialized: ColumnType = serde_json::from_str(r#"{"Decimal75":[1, 0]}"#).unwrap();
785 assert_eq!(deserialized, expected_column_type);
786 }
787
788 #[test]
789 fn we_can_deserialize_columns_from_lowercase_or_uppercase_strings() {
790 assert_eq!(
791 serde_json::from_str::<ColumnType>(r#""boolean""#).unwrap(),
792 ColumnType::Boolean
793 );
794 assert_eq!(
795 serde_json::from_str::<ColumnType>(r#""BOOLEAN""#).unwrap(),
796 ColumnType::Boolean
797 );
798
799 assert_eq!(
800 serde_json::from_str::<ColumnType>(r#""bigint""#).unwrap(),
801 ColumnType::BigInt
802 );
803 assert_eq!(
804 serde_json::from_str::<ColumnType>(r#""BIGINT""#).unwrap(),
805 ColumnType::BigInt
806 );
807 assert_eq!(
808 serde_json::from_str::<ColumnType>(r#""TINYINT""#).unwrap(),
809 ColumnType::TinyInt
810 );
811 assert_eq!(
812 serde_json::from_str::<ColumnType>(r#""tinyint""#).unwrap(),
813 ColumnType::TinyInt
814 );
815 assert_eq!(
816 serde_json::from_str::<ColumnType>(r#""SMALLINT""#).unwrap(),
817 ColumnType::SmallInt
818 );
819 assert_eq!(
820 serde_json::from_str::<ColumnType>(r#""smallint""#).unwrap(),
821 ColumnType::SmallInt
822 );
823 assert_eq!(
824 serde_json::from_str::<ColumnType>(r#""int""#).unwrap(),
825 ColumnType::Int
826 );
827 assert_eq!(
828 serde_json::from_str::<ColumnType>(r#""INT""#).unwrap(),
829 ColumnType::Int
830 );
831 assert_eq!(
832 serde_json::from_str::<ColumnType>(r#""decimal""#).unwrap(),
833 ColumnType::Int128
834 );
835 assert_eq!(
836 serde_json::from_str::<ColumnType>(r#""DECIMAL""#).unwrap(),
837 ColumnType::Int128
838 );
839
840 assert_eq!(
841 serde_json::from_str::<ColumnType>(r#""VARCHAR""#).unwrap(),
842 ColumnType::VarChar
843 );
844 assert_eq!(
845 serde_json::from_str::<ColumnType>(r#""varchar""#).unwrap(),
846 ColumnType::VarChar
847 );
848
849 assert_eq!(
850 serde_json::from_str::<ColumnType>(r#""SCALAR""#).unwrap(),
851 ColumnType::Scalar
852 );
853 assert_eq!(
854 serde_json::from_str::<ColumnType>(r#""scalar""#).unwrap(),
855 ColumnType::Scalar
856 );
857 assert_eq!(
858 serde_json::from_str::<ColumnType>(r#"{"decimal75":[1,0]}"#).unwrap(),
859 ColumnType::Decimal75(Precision::new(1).unwrap(), 0)
860 );
861 assert_eq!(
862 serde_json::from_str::<ColumnType>(r#"{"DECIMAL75":[1,0]}"#).unwrap(),
863 ColumnType::Decimal75(Precision::new(1).unwrap(), 0)
864 );
865
866 assert_eq!(
867 serde_json::from_str::<ColumnType>(r#"{"decimal75":[10,5]}"#).unwrap(),
868 ColumnType::Decimal75(Precision::new(10).unwrap(), 5)
869 );
870
871 assert_eq!(
872 serde_json::from_str::<ColumnType>(r#"{"DECIMAL75":[1,-128]}"#).unwrap(),
873 ColumnType::Decimal75(Precision::new(1).unwrap(), -128)
874 );
875 }
876
877 #[test]
878 fn we_cannot_deserialize_columns_from_invalid_strings() {
879 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""BooLean""#);
880 assert!(deserialized.is_err());
881
882 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""Tinyint""#);
883 assert!(deserialized.is_err());
884
885 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""Smallint""#);
886 assert!(deserialized.is_err());
887
888 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""iNt""#);
889 assert!(deserialized.is_err());
890
891 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""Bigint""#);
892 assert!(deserialized.is_err());
893
894 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""DecImal""#);
895 assert!(deserialized.is_err());
896
897 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""DecImal75""#);
898 assert!(deserialized.is_err());
899
900 let deserialized: Result<ColumnType, _> =
901 serde_json::from_str(r#"{"TimestampTZ":["Utc","Second"]}"#);
902 assert!(deserialized.is_err());
903
904 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""Varchar""#);
905 assert!(deserialized.is_err());
906
907 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""ScaLar""#);
908 assert!(deserialized.is_err());
909 }
910
911 #[test]
912 fn we_can_convert_columntype_to_json_string_and_back() {
913 let boolean = ColumnType::Boolean;
914 let boolean_json = serde_json::to_string(&boolean).unwrap();
915 assert_eq!(boolean_json, "\"Boolean\"");
916 assert_eq!(
917 serde_json::from_str::<ColumnType>(&boolean_json).unwrap(),
918 boolean
919 );
920
921 let tinyint = ColumnType::TinyInt;
922 let tinyint_json = serde_json::to_string(&tinyint).unwrap();
923 assert_eq!(tinyint_json, "\"TinyInt\"");
924 assert_eq!(
925 serde_json::from_str::<ColumnType>(&tinyint_json).unwrap(),
926 tinyint
927 );
928
929 let smallint = ColumnType::SmallInt;
930 let smallint_json = serde_json::to_string(&smallint).unwrap();
931 assert_eq!(smallint_json, "\"SmallInt\"");
932 assert_eq!(
933 serde_json::from_str::<ColumnType>(&smallint_json).unwrap(),
934 smallint
935 );
936
937 let int = ColumnType::Int;
938 let int_json = serde_json::to_string(&int).unwrap();
939 assert_eq!(int_json, "\"Int\"");
940 assert_eq!(serde_json::from_str::<ColumnType>(&int_json).unwrap(), int);
941
942 let bigint = ColumnType::BigInt;
943 let bigint_json = serde_json::to_string(&bigint).unwrap();
944 assert_eq!(bigint_json, "\"BigInt\"");
945 assert_eq!(
946 serde_json::from_str::<ColumnType>(&bigint_json).unwrap(),
947 bigint
948 );
949
950 let int128 = ColumnType::Int128;
951 let int128_json = serde_json::to_string(&int128).unwrap();
952 assert_eq!(int128_json, "\"Decimal\"");
953 assert_eq!(
954 serde_json::from_str::<ColumnType>(&int128_json).unwrap(),
955 int128
956 );
957
958 let varchar = ColumnType::VarChar;
959 let varchar_json = serde_json::to_string(&varchar).unwrap();
960 assert_eq!(varchar_json, "\"VarChar\"");
961 assert_eq!(
962 serde_json::from_str::<ColumnType>(&varchar_json).unwrap(),
963 varchar
964 );
965
966 let scalar = ColumnType::Scalar;
967 let scalar_json = serde_json::to_string(&scalar).unwrap();
968 assert_eq!(scalar_json, "\"Scalar\"");
969 assert_eq!(
970 serde_json::from_str::<ColumnType>(&scalar_json).unwrap(),
971 scalar
972 );
973
974 let decimal75 = ColumnType::Decimal75(Precision::new(75).unwrap(), 0);
975 let decimal75_json = serde_json::to_string(&decimal75).unwrap();
976 assert_eq!(decimal75_json, r#"{"Decimal75":[75,0]}"#);
977 assert_eq!(
978 serde_json::from_str::<ColumnType>(&decimal75_json).unwrap(),
979 decimal75
980 );
981 }
982
983 #[test]
984 fn we_can_get_the_len_of_a_column() {
985 let precision = 10;
986 let scale = 2;
987
988 let scalar_values = [
989 TestScalar::from(1),
990 TestScalar::from(2),
991 TestScalar::from(3),
992 ];
993
994 let column = Column::<DoryScalar>::Boolean(&[true, false, true]);
996 assert_eq!(column.len(), 3);
997 assert!(!column.is_empty());
998
999 let column = Column::<DoryScalar>::TinyInt(&[1, 2, 3]);
1000 assert_eq!(column.len(), 3);
1001 assert!(!column.is_empty());
1002
1003 let column = Column::<TestScalar>::SmallInt(&[1, 2, 3]);
1004 assert_eq!(column.len(), 3);
1005 assert!(!column.is_empty());
1006
1007 let column = Column::<TestScalar>::Int(&[1, 2, 3]);
1008 assert_eq!(column.len(), 3);
1009 assert!(!column.is_empty());
1010
1011 let column = Column::<TestScalar>::BigInt(&[1, 2, 3]);
1012 assert_eq!(column.len(), 3);
1013 assert!(!column.is_empty());
1014
1015 let column = Column::VarChar((&["a", "b", "c"], &scalar_values));
1016 assert_eq!(column.len(), 3);
1017 assert!(!column.is_empty());
1018
1019 let column = Column::<DoryScalar>::Int128(&[1, 2, 3]);
1020 assert_eq!(column.len(), 3);
1021 assert!(!column.is_empty());
1022
1023 let column = Column::Scalar(&scalar_values);
1024 assert_eq!(column.len(), 3);
1025 assert!(!column.is_empty());
1026
1027 let decimal_data = [
1028 TestScalar::from(1),
1029 TestScalar::from(2),
1030 TestScalar::from(3),
1031 ];
1032
1033 let precision = Precision::new(precision).unwrap();
1034 let column = Column::Decimal75(precision, scale, &decimal_data);
1035 assert_eq!(column.len(), 3);
1036 assert!(!column.is_empty());
1037
1038 let column = Column::<DoryScalar>::Boolean(&[]);
1040 assert_eq!(column.len(), 0);
1041 assert!(column.is_empty());
1042
1043 let column = Column::<DoryScalar>::TinyInt(&[]);
1044 assert_eq!(column.len(), 0);
1045 assert!(column.is_empty());
1046
1047 let column = Column::<TestScalar>::SmallInt(&[]);
1048 assert_eq!(column.len(), 0);
1049 assert!(column.is_empty());
1050
1051 let column = Column::<TestScalar>::Int(&[]);
1052 assert_eq!(column.len(), 0);
1053 assert!(column.is_empty());
1054
1055 let column = Column::<TestScalar>::BigInt(&[]);
1056 assert_eq!(column.len(), 0);
1057 assert!(column.is_empty());
1058
1059 let column = Column::<DoryScalar>::VarChar((&[], &[]));
1060 assert_eq!(column.len(), 0);
1061 assert!(column.is_empty());
1062
1063 let column = Column::<TestScalar>::Int128(&[]);
1064 assert_eq!(column.len(), 0);
1065 assert!(column.is_empty());
1066
1067 let column = Column::<DoryScalar>::Scalar(&[]);
1068 assert_eq!(column.len(), 0);
1069 assert!(column.is_empty());
1070
1071 let column: Column<'_, TestScalar> = Column::Decimal75(precision, scale, &[]);
1072 assert_eq!(column.len(), 0);
1073 assert!(column.is_empty());
1074 }
1075
1076 #[test]
1077 fn we_can_convert_owned_columns_to_columns_round_trip() {
1078 let alloc = Bump::new();
1079 let owned_col: OwnedColumn<TestScalar> = OwnedColumn::Int128(vec![1, 2, 3, 4, 5]);
1081 let col = Column::<TestScalar>::from_owned_column(&owned_col, &alloc);
1082 assert_eq!(col, Column::Int128(&[1, 2, 3, 4, 5]));
1083 let new_owned_col = (&col).into();
1084 assert_eq!(owned_col, new_owned_col);
1085
1086 let owned_col: OwnedColumn<TestScalar> =
1088 OwnedColumn::Boolean(vec![true, false, true, false, true]);
1089 let col = Column::<TestScalar>::from_owned_column(&owned_col, &alloc);
1090 assert_eq!(col, Column::Boolean(&[true, false, true, false, true]));
1091 let new_owned_col = (&col).into();
1092 assert_eq!(owned_col, new_owned_col);
1093
1094 let strs = [
1096 "Space and Time",
1097 "Tér és Idő",
1098 "Пространство и время",
1099 "Spațiu și Timp",
1100 "Spazju u Ħin",
1101 ];
1102 let scalars = strs.iter().map(TestScalar::from).collect::<Vec<_>>();
1103 let owned_col = OwnedColumn::VarChar(
1104 strs.iter()
1105 .map(ToString::to_string)
1106 .collect::<Vec<String>>(),
1107 );
1108 let col = Column::<TestScalar>::from_owned_column(&owned_col, &alloc);
1109 assert_eq!(col, Column::VarChar((&strs, &scalars)));
1110 let new_owned_col = (&col).into();
1111 assert_eq!(owned_col, new_owned_col);
1112
1113 let scalars: Vec<TestScalar> = [1, 2, 3, 4, 5].iter().map(TestScalar::from).collect();
1115 let owned_col: OwnedColumn<TestScalar> =
1116 OwnedColumn::Decimal75(Precision::new(75).unwrap(), 127, scalars.clone());
1117 let col = Column::<TestScalar>::from_owned_column(&owned_col, &alloc);
1118 assert_eq!(
1119 col,
1120 Column::Decimal75(Precision::new(75).unwrap(), 127, &scalars)
1121 );
1122 let new_owned_col = (&col).into();
1123 assert_eq!(owned_col, new_owned_col);
1124 }
1125
1126 #[test]
1127 fn we_can_get_the_data_size_of_a_column() {
1128 let column = Column::<DoryScalar>::Boolean(&[true, false, true]);
1129 assert_eq!(column.column_type().byte_size(), 1);
1130 assert_eq!(column.column_type().bit_size(), 8);
1131
1132 let column = Column::<TestScalar>::TinyInt(&[1, 2, 3, 4]);
1133 assert_eq!(column.column_type().byte_size(), 1);
1134 assert_eq!(column.column_type().bit_size(), 8);
1135
1136 let column = Column::<TestScalar>::SmallInt(&[1, 2, 3, 4]);
1137 assert_eq!(column.column_type().byte_size(), 2);
1138 assert_eq!(column.column_type().bit_size(), 16);
1139
1140 let column = Column::<TestScalar>::Int(&[1, 2, 3]);
1141 assert_eq!(column.column_type().byte_size(), 4);
1142 assert_eq!(column.column_type().bit_size(), 32);
1143
1144 let column = Column::<TestScalar>::BigInt(&[1]);
1145 assert_eq!(column.column_type().byte_size(), 8);
1146 assert_eq!(column.column_type().bit_size(), 64);
1147
1148 let column = Column::<DoryScalar>::Int128(&[1, 2]);
1149 assert_eq!(column.column_type().byte_size(), 16);
1150 assert_eq!(column.column_type().bit_size(), 128);
1151
1152 let scalar_values = [
1153 TestScalar::from(1),
1154 TestScalar::from(2),
1155 TestScalar::from(3),
1156 ];
1157
1158 let column = Column::VarChar((&["a", "b", "c", "d", "e"], &scalar_values));
1159 assert_eq!(column.column_type().byte_size(), 32);
1160 assert_eq!(column.column_type().bit_size(), 256);
1161
1162 let column = Column::Scalar(&scalar_values);
1163 assert_eq!(column.column_type().byte_size(), 32);
1164 assert_eq!(column.column_type().bit_size(), 256);
1165
1166 let precision = 10;
1167 let scale = 2;
1168 let decimal_data = [
1169 TestScalar::from(1),
1170 TestScalar::from(2),
1171 TestScalar::from(3),
1172 ];
1173
1174 let precision = Precision::new(precision).unwrap();
1175 let column = Column::Decimal75(precision, scale, &decimal_data);
1176 assert_eq!(column.column_type().byte_size(), 32);
1177 assert_eq!(column.column_type().bit_size(), 256);
1178
1179 let column: Column<'_, DoryScalar> =
1180 Column::TimestampTZ(PoSQLTimeUnit::Second, PoSQLTimeZone::utc(), &[1, 2, 3]);
1181 assert_eq!(column.column_type().byte_size(), 8);
1182 assert_eq!(column.column_type().bit_size(), 64);
1183 }
1184
1185 #[test]
1186 fn we_can_get_length_of_varbinary_column() {
1187 let raw_bytes: &[&[u8]] = &[b"foo", b"bar", b""];
1188 let scalars: Vec<TestScalar> = raw_bytes
1189 .iter()
1190 .map(|b| TestScalar::from_le_bytes_mod_order(b))
1191 .collect();
1192
1193 let column = Column::VarBinary((raw_bytes, &scalars));
1194 assert_eq!(column.len(), 3);
1195 assert!(!column.is_empty());
1196 assert_eq!(column.column_type(), ColumnType::VarBinary);
1197 }
1198
1199 #[test]
1200 fn we_can_convert_varbinary_owned_column_to_column_and_back() {
1201 use bumpalo::Bump;
1202 let alloc = Bump::new();
1203
1204 let owned_varbinary = OwnedColumn::VarBinary(vec![b"abc".to_vec(), b"xyz".to_vec()]);
1205
1206 let column = Column::<TestScalar>::from_owned_column(&owned_varbinary, &alloc);
1207 match column {
1208 Column::VarBinary((bytes, scalars)) => {
1209 assert_eq!(bytes.len(), 2);
1210 assert_eq!(scalars.len(), 2);
1211 assert_eq!(bytes[0], b"abc");
1212 assert_eq!(bytes[1], b"xyz");
1213 }
1214 _ => panic!("Expected VarBinary column"),
1215 }
1216
1217 let round_trip_owned: OwnedColumn<TestScalar> = (&column).into();
1218 assert_eq!(owned_varbinary, round_trip_owned);
1219 }
1220
1221 #[test]
1222 fn we_can_get_min_scalar() {
1223 assert_eq!(
1224 ColumnType::TinyInt.min_scalar(),
1225 Some(TestScalar::from(i8::MIN))
1226 );
1227 assert_eq!(
1228 ColumnType::SmallInt.min_scalar(),
1229 Some(TestScalar::from(i16::MIN))
1230 );
1231 assert_eq!(
1232 ColumnType::Int.min_scalar(),
1233 Some(TestScalar::from(i32::MIN))
1234 );
1235 assert_eq!(
1236 ColumnType::BigInt.min_scalar(),
1237 Some(TestScalar::from(i64::MIN))
1238 );
1239 assert_eq!(
1240 ColumnType::Int128.min_scalar(),
1241 Some(TestScalar::from(i128::MIN))
1242 );
1243 assert_eq!(ColumnType::Uint8.min_scalar::<TestScalar>(), None);
1244 assert_eq!(ColumnType::Scalar.min_scalar::<TestScalar>(), None);
1245 assert_eq!(ColumnType::Boolean.min_scalar::<TestScalar>(), None);
1246 assert_eq!(ColumnType::VarBinary.min_scalar::<TestScalar>(), None);
1247 assert_eq!(
1248 ColumnType::TimestampTZ(PoSQLTimeUnit::Second, PoSQLTimeZone::new(0))
1249 .min_scalar::<TestScalar>(),
1250 None
1251 );
1252 assert_eq!(
1253 ColumnType::Decimal75(Precision::new(1).unwrap(), 1).min_scalar::<TestScalar>(),
1254 None
1255 );
1256 assert_eq!(ColumnType::VarChar.min_scalar::<TestScalar>(), None);
1257 }
1258}