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 pub(crate) fn to_scalar(self) -> Vec<S> {
327 match self {
328 Self::Boolean(col) => slice_cast_with(col, |b| S::from(b)),
329 Self::Decimal75(_, _, col) => slice_cast_with(col, |s| *s),
330 Self::VarChar((_, values)) => slice_cast_with(values, |s| *s),
331 Self::VarBinary((_, values)) => slice_cast_with(values, |s| *s),
332 Self::Uint8(col) => slice_cast_with(col, |i| S::from(i)),
333 Self::TinyInt(col) => slice_cast_with(col, |i| S::from(i)),
334 Self::SmallInt(col) => slice_cast_with(col, |i| S::from(i)),
335 Self::Int(col) => slice_cast_with(col, |i| S::from(i)),
336 Self::BigInt(col) => slice_cast_with(col, |i| S::from(i)),
337 Self::Int128(col) => slice_cast_with(col, |i| S::from(i)),
338 Self::Scalar(col) => slice_cast_with(col, |i| S::from(i)),
339 Self::TimestampTZ(_, _, col) => slice_cast_with(col, |i| S::from(i)),
340 }
341 }
342}
343
344#[derive(Eq, PartialEq, Debug, Clone, Hash, Serialize, Deserialize, Copy)]
350#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
351pub enum ColumnType {
352 #[serde(alias = "BOOLEAN", alias = "boolean")]
354 Boolean,
355 #[serde(alias = "UINT8", alias = "uint8")]
357 Uint8,
358 #[serde(alias = "TINYINT", alias = "tinyint")]
360 TinyInt,
361 #[serde(alias = "SMALLINT", alias = "smallint")]
363 SmallInt,
364 #[serde(alias = "INT", alias = "int")]
366 Int,
367 #[serde(alias = "BIGINT", alias = "bigint")]
369 BigInt,
370 #[serde(rename = "Decimal", alias = "DECIMAL", alias = "decimal")]
372 Int128,
373 #[serde(alias = "VARCHAR", alias = "varchar")]
375 VarChar,
376 #[serde(rename = "Decimal75", alias = "DECIMAL75", alias = "decimal75")]
378 Decimal75(Precision, i8),
379 #[serde(alias = "TIMESTAMP", alias = "timestamp")]
381 #[cfg_attr(test, proptest(skip))]
382 TimestampTZ(PoSQLTimeUnit, PoSQLTimeZone),
383 #[serde(alias = "SCALAR", alias = "scalar")]
385 #[cfg_attr(test, proptest(skip))]
386 Scalar,
387 #[serde(alias = "BINARY", alias = "BINARY")]
389 VarBinary,
390}
391
392impl ColumnType {
393 #[must_use]
395 pub fn is_numeric(&self) -> bool {
396 matches!(
397 self,
398 ColumnType::Uint8
399 | ColumnType::TinyInt
400 | ColumnType::SmallInt
401 | ColumnType::Int
402 | ColumnType::BigInt
403 | ColumnType::Int128
404 | ColumnType::Scalar
405 | ColumnType::Decimal75(_, _)
406 )
407 }
408
409 #[must_use]
411 pub fn is_integer(&self) -> bool {
412 matches!(
413 self,
414 ColumnType::Uint8
415 | ColumnType::TinyInt
416 | ColumnType::SmallInt
417 | ColumnType::Int
418 | ColumnType::BigInt
419 | ColumnType::Int128
420 )
421 }
422
423 #[must_use]
427 #[cfg_attr(not(test), expect(dead_code))]
428 #[expect(clippy::trivially_copy_pass_by_ref)]
429 fn sqrt_negative_min(&self) -> Option<u64> {
430 match self {
431 ColumnType::TinyInt => Some(11),
432 ColumnType::SmallInt => Some(181),
433 ColumnType::Int => Some(46_340),
434 ColumnType::BigInt => Some(3_037_000_499),
435 ColumnType::Int128 => Some(13_043_817_825_332_782_212),
436 _ => None,
437 }
438 }
439
440 fn to_integer_bits(self) -> Option<usize> {
442 match self {
443 ColumnType::Uint8 | ColumnType::TinyInt => Some(8),
444 ColumnType::SmallInt => Some(16),
445 ColumnType::Int => Some(32),
446 ColumnType::BigInt => Some(64),
447 ColumnType::Int128 => Some(128),
448 _ => None,
449 }
450 }
451
452 fn from_signed_integer_bits(bits: usize) -> Option<Self> {
456 match bits {
457 8 => Some(ColumnType::TinyInt),
458 16 => Some(ColumnType::SmallInt),
459 32 => Some(ColumnType::Int),
460 64 => Some(ColumnType::BigInt),
461 128 => Some(ColumnType::Int128),
462 _ => None,
463 }
464 }
465
466 fn from_unsigned_integer_bits(bits: usize) -> Option<Self> {
470 match bits {
471 8 => Some(ColumnType::Uint8),
472 _ => None,
473 }
474 }
475
476 #[must_use]
480 pub fn max_integer_type(&self, other: &Self) -> Option<Self> {
481 if !self.is_integer() || !other.is_integer() {
483 return None;
484 }
485 self.to_integer_bits().and_then(|self_bits| {
486 other
487 .to_integer_bits()
488 .and_then(|other_bits| Self::from_signed_integer_bits(self_bits.max(other_bits)))
489 })
490 }
491
492 #[must_use]
496 pub fn max_unsigned_integer_type(&self, other: &Self) -> Option<Self> {
497 if !self.is_integer() || !other.is_integer() {
499 return None;
500 }
501 self.to_integer_bits().and_then(|self_bits| {
502 other
503 .to_integer_bits()
504 .and_then(|other_bits| Self::from_unsigned_integer_bits(self_bits.max(other_bits)))
505 })
506 }
507
508 #[must_use]
510 pub fn precision_value(&self) -> Option<u8> {
511 match self {
512 Self::Uint8 | Self::TinyInt => Some(3_u8),
513 Self::SmallInt => Some(5_u8),
514 Self::Int => Some(10_u8),
515 Self::BigInt | Self::TimestampTZ(_, _) => Some(19_u8),
516 Self::Int128 => Some(39_u8),
517 Self::Decimal75(precision, _) => Some(precision.value()),
518 Self::Scalar => Some(0_u8),
521 Self::Boolean | Self::VarChar | Self::VarBinary => None,
522 }
523 }
524 #[must_use]
526 pub fn scale(&self) -> Option<i8> {
527 match self {
528 Self::Decimal75(_, scale) => Some(*scale),
529 Self::TinyInt
530 | Self::Uint8
531 | Self::SmallInt
532 | Self::Int
533 | Self::BigInt
534 | Self::Int128
535 | Self::Scalar => Some(0),
536 Self::Boolean | Self::VarBinary | Self::VarChar => None,
537 Self::TimestampTZ(tu, _) => match tu {
538 PoSQLTimeUnit::Second => Some(0),
539 PoSQLTimeUnit::Millisecond => Some(3),
540 PoSQLTimeUnit::Microsecond => Some(6),
541 PoSQLTimeUnit::Nanosecond => Some(9),
542 },
543 }
544 }
545
546 #[must_use]
548 pub fn byte_size(&self) -> usize {
549 match self {
550 Self::Boolean => size_of::<bool>(),
551 Self::Uint8 => size_of::<u8>(),
552 Self::TinyInt => size_of::<i8>(),
553 Self::SmallInt => size_of::<i16>(),
554 Self::Int => size_of::<i32>(),
555 Self::BigInt | Self::TimestampTZ(_, _) => size_of::<i64>(),
556 Self::Int128 => size_of::<i128>(),
557 Self::Scalar | Self::Decimal75(_, _) | Self::VarBinary | Self::VarChar => {
558 size_of::<[u64; 4]>()
559 }
560 }
561 }
562
563 #[expect(clippy::cast_possible_truncation)]
564 #[must_use]
566 pub fn bit_size(&self) -> u32 {
567 self.byte_size() as u32 * 8
568 }
569
570 #[must_use]
572 pub const fn is_signed(&self) -> bool {
573 match self {
574 Self::TinyInt
575 | Self::SmallInt
576 | Self::Int
577 | Self::BigInt
578 | Self::Int128
579 | Self::TimestampTZ(_, _) => true,
580 Self::Decimal75(_, _)
581 | Self::Scalar
582 | Self::VarBinary
583 | Self::VarChar
584 | Self::Boolean
585 | Self::Uint8 => false,
586 }
587 }
588
589 #[must_use]
591 pub fn min_scalar<S: Scalar>(&self) -> Option<S> {
592 match self {
593 ColumnType::TinyInt => Some(S::from(i8::MIN)),
594 ColumnType::SmallInt => Some(S::from(i16::MIN)),
595 ColumnType::Int => Some(S::from(i32::MIN)),
596 ColumnType::BigInt => Some(S::from(i64::MIN)),
597 ColumnType::Int128 => Some(S::from(i128::MIN)),
598 _ => None,
599 }
600 }
601}
602
603impl Display for ColumnType {
605 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
606 match self {
607 ColumnType::Boolean => write!(f, "BOOLEAN"),
608 ColumnType::Uint8 => write!(f, "UINT8"),
609 ColumnType::TinyInt => write!(f, "TINYINT"),
610 ColumnType::SmallInt => write!(f, "SMALLINT"),
611 ColumnType::Int => write!(f, "INT"),
612 ColumnType::BigInt => write!(f, "BIGINT"),
613 ColumnType::Int128 => write!(f, "DECIMAL"),
614 ColumnType::Decimal75(precision, scale) => {
615 write!(
616 f,
617 "DECIMAL75(PRECISION: {:?}, SCALE: {scale})",
618 precision.value()
619 )
620 }
621 ColumnType::VarChar => write!(f, "VARCHAR"),
622 ColumnType::VarBinary => write!(f, "BINARY"),
623 ColumnType::Scalar => write!(f, "SCALAR"),
624 ColumnType::TimestampTZ(timeunit, timezone) => {
625 write!(f, "TIMESTAMP(TIMEUNIT: {timeunit}, TIMEZONE: {timezone})")
626 }
627 }
628 }
629}
630
631#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)]
633pub struct ColumnRef {
634 column_id: Ident,
635 table_ref: TableRef,
636 column_type: ColumnType,
637}
638
639impl ColumnRef {
640 #[must_use]
642 pub fn new(table_ref: TableRef, column_id: Ident, column_type: ColumnType) -> Self {
643 Self {
644 column_id,
645 table_ref,
646 column_type,
647 }
648 }
649
650 #[must_use]
652 pub fn table_ref(&self) -> TableRef {
653 self.table_ref.clone()
654 }
655
656 #[must_use]
658 pub fn column_id(&self) -> Ident {
659 self.column_id.clone()
660 }
661
662 #[must_use]
664 pub fn column_type(&self) -> &ColumnType {
665 &self.column_type
666 }
667}
668
669#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)]
674pub struct ColumnField {
675 name: Ident,
676 data_type: ColumnType,
677}
678
679impl ColumnField {
680 #[must_use]
682 pub fn new(name: Ident, data_type: ColumnType) -> ColumnField {
683 ColumnField { name, data_type }
684 }
685
686 #[must_use]
688 pub fn name(&self) -> Ident {
689 self.name.clone()
690 }
691
692 #[must_use]
694 pub fn data_type(&self) -> ColumnType {
695 self.data_type
696 }
697}
698
699#[cfg(test)]
700mod tests {
701 use super::*;
702 use crate::{base::scalar::test_scalar::TestScalar, proof_primitive::dory::DoryScalar};
703 use alloc::{string::String, vec};
704
705 #[test]
706 fn column_type_serializes_to_string() {
707 let column_type = ColumnType::TimestampTZ(PoSQLTimeUnit::Second, PoSQLTimeZone::utc());
708 let serialized = serde_json::to_string(&column_type).unwrap();
709 assert_eq!(serialized, r#"{"TimestampTZ":["Second",{"offset":0}]}"#);
710
711 let column_type = ColumnType::Boolean;
712 let serialized = serde_json::to_string(&column_type).unwrap();
713 assert_eq!(serialized, r#""Boolean""#);
714
715 let column_type = ColumnType::TinyInt;
716 let serialized = serde_json::to_string(&column_type).unwrap();
717 assert_eq!(serialized, r#""TinyInt""#);
718
719 let column_type = ColumnType::SmallInt;
720 let serialized = serde_json::to_string(&column_type).unwrap();
721 assert_eq!(serialized, r#""SmallInt""#);
722
723 let column_type = ColumnType::Int;
724 let serialized = serde_json::to_string(&column_type).unwrap();
725 assert_eq!(serialized, r#""Int""#);
726
727 let column_type = ColumnType::BigInt;
728 let serialized = serde_json::to_string(&column_type).unwrap();
729 assert_eq!(serialized, r#""BigInt""#);
730
731 let column_type = ColumnType::Int128;
732 let serialized = serde_json::to_string(&column_type).unwrap();
733 assert_eq!(serialized, r#""Decimal""#);
734
735 let column_type = ColumnType::VarChar;
736 let serialized = serde_json::to_string(&column_type).unwrap();
737 assert_eq!(serialized, r#""VarChar""#);
738
739 let column_type = ColumnType::Scalar;
740 let serialized = serde_json::to_string(&column_type).unwrap();
741 assert_eq!(serialized, r#""Scalar""#);
742
743 let column_type = ColumnType::Decimal75(Precision::new(1).unwrap(), 0);
744 let serialized = serde_json::to_string(&column_type).unwrap();
745 assert_eq!(serialized, r#"{"Decimal75":[1,0]}"#);
746 }
747
748 #[test]
749 fn we_can_deserialize_columns_from_valid_strings() {
750 let expected_column_type =
751 ColumnType::TimestampTZ(PoSQLTimeUnit::Second, PoSQLTimeZone::utc());
752 let deserialized: ColumnType =
753 serde_json::from_str(r#"{"TimestampTZ":["Second",{"offset":0}]}"#).unwrap();
754 assert_eq!(deserialized, expected_column_type);
755
756 let expected_column_type = ColumnType::Boolean;
757 let deserialized: ColumnType = serde_json::from_str(r#""Boolean""#).unwrap();
758 assert_eq!(deserialized, expected_column_type);
759
760 let expected_column_type = ColumnType::TinyInt;
761 let deserialized: ColumnType = serde_json::from_str(r#""TinyInt""#).unwrap();
762 assert_eq!(deserialized, expected_column_type);
763
764 let expected_column_type = ColumnType::SmallInt;
765 let deserialized: ColumnType = serde_json::from_str(r#""SmallInt""#).unwrap();
766 assert_eq!(deserialized, expected_column_type);
767
768 let expected_column_type = ColumnType::Int;
769 let deserialized: ColumnType = serde_json::from_str(r#""Int""#).unwrap();
770 assert_eq!(deserialized, expected_column_type);
771
772 let expected_column_type = ColumnType::BigInt;
773 let deserialized: ColumnType = serde_json::from_str(r#""BigInt""#).unwrap();
774 assert_eq!(deserialized, expected_column_type);
775
776 let expected_column_type = ColumnType::TinyInt;
777 let deserialized: ColumnType = serde_json::from_str(r#""TINYINT""#).unwrap();
778 assert_eq!(deserialized, expected_column_type);
779
780 let expected_column_type = ColumnType::SmallInt;
781 let deserialized: ColumnType = serde_json::from_str(r#""SMALLINT""#).unwrap();
782 assert_eq!(deserialized, expected_column_type);
783
784 let expected_column_type = ColumnType::Int128;
785 let deserialized: ColumnType = serde_json::from_str(r#""DECIMAL""#).unwrap();
786 assert_eq!(deserialized, expected_column_type);
787
788 let expected_column_type = ColumnType::Int128;
789 let deserialized: ColumnType = serde_json::from_str(r#""Decimal""#).unwrap();
790 assert_eq!(deserialized, expected_column_type);
791
792 let expected_column_type = ColumnType::VarChar;
793 let deserialized: ColumnType = serde_json::from_str(r#""VarChar""#).unwrap();
794 assert_eq!(deserialized, expected_column_type);
795
796 let expected_column_type = ColumnType::Scalar;
797 let deserialized: ColumnType = serde_json::from_str(r#""SCALAR""#).unwrap();
798 assert_eq!(deserialized, expected_column_type);
799
800 let expected_column_type = ColumnType::Decimal75(Precision::new(75).unwrap(), i8::MAX);
801 let deserialized: ColumnType = serde_json::from_str(r#"{"Decimal75":[75, 127]}"#).unwrap();
802 assert_eq!(deserialized, expected_column_type);
803
804 let expected_column_type =
805 ColumnType::Decimal75(Precision::new(u8::MIN + 1).unwrap(), i8::MIN);
806 let deserialized: ColumnType = serde_json::from_str(r#"{"Decimal75":[1, -128]}"#).unwrap();
807 assert_eq!(deserialized, expected_column_type);
808
809 let expected_column_type = ColumnType::Decimal75(Precision::new(1).unwrap(), 0);
810 let deserialized: ColumnType = serde_json::from_str(r#"{"Decimal75":[1, 0]}"#).unwrap();
811 assert_eq!(deserialized, expected_column_type);
812 }
813
814 #[test]
815 fn we_can_deserialize_columns_from_lowercase_or_uppercase_strings() {
816 assert_eq!(
817 serde_json::from_str::<ColumnType>(r#""boolean""#).unwrap(),
818 ColumnType::Boolean
819 );
820 assert_eq!(
821 serde_json::from_str::<ColumnType>(r#""BOOLEAN""#).unwrap(),
822 ColumnType::Boolean
823 );
824
825 assert_eq!(
826 serde_json::from_str::<ColumnType>(r#""bigint""#).unwrap(),
827 ColumnType::BigInt
828 );
829 assert_eq!(
830 serde_json::from_str::<ColumnType>(r#""BIGINT""#).unwrap(),
831 ColumnType::BigInt
832 );
833 assert_eq!(
834 serde_json::from_str::<ColumnType>(r#""TINYINT""#).unwrap(),
835 ColumnType::TinyInt
836 );
837 assert_eq!(
838 serde_json::from_str::<ColumnType>(r#""tinyint""#).unwrap(),
839 ColumnType::TinyInt
840 );
841 assert_eq!(
842 serde_json::from_str::<ColumnType>(r#""SMALLINT""#).unwrap(),
843 ColumnType::SmallInt
844 );
845 assert_eq!(
846 serde_json::from_str::<ColumnType>(r#""smallint""#).unwrap(),
847 ColumnType::SmallInt
848 );
849 assert_eq!(
850 serde_json::from_str::<ColumnType>(r#""int""#).unwrap(),
851 ColumnType::Int
852 );
853 assert_eq!(
854 serde_json::from_str::<ColumnType>(r#""INT""#).unwrap(),
855 ColumnType::Int
856 );
857 assert_eq!(
858 serde_json::from_str::<ColumnType>(r#""decimal""#).unwrap(),
859 ColumnType::Int128
860 );
861 assert_eq!(
862 serde_json::from_str::<ColumnType>(r#""DECIMAL""#).unwrap(),
863 ColumnType::Int128
864 );
865
866 assert_eq!(
867 serde_json::from_str::<ColumnType>(r#""VARCHAR""#).unwrap(),
868 ColumnType::VarChar
869 );
870 assert_eq!(
871 serde_json::from_str::<ColumnType>(r#""varchar""#).unwrap(),
872 ColumnType::VarChar
873 );
874
875 assert_eq!(
876 serde_json::from_str::<ColumnType>(r#""SCALAR""#).unwrap(),
877 ColumnType::Scalar
878 );
879 assert_eq!(
880 serde_json::from_str::<ColumnType>(r#""scalar""#).unwrap(),
881 ColumnType::Scalar
882 );
883 assert_eq!(
884 serde_json::from_str::<ColumnType>(r#"{"decimal75":[1,0]}"#).unwrap(),
885 ColumnType::Decimal75(Precision::new(1).unwrap(), 0)
886 );
887 assert_eq!(
888 serde_json::from_str::<ColumnType>(r#"{"DECIMAL75":[1,0]}"#).unwrap(),
889 ColumnType::Decimal75(Precision::new(1).unwrap(), 0)
890 );
891
892 assert_eq!(
893 serde_json::from_str::<ColumnType>(r#"{"decimal75":[10,5]}"#).unwrap(),
894 ColumnType::Decimal75(Precision::new(10).unwrap(), 5)
895 );
896
897 assert_eq!(
898 serde_json::from_str::<ColumnType>(r#"{"DECIMAL75":[1,-128]}"#).unwrap(),
899 ColumnType::Decimal75(Precision::new(1).unwrap(), -128)
900 );
901 }
902
903 #[test]
904 fn we_cannot_deserialize_columns_from_invalid_strings() {
905 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""BooLean""#);
906 assert!(deserialized.is_err());
907
908 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""Tinyint""#);
909 assert!(deserialized.is_err());
910
911 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""Smallint""#);
912 assert!(deserialized.is_err());
913
914 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""iNt""#);
915 assert!(deserialized.is_err());
916
917 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""Bigint""#);
918 assert!(deserialized.is_err());
919
920 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""DecImal""#);
921 assert!(deserialized.is_err());
922
923 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""DecImal75""#);
924 assert!(deserialized.is_err());
925
926 let deserialized: Result<ColumnType, _> =
927 serde_json::from_str(r#"{"TimestampTZ":["Utc","Second"]}"#);
928 assert!(deserialized.is_err());
929
930 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""Varchar""#);
931 assert!(deserialized.is_err());
932
933 let deserialized: Result<ColumnType, _> = serde_json::from_str(r#""ScaLar""#);
934 assert!(deserialized.is_err());
935 }
936
937 #[test]
938 fn we_can_convert_columntype_to_json_string_and_back() {
939 let boolean = ColumnType::Boolean;
940 let boolean_json = serde_json::to_string(&boolean).unwrap();
941 assert_eq!(boolean_json, "\"Boolean\"");
942 assert_eq!(
943 serde_json::from_str::<ColumnType>(&boolean_json).unwrap(),
944 boolean
945 );
946
947 let tinyint = ColumnType::TinyInt;
948 let tinyint_json = serde_json::to_string(&tinyint).unwrap();
949 assert_eq!(tinyint_json, "\"TinyInt\"");
950 assert_eq!(
951 serde_json::from_str::<ColumnType>(&tinyint_json).unwrap(),
952 tinyint
953 );
954
955 let smallint = ColumnType::SmallInt;
956 let smallint_json = serde_json::to_string(&smallint).unwrap();
957 assert_eq!(smallint_json, "\"SmallInt\"");
958 assert_eq!(
959 serde_json::from_str::<ColumnType>(&smallint_json).unwrap(),
960 smallint
961 );
962
963 let int = ColumnType::Int;
964 let int_json = serde_json::to_string(&int).unwrap();
965 assert_eq!(int_json, "\"Int\"");
966 assert_eq!(serde_json::from_str::<ColumnType>(&int_json).unwrap(), int);
967
968 let bigint = ColumnType::BigInt;
969 let bigint_json = serde_json::to_string(&bigint).unwrap();
970 assert_eq!(bigint_json, "\"BigInt\"");
971 assert_eq!(
972 serde_json::from_str::<ColumnType>(&bigint_json).unwrap(),
973 bigint
974 );
975
976 let int128 = ColumnType::Int128;
977 let int128_json = serde_json::to_string(&int128).unwrap();
978 assert_eq!(int128_json, "\"Decimal\"");
979 assert_eq!(
980 serde_json::from_str::<ColumnType>(&int128_json).unwrap(),
981 int128
982 );
983
984 let varchar = ColumnType::VarChar;
985 let varchar_json = serde_json::to_string(&varchar).unwrap();
986 assert_eq!(varchar_json, "\"VarChar\"");
987 assert_eq!(
988 serde_json::from_str::<ColumnType>(&varchar_json).unwrap(),
989 varchar
990 );
991
992 let scalar = ColumnType::Scalar;
993 let scalar_json = serde_json::to_string(&scalar).unwrap();
994 assert_eq!(scalar_json, "\"Scalar\"");
995 assert_eq!(
996 serde_json::from_str::<ColumnType>(&scalar_json).unwrap(),
997 scalar
998 );
999
1000 let decimal75 = ColumnType::Decimal75(Precision::new(75).unwrap(), 0);
1001 let decimal75_json = serde_json::to_string(&decimal75).unwrap();
1002 assert_eq!(decimal75_json, r#"{"Decimal75":[75,0]}"#);
1003 assert_eq!(
1004 serde_json::from_str::<ColumnType>(&decimal75_json).unwrap(),
1005 decimal75
1006 );
1007 }
1008
1009 #[test]
1010 fn we_can_get_the_len_of_a_column() {
1011 let precision = 10;
1012 let scale = 2;
1013
1014 let scalar_values = [
1015 TestScalar::from(1),
1016 TestScalar::from(2),
1017 TestScalar::from(3),
1018 ];
1019
1020 let column = Column::<DoryScalar>::Boolean(&[true, false, true]);
1022 assert_eq!(column.len(), 3);
1023 assert!(!column.is_empty());
1024
1025 let column = Column::<DoryScalar>::TinyInt(&[1, 2, 3]);
1026 assert_eq!(column.len(), 3);
1027 assert!(!column.is_empty());
1028
1029 let column = Column::<TestScalar>::SmallInt(&[1, 2, 3]);
1030 assert_eq!(column.len(), 3);
1031 assert!(!column.is_empty());
1032
1033 let column = Column::<TestScalar>::Int(&[1, 2, 3]);
1034 assert_eq!(column.len(), 3);
1035 assert!(!column.is_empty());
1036
1037 let column = Column::<TestScalar>::BigInt(&[1, 2, 3]);
1038 assert_eq!(column.len(), 3);
1039 assert!(!column.is_empty());
1040
1041 let column = Column::VarChar((&["a", "b", "c"], &scalar_values));
1042 assert_eq!(column.len(), 3);
1043 assert!(!column.is_empty());
1044
1045 let column = Column::<DoryScalar>::Int128(&[1, 2, 3]);
1046 assert_eq!(column.len(), 3);
1047 assert!(!column.is_empty());
1048
1049 let column = Column::Scalar(&scalar_values);
1050 assert_eq!(column.len(), 3);
1051 assert!(!column.is_empty());
1052
1053 let decimal_data = [
1054 TestScalar::from(1),
1055 TestScalar::from(2),
1056 TestScalar::from(3),
1057 ];
1058
1059 let precision = Precision::new(precision).unwrap();
1060 let column = Column::Decimal75(precision, scale, &decimal_data);
1061 assert_eq!(column.len(), 3);
1062 assert!(!column.is_empty());
1063
1064 let column = Column::<DoryScalar>::Boolean(&[]);
1066 assert_eq!(column.len(), 0);
1067 assert!(column.is_empty());
1068
1069 let column = Column::<DoryScalar>::TinyInt(&[]);
1070 assert_eq!(column.len(), 0);
1071 assert!(column.is_empty());
1072
1073 let column = Column::<TestScalar>::SmallInt(&[]);
1074 assert_eq!(column.len(), 0);
1075 assert!(column.is_empty());
1076
1077 let column = Column::<TestScalar>::Int(&[]);
1078 assert_eq!(column.len(), 0);
1079 assert!(column.is_empty());
1080
1081 let column = Column::<TestScalar>::BigInt(&[]);
1082 assert_eq!(column.len(), 0);
1083 assert!(column.is_empty());
1084
1085 let column = Column::<DoryScalar>::VarChar((&[], &[]));
1086 assert_eq!(column.len(), 0);
1087 assert!(column.is_empty());
1088
1089 let column = Column::<TestScalar>::Int128(&[]);
1090 assert_eq!(column.len(), 0);
1091 assert!(column.is_empty());
1092
1093 let column = Column::<DoryScalar>::Scalar(&[]);
1094 assert_eq!(column.len(), 0);
1095 assert!(column.is_empty());
1096
1097 let column: Column<'_, TestScalar> = Column::Decimal75(precision, scale, &[]);
1098 assert_eq!(column.len(), 0);
1099 assert!(column.is_empty());
1100 }
1101
1102 #[test]
1103 fn we_can_convert_owned_columns_to_columns_round_trip() {
1104 let alloc = Bump::new();
1105 let owned_col: OwnedColumn<TestScalar> = OwnedColumn::Int128(vec![1, 2, 3, 4, 5]);
1107 let col = Column::<TestScalar>::from_owned_column(&owned_col, &alloc);
1108 assert_eq!(col, Column::Int128(&[1, 2, 3, 4, 5]));
1109 let new_owned_col = (&col).into();
1110 assert_eq!(owned_col, new_owned_col);
1111
1112 let owned_col: OwnedColumn<TestScalar> =
1114 OwnedColumn::Boolean(vec![true, false, true, false, true]);
1115 let col = Column::<TestScalar>::from_owned_column(&owned_col, &alloc);
1116 assert_eq!(col, Column::Boolean(&[true, false, true, false, true]));
1117 let new_owned_col = (&col).into();
1118 assert_eq!(owned_col, new_owned_col);
1119
1120 let strs = [
1122 "Space and Time",
1123 "Tér és Idő",
1124 "Пространство и время",
1125 "Spațiu și Timp",
1126 "Spazju u Ħin",
1127 ];
1128 let scalars = strs.iter().map(TestScalar::from).collect::<Vec<_>>();
1129 let owned_col = OwnedColumn::VarChar(
1130 strs.iter()
1131 .map(ToString::to_string)
1132 .collect::<Vec<String>>(),
1133 );
1134 let col = Column::<TestScalar>::from_owned_column(&owned_col, &alloc);
1135 assert_eq!(col, Column::VarChar((&strs, &scalars)));
1136 let new_owned_col = (&col).into();
1137 assert_eq!(owned_col, new_owned_col);
1138
1139 let scalars: Vec<TestScalar> = [1, 2, 3, 4, 5].iter().map(TestScalar::from).collect();
1141 let owned_col: OwnedColumn<TestScalar> =
1142 OwnedColumn::Decimal75(Precision::new(75).unwrap(), 127, scalars.clone());
1143 let col = Column::<TestScalar>::from_owned_column(&owned_col, &alloc);
1144 assert_eq!(
1145 col,
1146 Column::Decimal75(Precision::new(75).unwrap(), 127, &scalars)
1147 );
1148 let new_owned_col = (&col).into();
1149 assert_eq!(owned_col, new_owned_col);
1150 }
1151
1152 #[test]
1153 fn we_can_get_the_data_size_of_a_column() {
1154 let column = Column::<DoryScalar>::Boolean(&[true, false, true]);
1155 assert_eq!(column.column_type().byte_size(), 1);
1156 assert_eq!(column.column_type().bit_size(), 8);
1157
1158 let column = Column::<TestScalar>::TinyInt(&[1, 2, 3, 4]);
1159 assert_eq!(column.column_type().byte_size(), 1);
1160 assert_eq!(column.column_type().bit_size(), 8);
1161
1162 let column = Column::<TestScalar>::SmallInt(&[1, 2, 3, 4]);
1163 assert_eq!(column.column_type().byte_size(), 2);
1164 assert_eq!(column.column_type().bit_size(), 16);
1165
1166 let column = Column::<TestScalar>::Int(&[1, 2, 3]);
1167 assert_eq!(column.column_type().byte_size(), 4);
1168 assert_eq!(column.column_type().bit_size(), 32);
1169
1170 let column = Column::<TestScalar>::BigInt(&[1]);
1171 assert_eq!(column.column_type().byte_size(), 8);
1172 assert_eq!(column.column_type().bit_size(), 64);
1173
1174 let column = Column::<DoryScalar>::Int128(&[1, 2]);
1175 assert_eq!(column.column_type().byte_size(), 16);
1176 assert_eq!(column.column_type().bit_size(), 128);
1177
1178 let scalar_values = [
1179 TestScalar::from(1),
1180 TestScalar::from(2),
1181 TestScalar::from(3),
1182 ];
1183
1184 let column = Column::VarChar((&["a", "b", "c", "d", "e"], &scalar_values));
1185 assert_eq!(column.column_type().byte_size(), 32);
1186 assert_eq!(column.column_type().bit_size(), 256);
1187
1188 let column = Column::Scalar(&scalar_values);
1189 assert_eq!(column.column_type().byte_size(), 32);
1190 assert_eq!(column.column_type().bit_size(), 256);
1191
1192 let precision = 10;
1193 let scale = 2;
1194 let decimal_data = [
1195 TestScalar::from(1),
1196 TestScalar::from(2),
1197 TestScalar::from(3),
1198 ];
1199
1200 let precision = Precision::new(precision).unwrap();
1201 let column = Column::Decimal75(precision, scale, &decimal_data);
1202 assert_eq!(column.column_type().byte_size(), 32);
1203 assert_eq!(column.column_type().bit_size(), 256);
1204
1205 let column: Column<'_, DoryScalar> =
1206 Column::TimestampTZ(PoSQLTimeUnit::Second, PoSQLTimeZone::utc(), &[1, 2, 3]);
1207 assert_eq!(column.column_type().byte_size(), 8);
1208 assert_eq!(column.column_type().bit_size(), 64);
1209 }
1210
1211 #[test]
1212 fn we_can_get_length_of_varbinary_column() {
1213 let raw_bytes: &[&[u8]] = &[b"foo", b"bar", b""];
1214 let scalars: Vec<TestScalar> = raw_bytes
1215 .iter()
1216 .map(|b| TestScalar::from_le_bytes_mod_order(b))
1217 .collect();
1218
1219 let column = Column::VarBinary((raw_bytes, &scalars));
1220 assert_eq!(column.len(), 3);
1221 assert!(!column.is_empty());
1222 assert_eq!(column.column_type(), ColumnType::VarBinary);
1223 }
1224
1225 #[test]
1226 fn we_can_convert_varbinary_owned_column_to_column_and_back() {
1227 use bumpalo::Bump;
1228 let alloc = Bump::new();
1229
1230 let owned_varbinary = OwnedColumn::VarBinary(vec![b"abc".to_vec(), b"xyz".to_vec()]);
1231
1232 let column = Column::<TestScalar>::from_owned_column(&owned_varbinary, &alloc);
1233 match column {
1234 Column::VarBinary((bytes, scalars)) => {
1235 assert_eq!(bytes.len(), 2);
1236 assert_eq!(scalars.len(), 2);
1237 assert_eq!(bytes[0], b"abc");
1238 assert_eq!(bytes[1], b"xyz");
1239 }
1240 _ => panic!("Expected VarBinary column"),
1241 }
1242
1243 let round_trip_owned: OwnedColumn<TestScalar> = (&column).into();
1244 assert_eq!(owned_varbinary, round_trip_owned);
1245 }
1246
1247 #[test]
1248 fn we_can_get_min_scalar() {
1249 assert_eq!(
1250 ColumnType::TinyInt.min_scalar(),
1251 Some(TestScalar::from(i8::MIN))
1252 );
1253 assert_eq!(
1254 ColumnType::SmallInt.min_scalar(),
1255 Some(TestScalar::from(i16::MIN))
1256 );
1257 assert_eq!(
1258 ColumnType::Int.min_scalar(),
1259 Some(TestScalar::from(i32::MIN))
1260 );
1261 assert_eq!(
1262 ColumnType::BigInt.min_scalar(),
1263 Some(TestScalar::from(i64::MIN))
1264 );
1265 assert_eq!(
1266 ColumnType::Int128.min_scalar(),
1267 Some(TestScalar::from(i128::MIN))
1268 );
1269 assert_eq!(ColumnType::Uint8.min_scalar::<TestScalar>(), None);
1270 assert_eq!(ColumnType::Scalar.min_scalar::<TestScalar>(), None);
1271 assert_eq!(ColumnType::Boolean.min_scalar::<TestScalar>(), None);
1272 assert_eq!(ColumnType::VarBinary.min_scalar::<TestScalar>(), None);
1273 assert_eq!(
1274 ColumnType::TimestampTZ(PoSQLTimeUnit::Second, PoSQLTimeZone::new(0))
1275 .min_scalar::<TestScalar>(),
1276 None
1277 );
1278 assert_eq!(
1279 ColumnType::Decimal75(Precision::new(1).unwrap(), 1).min_scalar::<TestScalar>(),
1280 None
1281 );
1282 assert_eq!(ColumnType::VarChar.min_scalar::<TestScalar>(), None);
1283 }
1284
1285 #[test]
1286 fn we_can_get_sqrt_negative_min() {
1287 for column_type in [
1288 ColumnType::TinyInt,
1289 ColumnType::SmallInt,
1290 ColumnType::Int,
1291 ColumnType::BigInt,
1292 ColumnType::Int128,
1293 ] {
1294 let floor = TestScalar::from(column_type.sqrt_negative_min().unwrap());
1295 let ceiling = floor + TestScalar::ONE;
1296 let floor_squared = floor * floor;
1297 let ceiling_squared = ceiling * ceiling;
1298 let negative_min_scalar = -column_type.min_scalar::<TestScalar>().unwrap();
1299 assert!(floor_squared <= negative_min_scalar);
1300 assert!(negative_min_scalar < ceiling_squared);
1301 }
1302 for column_type in [
1303 ColumnType::Uint8,
1304 ColumnType::Scalar,
1305 ColumnType::Boolean,
1306 ColumnType::VarBinary,
1307 ColumnType::TimestampTZ(PoSQLTimeUnit::Second, PoSQLTimeZone::new(1)),
1308 ColumnType::Decimal75(Precision::new(1).unwrap(), 1),
1309 ColumnType::VarChar,
1310 ] {
1311 assert_eq!(column_type.sqrt_negative_min(), None);
1312 }
1313 }
1314}