1use crate::error::Error::IllegalArgument;
19use crate::error::Result;
20use serde::{Deserialize, Serialize};
21use std::fmt::{Display, Formatter};
22
23#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
26pub enum DataType {
27 Boolean(BooleanType),
28 TinyInt(TinyIntType),
29 SmallInt(SmallIntType),
30 Int(IntType),
31 BigInt(BigIntType),
32 Float(FloatType),
33 Double(DoubleType),
34 Char(CharType),
35 String(StringType),
36 Decimal(DecimalType),
37 Date(DateType),
38 Time(TimeType),
39 Timestamp(TimestampType),
40 TimestampLTz(TimestampLTzType),
41 Bytes(BytesType),
42 Binary(BinaryType),
43 Array(ArrayType),
44 Map(MapType),
45 Row(RowType),
46}
47
48impl DataType {
49 pub fn is_nullable(&self) -> bool {
50 match self {
51 DataType::Boolean(v) => v.nullable,
52 DataType::TinyInt(v) => v.nullable,
53 DataType::SmallInt(v) => v.nullable,
54 DataType::Int(v) => v.nullable,
55 DataType::BigInt(v) => v.nullable,
56 DataType::Decimal(v) => v.nullable,
57 DataType::Double(v) => v.nullable,
58 DataType::Float(v) => v.nullable,
59 DataType::Binary(v) => v.nullable,
60 DataType::Char(v) => v.nullable,
61 DataType::String(v) => v.nullable,
62 DataType::Date(v) => v.nullable,
63 DataType::TimestampLTz(v) => v.nullable,
64 DataType::Time(v) => v.nullable,
65 DataType::Timestamp(v) => v.nullable,
66 DataType::Array(v) => v.nullable,
67 DataType::Map(v) => v.nullable,
68 DataType::Row(v) => v.nullable,
69 DataType::Bytes(v) => v.nullable,
70 }
71 }
72
73 pub fn as_non_nullable(&self) -> Self {
74 match self {
75 DataType::Boolean(v) => DataType::Boolean(v.as_non_nullable()),
76 DataType::TinyInt(v) => DataType::TinyInt(v.as_non_nullable()),
77 DataType::SmallInt(v) => DataType::SmallInt(v.as_non_nullable()),
78 DataType::Int(v) => DataType::Int(v.as_non_nullable()),
79 DataType::BigInt(v) => DataType::BigInt(v.as_non_nullable()),
80 DataType::Decimal(v) => DataType::Decimal(v.as_non_nullable()),
81 DataType::Double(v) => DataType::Double(v.as_non_nullable()),
82 DataType::Float(v) => DataType::Float(v.as_non_nullable()),
83 DataType::Binary(v) => DataType::Binary(v.as_non_nullable()),
84 DataType::Char(v) => DataType::Char(v.as_non_nullable()),
85 DataType::String(v) => DataType::String(v.as_non_nullable()),
86 DataType::Date(v) => DataType::Date(v.as_non_nullable()),
87 DataType::TimestampLTz(v) => DataType::TimestampLTz(v.as_non_nullable()),
88 DataType::Time(v) => DataType::Time(v.as_non_nullable()),
89 DataType::Timestamp(v) => DataType::Timestamp(v.as_non_nullable()),
90 DataType::Array(v) => DataType::Array(v.as_non_nullable()),
91 DataType::Map(v) => DataType::Map(v.as_non_nullable()),
92 DataType::Row(v) => DataType::Row(v.as_non_nullable()),
93 DataType::Bytes(v) => DataType::Bytes(v.as_non_nullable()),
94 }
95 }
96}
97
98impl Display for DataType {
99 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
100 match self {
101 DataType::Boolean(v) => write!(f, "{v}"),
102 DataType::TinyInt(v) => write!(f, "{v}"),
103 DataType::SmallInt(v) => write!(f, "{v}"),
104 DataType::Int(v) => write!(f, "{v}"),
105 DataType::BigInt(v) => write!(f, "{v}"),
106 DataType::Float(v) => write!(f, "{v}"),
107 DataType::Double(v) => write!(f, "{v}"),
108 DataType::Char(v) => write!(f, "{v}"),
109 DataType::String(v) => write!(f, "{v}"),
110 DataType::Decimal(v) => write!(f, "{v}"),
111 DataType::Date(v) => write!(f, "{v}"),
112 DataType::Time(v) => write!(f, "{v}"),
113 DataType::Timestamp(v) => write!(f, "{v}"),
114 DataType::TimestampLTz(v) => write!(f, "{v}"),
115 DataType::Bytes(v) => write!(f, "{v}"),
116 DataType::Binary(v) => write!(f, "{v}"),
117 DataType::Array(v) => write!(f, "{v}"),
118 DataType::Map(v) => write!(f, "{v}"),
119 DataType::Row(v) => write!(f, "{v}"),
120 }
121 }
122}
123
124#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
125pub struct BooleanType {
126 nullable: bool,
127}
128
129impl Default for BooleanType {
130 fn default() -> Self {
131 Self::new()
132 }
133}
134
135impl BooleanType {
136 pub fn new() -> Self {
137 Self::with_nullable(true)
138 }
139
140 pub fn with_nullable(nullable: bool) -> Self {
141 Self { nullable }
142 }
143
144 pub fn as_non_nullable(&self) -> Self {
145 Self::with_nullable(false)
146 }
147}
148
149impl Display for BooleanType {
150 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
151 write!(f, "BOOLEAN")?;
152 if !self.nullable {
153 write!(f, " NOT NULL")?;
154 }
155 Ok(())
156 }
157}
158
159#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
160pub struct TinyIntType {
161 nullable: bool,
162}
163
164impl Default for TinyIntType {
165 fn default() -> Self {
166 Self::new()
167 }
168}
169
170impl TinyIntType {
171 pub fn new() -> Self {
172 Self::with_nullable(true)
173 }
174
175 pub fn with_nullable(nullable: bool) -> Self {
176 Self { nullable }
177 }
178
179 pub fn as_non_nullable(&self) -> Self {
180 Self::with_nullable(false)
181 }
182}
183
184impl Display for TinyIntType {
185 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
186 write!(f, "TINYINT")?;
187 if !self.nullable {
188 write!(f, " NOT NULL")?;
189 }
190 Ok(())
191 }
192}
193
194#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
195pub struct SmallIntType {
196 nullable: bool,
197}
198
199impl Default for SmallIntType {
200 fn default() -> Self {
201 Self::new()
202 }
203}
204
205impl SmallIntType {
206 pub fn new() -> Self {
207 Self::with_nullable(true)
208 }
209
210 pub fn with_nullable(nullable: bool) -> Self {
211 Self { nullable }
212 }
213
214 pub fn as_non_nullable(&self) -> Self {
215 Self::with_nullable(false)
216 }
217}
218
219impl Display for SmallIntType {
220 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
221 write!(f, "SMALLINT")?;
222 if !self.nullable {
223 write!(f, " NOT NULL")?;
224 }
225 Ok(())
226 }
227}
228
229#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
230pub struct IntType {
231 nullable: bool,
232}
233
234impl Default for IntType {
235 fn default() -> Self {
236 Self::new()
237 }
238}
239
240impl IntType {
241 pub fn new() -> Self {
242 Self::with_nullable(true)
243 }
244
245 pub fn with_nullable(nullable: bool) -> Self {
246 Self { nullable }
247 }
248
249 pub fn as_non_nullable(&self) -> Self {
250 Self::with_nullable(false)
251 }
252}
253
254impl Display for IntType {
255 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
256 write!(f, "INT")?;
257 if !self.nullable {
258 write!(f, " NOT NULL")?;
259 }
260 Ok(())
261 }
262}
263
264#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
265pub struct BigIntType {
266 nullable: bool,
267}
268
269impl Default for BigIntType {
270 fn default() -> Self {
271 Self::new()
272 }
273}
274
275impl BigIntType {
276 pub fn new() -> Self {
277 Self::with_nullable(true)
278 }
279
280 pub fn with_nullable(nullable: bool) -> Self {
281 Self { nullable }
282 }
283
284 pub fn as_non_nullable(&self) -> Self {
285 Self::with_nullable(false)
286 }
287}
288
289impl Display for BigIntType {
290 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
291 write!(f, "BIGINT")?;
292 if !self.nullable {
293 write!(f, " NOT NULL")?;
294 }
295 Ok(())
296 }
297}
298
299#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
300pub struct FloatType {
301 nullable: bool,
302}
303
304impl Default for FloatType {
305 fn default() -> Self {
306 Self::new()
307 }
308}
309
310impl FloatType {
311 pub fn new() -> Self {
312 Self::with_nullable(true)
313 }
314
315 pub fn with_nullable(nullable: bool) -> Self {
316 Self { nullable }
317 }
318
319 pub fn as_non_nullable(&self) -> Self {
320 Self::with_nullable(false)
321 }
322}
323
324impl Display for FloatType {
325 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
326 write!(f, "FLOAT")?;
327 if !self.nullable {
328 write!(f, " NOT NULL")?;
329 }
330 Ok(())
331 }
332}
333
334#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
335pub struct DoubleType {
336 nullable: bool,
337}
338
339impl Default for DoubleType {
340 fn default() -> Self {
341 Self::new()
342 }
343}
344
345impl DoubleType {
346 pub fn new() -> Self {
347 Self::with_nullable(true)
348 }
349
350 pub fn with_nullable(nullable: bool) -> Self {
351 Self { nullable }
352 }
353
354 pub fn as_non_nullable(&self) -> Self {
355 Self::with_nullable(false)
356 }
357}
358
359impl Display for DoubleType {
360 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
361 write!(f, "DOUBLE")?;
362 if !self.nullable {
363 write!(f, " NOT NULL")?;
364 }
365 Ok(())
366 }
367}
368
369#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
370pub struct CharType {
371 nullable: bool,
372 length: u32,
373}
374
375impl CharType {
376 pub fn new(length: u32) -> Self {
377 Self::with_nullable(length, true)
378 }
379
380 pub fn with_nullable(length: u32, nullable: bool) -> Self {
381 Self { nullable, length }
382 }
383
384 pub fn as_non_nullable(&self) -> Self {
385 Self::with_nullable(self.length, false)
386 }
387
388 pub fn length(&self) -> u32 {
389 self.length
390 }
391}
392
393impl Default for CharType {
394 fn default() -> Self {
395 Self::new(1)
396 }
397}
398
399impl Display for CharType {
400 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
401 write!(f, "CHAR({})", self.length)?;
402 if !self.nullable {
403 write!(f, " NOT NULL")?;
404 }
405 Ok(())
406 }
407}
408
409#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
410pub struct StringType {
411 nullable: bool,
412}
413
414impl Default for StringType {
415 fn default() -> Self {
416 Self::new()
417 }
418}
419
420impl StringType {
421 pub fn new() -> Self {
422 Self::with_nullable(true)
423 }
424
425 pub fn with_nullable(nullable: bool) -> Self {
426 Self { nullable }
427 }
428
429 pub fn as_non_nullable(&self) -> Self {
430 Self::with_nullable(false)
431 }
432}
433
434impl Display for StringType {
435 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
436 write!(f, "STRING")?;
437 if !self.nullable {
438 write!(f, " NOT NULL")?;
439 }
440 Ok(())
441 }
442}
443
444#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
445pub struct DecimalType {
446 nullable: bool,
447 precision: u32,
448 scale: u32,
449}
450
451impl DecimalType {
452 pub const MIN_PRECISION: u32 = 1;
453
454 pub const MAX_PRECISION: u32 = 38;
455
456 pub const DEFAULT_PRECISION: u32 = 10;
457
458 pub const MIN_SCALE: u32 = 0;
459
460 pub const DEFAULT_SCALE: u32 = 0;
461
462 pub fn new(precision: u32, scale: u32) -> Result<Self> {
463 Self::with_nullable(true, precision, scale)
464 }
465
466 pub fn with_nullable(nullable: bool, precision: u32, scale: u32) -> Result<Self> {
468 if !(Self::MIN_PRECISION..=Self::MAX_PRECISION).contains(&precision) {
470 return Err(IllegalArgument {
471 message: format!(
472 "Decimal precision must be between {} and {} (both inclusive), got: {}",
473 Self::MIN_PRECISION,
474 Self::MAX_PRECISION,
475 precision
476 ),
477 });
478 }
479 if scale > precision {
482 return Err(IllegalArgument {
483 message: format!(
484 "Decimal scale must be between {} and the precision {} (both inclusive), got: {}",
485 Self::MIN_SCALE,
486 precision,
487 scale
488 ),
489 });
490 }
491 Ok(DecimalType {
492 nullable,
493 precision,
494 scale,
495 })
496 }
497
498 pub fn precision(&self) -> u32 {
499 self.precision
500 }
501
502 pub fn scale(&self) -> u32 {
503 self.scale
504 }
505
506 pub fn as_non_nullable(&self) -> Self {
507 Self::with_nullable(false, self.precision, self.scale)
508 .expect("Invalid decimal precision or scale")
509 }
510}
511
512impl Default for DecimalType {
513 fn default() -> Self {
514 Self::new(Self::DEFAULT_PRECISION, Self::DEFAULT_SCALE)
515 .expect("Invalid default decimal precision or scale")
516 }
517}
518
519impl Display for DecimalType {
520 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
521 write!(f, "DECIMAL({}, {})", self.precision, self.scale)?;
522 if !self.nullable {
523 write!(f, " NOT NULL")?;
524 }
525 Ok(())
526 }
527}
528
529#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
530pub struct DateType {
531 nullable: bool,
532}
533
534impl Default for DateType {
535 fn default() -> Self {
536 Self::new()
537 }
538}
539
540impl DateType {
541 pub fn new() -> Self {
542 Self::with_nullable(true)
543 }
544
545 pub fn with_nullable(nullable: bool) -> Self {
546 Self { nullable }
547 }
548
549 pub fn as_non_nullable(&self) -> Self {
550 Self::with_nullable(false)
551 }
552}
553
554impl Display for DateType {
555 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
556 write!(f, "DATE")?;
557 if !self.nullable {
558 write!(f, " NOT NULL")?;
559 }
560 Ok(())
561 }
562}
563
564#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
565pub struct TimeType {
566 nullable: bool,
567 precision: u32,
568}
569
570impl Default for TimeType {
571 fn default() -> Self {
572 Self::new(Self::DEFAULT_PRECISION).expect("Invalid default time precision")
573 }
574}
575
576impl TimeType {
577 pub const MIN_PRECISION: u32 = 0;
578
579 pub const MAX_PRECISION: u32 = 9;
580
581 pub const DEFAULT_PRECISION: u32 = 0;
582
583 pub fn new(precision: u32) -> Result<Self> {
584 Self::with_nullable(true, precision)
585 }
586
587 pub fn with_nullable(nullable: bool, precision: u32) -> Result<Self> {
589 if !(Self::MIN_PRECISION..=Self::MAX_PRECISION).contains(&precision) {
591 return Err(IllegalArgument {
592 message: format!(
593 "Time precision must be between {} and {} (both inclusive), got: {}",
594 Self::MIN_PRECISION,
595 Self::MAX_PRECISION,
596 precision
597 ),
598 });
599 }
600 Ok(TimeType {
601 nullable,
602 precision,
603 })
604 }
605
606 pub fn precision(&self) -> u32 {
607 self.precision
608 }
609
610 pub fn as_non_nullable(&self) -> Self {
611 Self::with_nullable(false, self.precision).expect("Invalid time precision")
612 }
613}
614
615impl Display for TimeType {
616 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
617 write!(f, "TIME({})", self.precision)?;
618 if !self.nullable {
619 write!(f, " NOT NULL")?;
620 }
621 Ok(())
622 }
623}
624
625#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
626pub struct TimestampType {
627 nullable: bool,
628 precision: u32,
629}
630
631impl Default for TimestampType {
632 fn default() -> Self {
633 Self::new(Self::DEFAULT_PRECISION).expect("Invalid default timestamp precision")
634 }
635}
636
637impl TimestampType {
638 pub const MIN_PRECISION: u32 = 0;
639
640 pub const MAX_PRECISION: u32 = 9;
641
642 pub const DEFAULT_PRECISION: u32 = 6;
643
644 pub fn new(precision: u32) -> Result<Self> {
645 Self::with_nullable(true, precision)
646 }
647
648 pub fn with_nullable(nullable: bool, precision: u32) -> Result<Self> {
650 if !(Self::MIN_PRECISION..=Self::MAX_PRECISION).contains(&precision) {
652 return Err(IllegalArgument {
653 message: format!(
654 "Timestamp precision must be between {} and {} (both inclusive), got: {}",
655 Self::MIN_PRECISION,
656 Self::MAX_PRECISION,
657 precision
658 ),
659 });
660 }
661 Ok(TimestampType {
662 nullable,
663 precision,
664 })
665 }
666
667 pub fn precision(&self) -> u32 {
668 self.precision
669 }
670
671 pub fn as_non_nullable(&self) -> Self {
672 Self::with_nullable(false, self.precision).expect("Invalid timestamp precision")
673 }
674}
675
676impl Display for TimestampType {
677 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
678 write!(f, "TIMESTAMP({})", self.precision)?;
679 if !self.nullable {
680 write!(f, " NOT NULL")?;
681 }
682 Ok(())
683 }
684}
685
686#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
687pub struct TimestampLTzType {
688 nullable: bool,
689 precision: u32,
690}
691
692impl Default for TimestampLTzType {
693 fn default() -> Self {
694 Self::new(Self::DEFAULT_PRECISION)
695 .expect("Invalid default timestamp with local time zone precision")
696 }
697}
698
699impl TimestampLTzType {
700 pub const MIN_PRECISION: u32 = 0;
701
702 pub const MAX_PRECISION: u32 = 9;
703
704 pub const DEFAULT_PRECISION: u32 = 6;
705
706 pub fn new(precision: u32) -> Result<Self> {
707 Self::with_nullable(true, precision)
708 }
709
710 pub fn with_nullable(nullable: bool, precision: u32) -> Result<Self> {
712 if !(Self::MIN_PRECISION..=Self::MAX_PRECISION).contains(&precision) {
714 return Err(IllegalArgument {
715 message: format!(
716 "Timestamp with local time zone precision must be between {} and {} (both inclusive), got: {}",
717 Self::MIN_PRECISION,
718 Self::MAX_PRECISION,
719 precision
720 ),
721 });
722 }
723 Ok(TimestampLTzType {
724 nullable,
725 precision,
726 })
727 }
728
729 pub fn precision(&self) -> u32 {
730 self.precision
731 }
732
733 pub fn as_non_nullable(&self) -> Self {
734 Self::with_nullable(false, self.precision)
735 .expect("Invalid timestamp with local time zone precision")
736 }
737}
738
739impl Display for TimestampLTzType {
740 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
741 write!(f, "TIMESTAMP_LTZ({})", self.precision)?;
742 if !self.nullable {
743 write!(f, " NOT NULL")?;
744 }
745 Ok(())
746 }
747}
748
749#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
750pub struct BytesType {
751 nullable: bool,
752}
753
754impl Default for BytesType {
755 fn default() -> Self {
756 Self::new()
757 }
758}
759
760impl BytesType {
761 pub const fn new() -> Self {
762 Self::with_nullable(true)
763 }
764
765 pub const fn with_nullable(nullable: bool) -> Self {
766 Self { nullable }
767 }
768
769 pub fn as_non_nullable(&self) -> Self {
770 Self::with_nullable(false)
771 }
772}
773
774impl Display for BytesType {
775 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
776 write!(f, "BYTES")?;
777 if !self.nullable {
778 write!(f, " NOT NULL")?;
779 }
780 Ok(())
781 }
782}
783
784#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
785pub struct BinaryType {
786 nullable: bool,
787 length: usize,
788}
789
790impl BinaryType {
791 pub const MIN_LENGTH: usize = 1;
792
793 pub const MAX_LENGTH: usize = usize::MAX;
794
795 pub const DEFAULT_LENGTH: usize = 1;
796
797 pub fn new(length: usize) -> Self {
798 Self::with_nullable(true, length)
799 }
800
801 pub fn with_nullable(nullable: bool, length: usize) -> Self {
802 Self { nullable, length }
803 }
804
805 pub fn length(&self) -> usize {
806 self.length
807 }
808
809 pub fn as_non_nullable(&self) -> Self {
810 Self::with_nullable(false, self.length)
811 }
812}
813
814impl Default for BinaryType {
815 fn default() -> Self {
816 Self::new(Self::DEFAULT_LENGTH)
817 }
818}
819
820impl Display for BinaryType {
821 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
822 write!(f, "BINARY({})", self.length)?;
823 if !self.nullable {
824 write!(f, " NOT NULL")?;
825 }
826 Ok(())
827 }
828}
829
830#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
831pub struct ArrayType {
832 nullable: bool,
833 element_type: Box<DataType>,
834}
835
836impl ArrayType {
837 pub fn new(element_type: DataType) -> Self {
838 Self::with_nullable(true, element_type)
839 }
840
841 pub fn with_nullable(nullable: bool, element_type: DataType) -> Self {
842 Self {
843 nullable,
844 element_type: Box::new(element_type),
845 }
846 }
847
848 pub fn as_non_nullable(&self) -> Self {
849 Self {
850 nullable: false,
851 element_type: self.element_type.clone(),
852 }
853 }
854
855 pub fn get_element_type(&self) -> &DataType {
856 &self.element_type
857 }
858}
859
860impl Display for ArrayType {
861 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
862 write!(f, "ARRAY<{}>", self.element_type)?;
863 if !self.nullable {
864 write!(f, " NOT NULL")?;
865 }
866 Ok(())
867 }
868}
869
870#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, Hash)]
871pub struct MapType {
872 nullable: bool,
873 key_type: Box<DataType>,
874 value_type: Box<DataType>,
875}
876
877impl MapType {
878 pub fn new(key_type: DataType, value_type: DataType) -> Self {
879 Self::with_nullable(true, key_type, value_type)
880 }
881
882 pub fn with_nullable(nullable: bool, key_type: DataType, value_type: DataType) -> Self {
883 Self {
884 nullable,
885 key_type: Box::new(key_type),
886 value_type: Box::new(value_type),
887 }
888 }
889
890 pub fn as_non_nullable(&self) -> Self {
891 Self {
892 nullable: false,
893 key_type: self.key_type.clone(),
894 value_type: self.value_type.clone(),
895 }
896 }
897
898 pub fn key_type(&self) -> &DataType {
899 &self.key_type
900 }
901
902 pub fn value_type(&self) -> &DataType {
903 &self.value_type
904 }
905}
906
907impl Display for MapType {
908 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
909 write!(f, "MAP<{}, {}>", self.key_type, self.value_type)?;
910 if !self.nullable {
911 write!(f, " NOT NULL")?;
912 }
913 Ok(())
914 }
915}
916
917#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, Hash)]
918pub struct RowType {
919 nullable: bool,
920 fields: Vec<DataField>,
921}
922
923impl RowType {
924 pub const fn new(fields: Vec<DataField>) -> Self {
925 Self::with_nullable(true, fields)
926 }
927
928 pub const fn with_nullable(nullable: bool, fields: Vec<DataField>) -> Self {
929 Self { nullable, fields }
930 }
931
932 pub fn as_non_nullable(&self) -> Self {
933 Self::with_nullable(false, self.fields.clone())
934 }
935
936 pub fn fields(&self) -> &Vec<DataField> {
937 &self.fields
938 }
939
940 pub fn get_field_index(&self, field_name: &str) -> Option<usize> {
941 self.fields.iter().position(|f| f.name == field_name)
942 }
943
944 pub fn field_types(&self) -> impl Iterator<Item = &DataType> + '_ {
945 self.fields.iter().map(|f| &f.data_type)
946 }
947
948 pub fn get_field_names(&self) -> Vec<&str> {
949 self.fields.iter().map(|f| f.name.as_str()).collect()
950 }
951
952 pub fn project_with_field_names(&self, field_names: &[String]) -> Result<RowType> {
953 let indices: Vec<usize> = field_names
954 .iter()
955 .map(|name| {
956 self.get_field_index(name).ok_or_else(|| IllegalArgument {
957 message: format!("Field '{name}' does not exist in the row type"),
958 })
959 })
960 .collect::<Result<Vec<_>>>()?;
961
962 self.project(indices.as_slice())
963 }
964
965 pub fn project(&self, project_field_positions: &[usize]) -> Result<RowType> {
966 Ok(RowType::with_nullable(
967 self.nullable,
968 project_field_positions
969 .iter()
970 .map(|pos| {
971 self.fields
972 .get(*pos)
973 .cloned()
974 .ok_or_else(|| IllegalArgument {
975 message: format!("invalid field position: {}", *pos),
976 })
977 })
978 .collect::<Result<Vec<_>>>()?,
979 ))
980 }
981
982 #[cfg(test)]
983 pub fn with_data_types(data_types: Vec<DataType>) -> Self {
984 let mut fields: Vec<DataField> = Vec::new();
985 data_types.iter().enumerate().for_each(|(idx, data_type)| {
986 fields.push(DataField::new(format!("f{idx}"), data_type.clone(), None));
987 });
988
989 Self::with_nullable(true, fields)
990 }
991
992 #[cfg(test)]
993 pub fn with_data_types_and_field_names(
994 data_types: Vec<DataType>,
995 field_names: Vec<&str>,
996 ) -> Self {
997 let fields = data_types
998 .into_iter()
999 .zip(field_names)
1000 .map(|(data_type, field_name)| {
1001 DataField::new(field_name.to_string(), data_type.clone(), None)
1002 })
1003 .collect::<Vec<_>>();
1004
1005 Self::with_nullable(true, fields)
1006 }
1007}
1008
1009impl Display for RowType {
1010 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1011 write!(f, "ROW<")?;
1012 for (i, field) in self.fields.iter().enumerate() {
1013 if i > 0 {
1014 write!(f, ", ")?;
1015 }
1016 write!(f, "{field}")?;
1017 }
1018 write!(f, ">")?;
1019 if !self.nullable {
1020 write!(f, " NOT NULL")?;
1021 }
1022 Ok(())
1023 }
1024}
1025
1026pub struct DataTypes;
1027
1028impl DataTypes {
1029 pub fn binary(length: usize) -> DataType {
1030 DataType::Binary(BinaryType::new(length))
1031 }
1032
1033 pub const fn bytes() -> DataType {
1034 DataType::Bytes(BytesType::new())
1035 }
1036
1037 pub fn boolean() -> DataType {
1038 DataType::Boolean(BooleanType::new())
1039 }
1040
1041 pub fn int() -> DataType {
1042 DataType::Int(IntType::new())
1043 }
1044
1045 pub fn tinyint() -> DataType {
1047 DataType::TinyInt(TinyIntType::new())
1048 }
1049
1050 pub fn smallint() -> DataType {
1052 DataType::SmallInt(SmallIntType::new())
1053 }
1054
1055 pub fn bigint() -> DataType {
1056 DataType::BigInt(BigIntType::new())
1057 }
1058
1059 pub fn float() -> DataType {
1061 DataType::Float(FloatType::new())
1062 }
1063
1064 pub fn double() -> DataType {
1066 DataType::Double(DoubleType::new())
1067 }
1068
1069 pub fn char(length: u32) -> DataType {
1070 DataType::Char(CharType::new(length))
1071 }
1072
1073 pub fn string() -> DataType {
1075 DataType::String(StringType::new())
1076 }
1077
1078 pub fn decimal(precision: u32, scale: u32) -> DataType {
1083 DataType::Decimal(DecimalType::new(precision, scale).expect("Invalid decimal parameters"))
1084 }
1085
1086 pub fn date() -> DataType {
1087 DataType::Date(DateType::new())
1088 }
1089
1090 pub fn time() -> DataType {
1092 DataType::Time(TimeType::default())
1093 }
1094
1095 pub fn time_with_precision(precision: u32) -> DataType {
1098 DataType::Time(TimeType::new(precision).expect("Invalid time precision"))
1099 }
1100
1101 pub fn timestamp() -> DataType {
1104 DataType::Timestamp(TimestampType::default())
1105 }
1106
1107 pub fn timestamp_with_precision(precision: u32) -> DataType {
1111 DataType::Timestamp(TimestampType::new(precision).expect("Invalid timestamp precision"))
1112 }
1113
1114 pub fn timestamp_ltz() -> DataType {
1117 DataType::TimestampLTz(TimestampLTzType::default())
1118 }
1119
1120 pub fn timestamp_ltz_with_precision(precision: u32) -> DataType {
1123 DataType::TimestampLTz(
1124 TimestampLTzType::new(precision)
1125 .expect("Invalid timestamp with local time zone precision"),
1126 )
1127 }
1128
1129 pub fn array(element: DataType) -> DataType {
1131 DataType::Array(ArrayType::new(element))
1132 }
1133
1134 pub fn map(key_type: DataType, value_type: DataType) -> DataType {
1136 DataType::Map(MapType::new(key_type, value_type))
1137 }
1138
1139 pub fn field<N: Into<String>>(name: N, data_type: DataType) -> DataField {
1141 DataField::new(name, data_type, None)
1142 }
1143
1144 pub fn field_with_description<N: Into<String>>(
1146 name: N,
1147 data_type: DataType,
1148 description: String,
1149 ) -> DataField {
1150 DataField::new(name, data_type, Some(description))
1151 }
1152
1153 pub fn row(fields: Vec<DataField>) -> DataType {
1155 DataType::Row(RowType::new(fields))
1156 }
1157
1158 pub fn row_from_types(field_types: Vec<DataType>) -> DataType {
1160 let fields = field_types
1161 .into_iter()
1162 .enumerate()
1163 .map(|(i, dt)| DataField::new(format!("f{i}"), dt, None))
1164 .collect();
1165 DataType::Row(RowType::new(fields))
1166 }
1167}
1168
1169#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
1170pub struct DataField {
1171 pub name: String,
1172 pub data_type: DataType,
1173 pub description: Option<String>,
1174}
1175
1176impl DataField {
1177 pub fn new<N: Into<String>>(
1178 name: N,
1179 data_type: DataType,
1180 description: Option<String>,
1181 ) -> DataField {
1182 DataField {
1183 name: name.into(),
1184 data_type,
1185 description,
1186 }
1187 }
1188
1189 pub fn name(&self) -> &str {
1190 &self.name
1191 }
1192
1193 pub fn data_type(&self) -> &DataType {
1194 &self.data_type
1195 }
1196}
1197
1198impl Display for DataField {
1199 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1200 write!(f, "{} {}", self.name, self.data_type)
1201 }
1202}
1203
1204#[test]
1205fn test_primitive_types_display() {
1206 assert_eq!(BooleanType::new().to_string(), "BOOLEAN");
1208 assert_eq!(
1209 BooleanType::with_nullable(false).to_string(),
1210 "BOOLEAN NOT NULL"
1211 );
1212
1213 assert_eq!(TinyIntType::new().to_string(), "TINYINT");
1214 assert_eq!(
1215 TinyIntType::with_nullable(false).to_string(),
1216 "TINYINT NOT NULL"
1217 );
1218
1219 assert_eq!(SmallIntType::new().to_string(), "SMALLINT");
1220 assert_eq!(
1221 SmallIntType::with_nullable(false).to_string(),
1222 "SMALLINT NOT NULL"
1223 );
1224
1225 assert_eq!(IntType::new().to_string(), "INT");
1226 assert_eq!(IntType::with_nullable(false).to_string(), "INT NOT NULL");
1227
1228 assert_eq!(BigIntType::new().to_string(), "BIGINT");
1229 assert_eq!(
1230 BigIntType::with_nullable(false).to_string(),
1231 "BIGINT NOT NULL"
1232 );
1233
1234 assert_eq!(FloatType::new().to_string(), "FLOAT");
1235 assert_eq!(
1236 FloatType::with_nullable(false).to_string(),
1237 "FLOAT NOT NULL"
1238 );
1239
1240 assert_eq!(DoubleType::new().to_string(), "DOUBLE");
1241 assert_eq!(
1242 DoubleType::with_nullable(false).to_string(),
1243 "DOUBLE NOT NULL"
1244 );
1245
1246 assert_eq!(StringType::new().to_string(), "STRING");
1247 assert_eq!(
1248 StringType::with_nullable(false).to_string(),
1249 "STRING NOT NULL"
1250 );
1251
1252 assert_eq!(DateType::new().to_string(), "DATE");
1253 assert_eq!(DateType::with_nullable(false).to_string(), "DATE NOT NULL");
1254
1255 assert_eq!(BytesType::new().to_string(), "BYTES");
1256 assert_eq!(
1257 BytesType::with_nullable(false).to_string(),
1258 "BYTES NOT NULL"
1259 );
1260}
1261
1262#[test]
1263fn test_parameterized_types_display() {
1264 assert_eq!(CharType::new(10).to_string(), "CHAR(10)");
1266 assert_eq!(
1267 CharType::with_nullable(20, false).to_string(),
1268 "CHAR(20) NOT NULL"
1269 );
1270
1271 assert_eq!(BinaryType::new(100).to_string(), "BINARY(100)");
1272 assert_eq!(
1273 BinaryType::with_nullable(false, 256).to_string(),
1274 "BINARY(256) NOT NULL"
1275 );
1276
1277 assert_eq!(
1278 DecimalType::new(10, 2).unwrap().to_string(),
1279 "DECIMAL(10, 2)"
1280 );
1281 assert_eq!(
1282 DecimalType::with_nullable(false, 38, 10)
1283 .unwrap()
1284 .to_string(),
1285 "DECIMAL(38, 10) NOT NULL"
1286 );
1287
1288 assert_eq!(TimeType::new(0).unwrap().to_string(), "TIME(0)");
1289 assert_eq!(TimeType::new(3).unwrap().to_string(), "TIME(3)");
1290 assert_eq!(
1291 TimeType::with_nullable(false, 9).unwrap().to_string(),
1292 "TIME(9) NOT NULL"
1293 );
1294
1295 assert_eq!(TimestampType::new(6).unwrap().to_string(), "TIMESTAMP(6)");
1296 assert_eq!(TimestampType::new(0).unwrap().to_string(), "TIMESTAMP(0)");
1297 assert_eq!(
1298 TimestampType::with_nullable(false, 9).unwrap().to_string(),
1299 "TIMESTAMP(9) NOT NULL"
1300 );
1301
1302 assert_eq!(
1303 TimestampLTzType::new(6).unwrap().to_string(),
1304 "TIMESTAMP_LTZ(6)"
1305 );
1306 assert_eq!(
1307 TimestampLTzType::new(3).unwrap().to_string(),
1308 "TIMESTAMP_LTZ(3)"
1309 );
1310 assert_eq!(
1311 TimestampLTzType::with_nullable(false, 9)
1312 .unwrap()
1313 .to_string(),
1314 "TIMESTAMP_LTZ(9) NOT NULL"
1315 );
1316}
1317
1318#[test]
1319fn test_array_display() {
1320 let array_type = ArrayType::new(DataTypes::int());
1321 assert_eq!(array_type.to_string(), "ARRAY<INT>");
1322
1323 let array_type_non_null = ArrayType::with_nullable(false, DataTypes::string());
1324 assert_eq!(array_type_non_null.to_string(), "ARRAY<STRING> NOT NULL");
1325
1326 let nested_array = ArrayType::new(DataTypes::array(DataTypes::int()));
1327 assert_eq!(nested_array.to_string(), "ARRAY<ARRAY<INT>>");
1328}
1329
1330#[test]
1331fn test_map_display() {
1332 let map_type = MapType::new(DataTypes::string(), DataTypes::int());
1333 assert_eq!(map_type.to_string(), "MAP<STRING, INT>");
1334
1335 let map_type_non_null = MapType::with_nullable(false, DataTypes::int(), DataTypes::string());
1336 assert_eq!(map_type_non_null.to_string(), "MAP<INT, STRING> NOT NULL");
1337
1338 let nested_map = MapType::new(
1339 DataTypes::string(),
1340 DataTypes::map(DataTypes::int(), DataTypes::boolean()),
1341 );
1342 assert_eq!(nested_map.to_string(), "MAP<STRING, MAP<INT, BOOLEAN>>");
1343}
1344
1345#[test]
1346fn test_row_display() {
1347 let fields = vec![
1348 DataTypes::field("id", DataTypes::int()),
1349 DataTypes::field("name", DataTypes::string()),
1350 ];
1351 let row_type = RowType::new(fields);
1352 assert_eq!(row_type.to_string(), "ROW<id INT, name STRING>");
1353
1354 let fields_non_null = vec![DataTypes::field("age", DataTypes::bigint())];
1355 let row_type_non_null = RowType::with_nullable(false, fields_non_null);
1356 assert_eq!(row_type_non_null.to_string(), "ROW<age BIGINT> NOT NULL");
1357}
1358
1359#[test]
1360fn test_datatype_display() {
1361 assert_eq!(DataTypes::boolean().to_string(), "BOOLEAN");
1362 assert_eq!(DataTypes::int().to_string(), "INT");
1363 assert_eq!(DataTypes::string().to_string(), "STRING");
1364 assert_eq!(DataTypes::char(50).to_string(), "CHAR(50)");
1365 assert_eq!(DataTypes::decimal(10, 2).to_string(), "DECIMAL(10, 2)");
1366 assert_eq!(DataTypes::time_with_precision(3).to_string(), "TIME(3)");
1367 assert_eq!(
1368 DataTypes::timestamp_with_precision(6).to_string(),
1369 "TIMESTAMP(6)"
1370 );
1371 assert_eq!(
1372 DataTypes::timestamp_ltz_with_precision(9).to_string(),
1373 "TIMESTAMP_LTZ(9)"
1374 );
1375 assert_eq!(DataTypes::array(DataTypes::int()).to_string(), "ARRAY<INT>");
1376 assert_eq!(
1377 DataTypes::map(DataTypes::string(), DataTypes::int()).to_string(),
1378 "MAP<STRING, INT>"
1379 );
1380}
1381
1382#[test]
1383fn test_datafield_display() {
1384 let field = DataTypes::field("user_id", DataTypes::bigint());
1385 assert_eq!(field.to_string(), "user_id BIGINT");
1386
1387 let field2 = DataTypes::field("email", DataTypes::string());
1388 assert_eq!(field2.to_string(), "email STRING");
1389
1390 let field3 = DataTypes::field("score", DataTypes::decimal(10, 2));
1391 assert_eq!(field3.to_string(), "score DECIMAL(10, 2)");
1392}
1393
1394#[test]
1395fn test_complex_nested_display() {
1396 let row_type = DataTypes::row(vec![
1397 DataTypes::field("id", DataTypes::int()),
1398 DataTypes::field("tags", DataTypes::array(DataTypes::string())),
1399 DataTypes::field(
1400 "metadata",
1401 DataTypes::map(DataTypes::string(), DataTypes::string()),
1402 ),
1403 ]);
1404 assert_eq!(
1405 row_type.to_string(),
1406 "ROW<id INT, tags ARRAY<STRING>, metadata MAP<STRING, STRING>>"
1407 );
1408}
1409
1410#[test]
1411fn test_non_nullable_datatype() {
1412 let nullable_int = DataTypes::int();
1413 assert_eq!(nullable_int.to_string(), "INT");
1414
1415 let non_nullable_int = nullable_int.as_non_nullable();
1416 assert_eq!(non_nullable_int.to_string(), "INT NOT NULL");
1417}
1418
1419#[test]
1420fn test_deeply_nested_types() {
1421 let nested = DataTypes::array(DataTypes::map(
1422 DataTypes::string(),
1423 DataTypes::row(vec![
1424 DataTypes::field("x", DataTypes::int()),
1425 DataTypes::field("y", DataTypes::int()),
1426 ]),
1427 ));
1428 assert_eq!(nested.to_string(), "ARRAY<MAP<STRING, ROW<x INT, y INT>>>");
1429}
1430
1431#[test]
1436fn test_decimal_invalid_precision() {
1437 let result = DecimalType::with_nullable(true, 50, 2);
1439 assert!(result.is_err());
1440 assert!(
1441 result
1442 .unwrap_err()
1443 .to_string()
1444 .contains("Decimal precision must be between 1 and 38")
1445 );
1446}
1447
1448#[test]
1449fn test_decimal_invalid_scale() {
1450 let result = DecimalType::with_nullable(true, 10, 15);
1452 assert!(result.is_err());
1453 assert!(
1454 result
1455 .unwrap_err()
1456 .to_string()
1457 .contains("Decimal scale must be between 0 and the precision 10")
1458 );
1459}
1460
1461#[test]
1466fn test_decimal_valid_precision_and_scale() {
1467 let result = DecimalType::with_nullable(true, 10, 2);
1469 assert!(result.is_ok());
1470 let decimal = result.unwrap();
1471 assert_eq!(decimal.precision(), 10);
1472 assert_eq!(decimal.scale(), 2);
1473 assert!(!decimal.to_string().contains("NOT NULL"));
1475
1476 let result = DecimalType::with_nullable(true, 38, 0);
1478 assert!(result.is_ok());
1479 let decimal = result.unwrap();
1480 assert_eq!(decimal.precision(), 38);
1481 assert_eq!(decimal.scale(), 0);
1482
1483 let result = DecimalType::with_nullable(false, 1, 0);
1485 assert!(result.is_ok());
1486 let decimal = result.unwrap();
1487 assert_eq!(decimal.precision(), 1);
1488 assert_eq!(decimal.scale(), 0);
1489 assert!(decimal.to_string().contains("NOT NULL"));
1491}
1492
1493#[test]
1494fn test_decimal_invalid_precision_zero() {
1495 let result = DecimalType::with_nullable(true, 0, 0);
1497 assert!(result.is_err());
1498 assert!(
1499 result
1500 .unwrap_err()
1501 .to_string()
1502 .contains("Decimal precision must be between 1 and 38")
1503 );
1504}
1505
1506#[test]
1507fn test_decimal_scale_equals_precision_boundary() {
1508 let result = DecimalType::with_nullable(true, 10, 10);
1510 assert!(result.is_ok());
1511 let decimal = result.unwrap();
1512 assert_eq!(decimal.precision(), 10);
1513 assert_eq!(decimal.scale(), 10);
1514}
1515
1516#[test]
1521fn test_time_valid_precision() {
1522 for precision in 0..=9 {
1524 let result = TimeType::with_nullable(true, precision);
1525 assert!(result.is_ok(), "precision {precision} should be valid");
1526 let time = result.unwrap();
1527 assert_eq!(time.precision(), precision);
1528 }
1529}
1530
1531#[test]
1532fn test_time_invalid_precision() {
1533 let result = TimeType::with_nullable(true, 10);
1535 assert!(result.is_err());
1536 assert!(
1537 result
1538 .unwrap_err()
1539 .to_string()
1540 .contains("Time precision must be between 0 and 9")
1541 );
1542}
1543
1544#[test]
1549fn test_timestamp_valid_precision() {
1550 for precision in 0..=9 {
1552 let result = TimestampType::with_nullable(true, precision);
1553 assert!(result.is_ok(), "precision {precision} should be valid");
1554 let timestamp_type = result.unwrap();
1555 assert_eq!(timestamp_type.precision(), precision);
1556 }
1557}
1558
1559#[test]
1560fn test_timestamp_invalid_precision() {
1561 let result = TimestampType::with_nullable(true, 10);
1563 assert!(result.is_err());
1564 assert!(
1565 result
1566 .unwrap_err()
1567 .to_string()
1568 .contains("Timestamp precision must be between 0 and 9")
1569 );
1570}
1571
1572#[test]
1573fn test_timestamp_ltz_invalid_precision() {
1574 let result = TimestampLTzType::with_nullable(true, 10);
1576 assert!(result.is_err());
1577 assert!(
1578 result
1579 .unwrap_err()
1580 .to_string()
1581 .contains("Timestamp with local time zone precision must be between 0 and 9")
1582 );
1583}
1584
1585#[test]
1590fn test_row_type_project_valid_indices() {
1591 let row_type = RowType::with_data_types_and_field_names(
1593 vec![DataTypes::int(), DataTypes::string(), DataTypes::bigint()],
1594 vec!["id", "name", "age"],
1595 );
1596
1597 let projected = row_type.project(&[0, 2]).unwrap();
1599 assert_eq!(projected.fields().len(), 2);
1600 assert_eq!(projected.fields()[0].name, "id");
1601 assert_eq!(projected.fields()[1].name, "age");
1602}
1603
1604#[test]
1605fn test_row_type_project_empty_indices() {
1606 let row_type = RowType::with_data_types_and_field_names(
1608 vec![DataTypes::int(), DataTypes::string(), DataTypes::bigint()],
1609 vec!["id", "name", "age"],
1610 );
1611
1612 let projected = row_type.project(&[]).unwrap();
1614 assert_eq!(projected.fields().len(), 0);
1615}
1616
1617#[test]
1618fn test_row_type_project_with_field_names_valid() {
1619 let row_type = RowType::with_data_types_and_field_names(
1621 vec![DataTypes::int(), DataTypes::string(), DataTypes::bigint()],
1622 vec!["id", "name", "age"],
1623 );
1624
1625 let projected = row_type
1627 .project_with_field_names(&["id".to_string(), "name".to_string()])
1628 .unwrap();
1629 assert_eq!(projected.fields().len(), 2);
1630 assert_eq!(projected.fields()[0].name, "id");
1631 assert_eq!(projected.fields()[1].name, "name");
1632}
1633
1634#[test]
1635fn test_row_type_project_index_out_of_bounds() {
1636 let row_type = RowType::with_data_types_and_field_names(
1638 vec![DataTypes::int(), DataTypes::string(), DataTypes::bigint()],
1639 vec!["id", "name", "age"],
1640 );
1641
1642 let result = row_type.project(&[0, 5]);
1644 assert!(result.is_err());
1645 assert!(
1646 result
1647 .unwrap_err()
1648 .to_string()
1649 .contains("invalid field position: 5")
1650 );
1651}
1652
1653#[test]
1654fn test_row_type_project_with_field_names_nonexistent() {
1655 let row_type = RowType::with_data_types_and_field_names(
1657 vec![DataTypes::int(), DataTypes::string(), DataTypes::bigint()],
1658 vec!["id", "name", "age"],
1659 );
1660
1661 let result = row_type.project_with_field_names(&["nonexistent".to_string()]);
1663 assert!(result.is_err());
1664 assert!(
1665 result
1666 .unwrap_err()
1667 .to_string()
1668 .contains("Field 'nonexistent' does not exist in the row type")
1669 );
1670
1671 let result = row_type.project_with_field_names(&["id".to_string(), "nonexistent".to_string()]);
1673 assert!(result.is_err());
1674 assert!(
1675 result
1676 .unwrap_err()
1677 .to_string()
1678 .contains("Field 'nonexistent' does not exist in the row type")
1679 );
1680}
1681
1682#[test]
1683fn test_row_type_project_duplicate_indices() {
1684 let row_type = RowType::with_data_types_and_field_names(
1686 vec![DataTypes::int(), DataTypes::string(), DataTypes::bigint()],
1687 vec!["id", "name", "age"],
1688 );
1689
1690 let projected = row_type.project(&[0, 0, 1]).unwrap();
1693 assert_eq!(projected.fields().len(), 3);
1694 assert_eq!(projected.fields()[0].name, "id");
1695 assert_eq!(projected.fields()[1].name, "id");
1696 assert_eq!(projected.fields()[2].name, "name");
1697}