1use std::fmt;
29use std::ops::Index;
30
31use super::error::{Error, Result};
32use super::schema::Schema;
33use super::types::DataType;
34use super::value::Value;
35use crate::common::{CompactArc, CompactVec};
36
37#[derive(Debug, Clone)]
44enum RowStorage {
45 Shared(CompactArc<[Value]>),
47 Owned(CompactVec<Value>),
49}
50
51impl Default for RowStorage {
52 fn default() -> Self {
53 RowStorage::Owned(CompactVec::new())
54 }
55}
56
57impl PartialEq for RowStorage {
58 #[inline]
59 fn eq(&self, other: &Self) -> bool {
60 match (self, other) {
61 (RowStorage::Shared(a), RowStorage::Shared(b)) => {
62 CompactArc::ptr_eq(a, b) || a.as_ref() == b.as_ref()
64 }
65 (RowStorage::Owned(a), RowStorage::Owned(b)) => a.as_slice() == b.as_slice(),
66 (RowStorage::Shared(a), RowStorage::Owned(b)) => a.as_ref() == b.as_slice(),
68 (RowStorage::Owned(a), RowStorage::Shared(b)) => a.as_slice() == b.as_ref(),
69 }
70 }
71}
72
73impl RowStorage {
74 #[inline(always)]
76 fn get(&self, index: usize) -> Option<&Value> {
77 match self {
78 RowStorage::Shared(arc) => arc.get(index),
79 RowStorage::Owned(vec) => vec.get(index),
80 }
81 }
82
83 #[inline(always)]
84 fn len(&self) -> usize {
85 match self {
86 RowStorage::Shared(arc) => arc.len(),
87 RowStorage::Owned(vec) => vec.len(),
88 }
89 }
90
91 #[inline]
92 fn is_empty(&self) -> bool {
93 self.len() == 0
94 }
95
96 #[inline]
98 fn make_mut(&mut self) -> &mut CompactVec<Value> {
99 match self {
100 RowStorage::Owned(vec) => vec,
101 RowStorage::Shared(arc) => {
102 let len = arc.len();
106 let mut vec = CompactVec::with_capacity(len);
107 vec.extend_clone(arc);
108 *self = RowStorage::Owned(vec);
109 match self {
110 RowStorage::Owned(vec) => vec,
111 _ => unreachable!(),
112 }
113 }
114 }
115 }
116
117 #[inline]
119 fn into_vec(self) -> Vec<Value> {
120 match self {
121 RowStorage::Owned(vec) => vec.into_vec(),
122 RowStorage::Shared(arc) => arc.iter().cloned().collect(),
123 }
124 }
125}
126
127#[derive(Debug, Clone, PartialEq, Default)]
138pub struct Row {
139 storage: RowStorage,
140}
141
142pub struct RowIter<'a> {
144 inner: std::slice::Iter<'a, Value>,
145}
146
147impl<'a> Iterator for RowIter<'a> {
148 type Item = &'a Value;
149
150 #[inline]
151 fn next(&mut self) -> Option<Self::Item> {
152 self.inner.next()
153 }
154
155 #[inline]
156 fn size_hint(&self) -> (usize, Option<usize>) {
157 self.inner.size_hint()
158 }
159}
160
161impl<'a> ExactSizeIterator for RowIter<'a> {
162 fn len(&self) -> usize {
163 self.inner.len()
164 }
165}
166
167impl<'a> DoubleEndedIterator for RowIter<'a> {
168 fn next_back(&mut self) -> Option<Self::Item> {
169 self.inner.next_back()
170 }
171}
172
173pub struct RowIterMut<'a> {
175 inner: std::slice::IterMut<'a, Value>,
176}
177
178impl<'a> Iterator for RowIterMut<'a> {
179 type Item = &'a mut Value;
180
181 #[inline]
182 fn next(&mut self) -> Option<Self::Item> {
183 self.inner.next()
184 }
185
186 #[inline]
187 fn size_hint(&self) -> (usize, Option<usize>) {
188 self.inner.size_hint()
189 }
190}
191
192impl<'a> ExactSizeIterator for RowIterMut<'a> {
193 fn len(&self) -> usize {
194 self.inner.len()
195 }
196}
197
198impl Row {
199 #[inline]
201 pub fn new() -> Self {
202 Self {
203 storage: RowStorage::Owned(CompactVec::new()),
204 }
205 }
206
207 #[inline]
209 pub fn with_capacity(capacity: usize) -> Self {
210 Self {
211 storage: RowStorage::Owned(CompactVec::with_capacity(capacity)),
212 }
213 }
214
215 #[inline]
217 pub fn from_values(values: Vec<Value>) -> Self {
218 Self {
219 storage: RowStorage::Owned(CompactVec::from_vec(values)),
220 }
221 }
222
223 #[inline]
225 pub fn from_compact_vec(values: CompactVec<Value>) -> Self {
226 Self {
227 storage: RowStorage::Owned(values),
228 }
229 }
230
231 #[inline]
233 pub fn from_arc(values: CompactArc<[Value]>) -> Self {
234 Self {
235 storage: RowStorage::Shared(values),
236 }
237 }
238
239 #[inline]
242 pub fn from_combined(left: &Row, right: &Row) -> Self {
243 let total_len = left.len() + right.len();
244 let mut values = CompactVec::with_capacity(total_len);
245 values.extend_clone(left.as_slice());
247 values.extend_clone(right.as_slice());
248 Self {
249 storage: RowStorage::Owned(values),
250 }
251 }
252
253 #[inline]
255 pub fn combine_into(&mut self, left: &Row, right: &Row) {
256 let total_len = left.len() + right.len();
257 let vec = self.storage.make_mut();
258 vec.clear();
259 vec.reserve(total_len);
260 vec.extend_clone(left.as_slice());
262 vec.extend_clone(right.as_slice());
263 }
264
265 #[inline]
267 pub fn combine_into_clone_move(&mut self, left: &Row, right: Row) {
268 let total_len = left.len() + right.len();
269 let vec = self.storage.make_mut();
270 vec.clear();
271 vec.reserve(total_len);
272 vec.extend_clone(left.as_slice());
274 match right.storage {
276 RowStorage::Owned(right_vec) => vec.extend(right_vec),
277 RowStorage::Shared(arc) => vec.extend_clone(&arc),
278 }
279 }
280
281 #[inline]
283 pub fn combine_into_owned(&mut self, left: Row, right: Row) {
284 let total_len = left.len() + right.len();
285 let vec = self.storage.make_mut();
286 vec.clear();
287 vec.reserve(total_len);
288 match left.storage {
290 RowStorage::Owned(left_vec) => vec.extend(left_vec),
291 RowStorage::Shared(arc) => vec.extend_clone(&arc),
292 }
293 match right.storage {
295 RowStorage::Owned(right_vec) => vec.extend(right_vec),
296 RowStorage::Shared(arc) => vec.extend_clone(&arc),
297 }
298 }
299
300 #[inline]
302 pub fn from_combined_clone_move(left: &Row, right: Row) -> Self {
303 let total_len = left.len() + right.len();
304 let mut values = CompactVec::with_capacity(total_len);
305 values.extend_clone(left.as_slice());
307 match right.storage {
308 RowStorage::Owned(right_vec) => values.extend(right_vec),
309 RowStorage::Shared(arc) => values.extend_clone(&arc),
310 }
311 Self {
312 storage: RowStorage::Owned(values),
313 }
314 }
315
316 #[inline]
318 pub fn from_combined_owned(left: Row, right: Row) -> Self {
319 match (left.storage, right.storage) {
321 (RowStorage::Owned(mut left_vec), RowStorage::Owned(right_vec)) => {
322 left_vec.reserve(right_vec.len());
323 left_vec.extend(right_vec);
324 Self {
325 storage: RowStorage::Owned(left_vec),
326 }
327 }
328 (left_storage, right_storage) => {
329 let left_len = left_storage.len();
330 let right_len = right_storage.len();
331 let mut values = CompactVec::with_capacity(left_len + right_len);
332 match left_storage {
334 RowStorage::Owned(v) => values.extend(v),
335 RowStorage::Shared(a) => values.extend_clone(&a),
336 }
337 match right_storage {
338 RowStorage::Owned(v) => values.extend(v),
339 RowStorage::Shared(a) => values.extend_clone(&a),
340 }
341 Self {
342 storage: RowStorage::Owned(values),
343 }
344 }
345 }
346 }
347
348 #[inline]
350 pub fn null_row(schema: &Schema) -> Self {
351 let values: CompactVec<Value> = schema
352 .columns
353 .iter()
354 .map(|col| Value::null(col.data_type))
355 .collect();
356 Self {
357 storage: RowStorage::Owned(values),
358 }
359 }
360
361 #[inline(always)]
363 pub fn len(&self) -> usize {
364 self.storage.len()
365 }
366
367 #[inline]
369 pub fn is_empty(&self) -> bool {
370 self.storage.is_empty()
371 }
372
373 #[inline(always)]
375 pub fn get(&self, index: usize) -> Option<&Value> {
376 self.storage.get(index)
377 }
378
379 #[inline]
381 pub fn get_mut(&mut self, index: usize) -> Option<&mut Value> {
382 self.storage.make_mut().get_mut(index)
383 }
384
385 pub fn set(&mut self, index: usize, value: Value) -> Result<()> {
387 let vec = self.storage.make_mut();
388 if index >= vec.len() {
389 return Err(Error::Internal {
390 message: format!("row index {} out of bounds (len={})", index, vec.len()),
391 });
392 }
393 vec[index] = value;
394 Ok(())
395 }
396
397 #[inline]
399 pub fn push(&mut self, value: Value) {
400 self.storage.make_mut().push(value);
401 }
402
403 #[inline]
405 pub fn pop(&mut self) -> Option<Value> {
406 self.storage.make_mut().pop()
407 }
408
409 #[inline]
411 pub fn truncate(&mut self, len: usize) {
412 self.storage.make_mut().truncate(len);
413 }
414
415 #[inline]
417 pub fn clear(&mut self) {
418 self.storage.make_mut().clear();
419 }
420
421 #[inline]
424 pub fn take_and_clear(&mut self) -> Row {
425 match &mut self.storage {
426 RowStorage::Owned(vec) => {
427 let cap = vec.capacity();
428 let values = std::mem::replace(vec, CompactVec::with_capacity(cap));
429 Row {
430 storage: RowStorage::Owned(values),
431 }
432 }
433 RowStorage::Shared(arc) => {
434 let result = Row {
435 storage: RowStorage::Shared(arc.clone()),
436 };
437 *self = Row::new();
438 result
439 }
440 }
441 }
442
443 #[inline]
445 pub fn reserve(&mut self, additional: usize) {
446 self.storage.make_mut().reserve(additional);
447 }
448
449 #[inline]
451 pub fn extend_from_slice(&mut self, other: &[Value]) {
452 self.storage.make_mut().extend_clone(other);
453 }
454
455 #[inline]
462 pub fn extend_into_compact_vec(self, target: &mut CompactVec<Value>) {
463 match self.storage {
464 RowStorage::Owned(vec) => target.extend(vec),
465 RowStorage::Shared(arc) => target.extend_clone(&arc),
466 }
467 }
468
469 #[inline(always)]
471 pub fn iter(&self) -> RowIter<'_> {
472 RowIter {
473 inner: match &self.storage {
474 RowStorage::Shared(arc) => arc.iter(),
475 RowStorage::Owned(vec) => vec.iter(),
476 },
477 }
478 }
479
480 #[inline]
482 pub fn iter_mut(&mut self) -> RowIterMut<'_> {
483 RowIterMut {
484 inner: self.storage.make_mut().iter_mut(),
485 }
486 }
487
488 #[inline]
490 pub fn into_values(self) -> Vec<Value> {
491 self.storage.into_vec()
492 }
493
494 #[inline]
496 pub fn take_first_value(self) -> Option<Value> {
497 match self.storage {
498 RowStorage::Owned(mut vec) => {
499 if vec.is_empty() {
500 None
501 } else {
502 Some(vec.swap_remove(0))
503 }
504 }
505 RowStorage::Shared(arc) => arc.first().cloned(),
506 }
507 }
508
509 #[inline]
511 pub fn is_shared(&self) -> bool {
512 matches!(self.storage, RowStorage::Shared(_))
513 }
514
515 #[inline]
517 pub fn is_owned(&self) -> bool {
518 matches!(self.storage, RowStorage::Owned(_))
519 }
520
521 #[inline]
525 pub fn into_arc(self) -> CompactArc<[Value]> {
526 match self.storage {
527 RowStorage::Shared(arc) => arc,
528 RowStorage::Owned(vec) => CompactArc::from_compact_vec(vec),
530 }
531 }
532
533 #[inline]
538 pub fn into_shared(self) -> Self {
539 match self.storage {
540 RowStorage::Shared(_) => self, RowStorage::Owned(vec) => Self {
542 storage: RowStorage::Shared(CompactArc::from_compact_vec(vec)),
544 },
545 }
546 }
547
548 #[inline]
550 pub fn as_arc(&self) -> Option<&CompactArc<[Value]>> {
551 match &self.storage {
552 RowStorage::Shared(arc) => Some(arc),
553 RowStorage::Owned(_) => None,
554 }
555 }
556
557 #[inline]
559 pub fn as_slice(&self) -> &[Value] {
560 match &self.storage {
561 RowStorage::Shared(arc) => arc,
562 RowStorage::Owned(vec) => vec.as_slice(),
563 }
564 }
565
566 #[inline]
568 pub fn select_columns(&self, indices: &[usize]) -> Result<Row> {
569 let len = self.len();
570 let mut values = CompactVec::with_capacity(indices.len());
571 for &idx in indices {
572 match self.storage.get(idx) {
573 Some(val) => values.push(val.clone()),
574 None => {
575 return Err(Error::Internal {
576 message: format!("column index {} out of bounds (len={})", idx, len),
577 })
578 }
579 }
580 }
581 Ok(Row::from_compact_vec(values))
582 }
583
584 #[inline]
587 pub fn take_columns(self, indices: &[usize]) -> Row {
588 let is_prefix = !indices.is_empty()
590 && indices.len() <= self.len()
591 && indices.iter().enumerate().all(|(i, &idx)| i == idx);
592
593 if is_prefix {
594 match self.storage {
595 RowStorage::Owned(mut vec) => {
596 vec.truncate(indices.len());
597 return Row {
598 storage: RowStorage::Owned(vec),
599 };
600 }
601 RowStorage::Shared(ref arc) if indices.len() == arc.len() => {
602 return self;
603 }
604 RowStorage::Shared(arc) => {
605 let values: CompactVec<Value> = arc[..indices.len()].iter().cloned().collect();
607 return Row {
608 storage: RowStorage::Owned(values),
609 };
610 }
611 }
612 }
613
614 let mut values = CompactVec::with_capacity(indices.len());
616 let slice = self.as_slice();
617 for &idx in indices {
618 if idx < slice.len() {
619 values.push(slice[idx].clone());
620 } else {
621 values.push(Value::null_unknown());
622 }
623 }
624 Row {
625 storage: RowStorage::Owned(values),
626 }
627 }
628
629 pub fn validate(&self, schema: &Schema) -> Result<()> {
631 let len = self.len();
632
633 if len != schema.columns.len() {
635 return Err(Error::table_columns_not_match(schema.columns.len(), len));
636 }
637
638 for (i, (value, col)) in self.iter().zip(schema.columns.iter()).enumerate() {
640 if value.is_null() && !col.nullable && !col.primary_key {
642 return Err(Error::not_null_constraint(&col.name));
643 }
644
645 if !value.is_null() {
647 let value_type = value.data_type();
648 if value_type != col.data_type {
649 let compatible = matches!(
651 (value_type, col.data_type),
652 (DataType::Integer, DataType::Float) | (DataType::Float, DataType::Integer)
653 );
654 if !compatible {
655 return Err(Error::type_conversion(
656 format!("column {} at index {}: {:?}", col.name, i, value_type),
657 format!("{:?}", col.data_type),
658 ));
659 }
660 }
661 }
662 }
663
664 Ok(())
665 }
666
667 #[inline]
669 pub fn clone_subset(&self, indices: &[usize]) -> Row {
670 let mut values = CompactVec::with_capacity(indices.len());
671 let slice = self.as_slice();
672 for &i in indices {
673 if let Some(v) = slice.get(i) {
674 values.push(v.clone());
675 }
676 }
677 Row::from_compact_vec(values)
678 }
679
680 pub fn concat(&self, other: &Row) -> Row {
682 let total_len = self.len() + other.len();
683 let mut values = CompactVec::with_capacity(total_len);
684 values.extend(self.iter().cloned());
685 values.extend(other.iter().cloned());
686 Row::from_compact_vec(values)
687 }
688
689 pub fn repeat(value: Value, count: usize) -> Row {
691 let mut values = CompactVec::with_capacity(count);
692 for _ in 0..count {
693 values.push(value.clone());
694 }
695 Row::from_compact_vec(values)
696 }
697
698 #[inline]
703 pub fn is_inline(&self) -> bool {
704 self.is_owned()
705 }
706
707 #[inline]
709 pub fn clear_inline(&mut self) {
710 self.clear();
711 }
712
713 #[inline]
715 pub fn push_inline(&mut self, value: Value) {
716 self.push(value);
717 }
718
719 #[inline]
721 pub fn reserve_inline(&mut self, capacity: usize) {
722 let vec = self.storage.make_mut();
723 if vec.capacity() < capacity {
724 vec.reserve(capacity - vec.len());
725 }
726 }
727
728 #[inline]
730 pub fn refill_inline<I: Iterator<Item = Value>>(&mut self, values: I) {
731 let vec = self.storage.make_mut();
732 vec.clear();
733 vec.extend(values);
734 }
735}
736
737impl Index<usize> for Row {
739 type Output = Value;
740
741 #[inline]
742 fn index(&self, index: usize) -> &Self::Output {
743 self.storage.get(index).expect("row index out of bounds")
744 }
745}
746
747impl FromIterator<Value> for Row {
749 fn from_iter<I: IntoIterator<Item = Value>>(iter: I) -> Self {
750 Row::from_compact_vec(iter.into_iter().collect())
751 }
752}
753
754impl IntoIterator for Row {
756 type Item = Value;
757 type IntoIter = std::vec::IntoIter<Value>;
758
759 fn into_iter(self) -> Self::IntoIter {
760 self.storage.into_vec().into_iter()
761 }
762}
763
764impl<'a> IntoIterator for &'a Row {
765 type Item = &'a Value;
766 type IntoIter = RowIter<'a>;
767
768 fn into_iter(self) -> Self::IntoIter {
769 self.iter()
770 }
771}
772
773impl From<Vec<Value>> for Row {
774 fn from(values: Vec<Value>) -> Self {
775 Row::from_values(values)
776 }
777}
778
779impl From<CompactArc<[Value]>> for Row {
780 fn from(values: CompactArc<[Value]>) -> Self {
781 Row::from_arc(values)
782 }
783}
784
785impl fmt::Display for Row {
786 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
787 write!(f, "(")?;
788 for (i, value) in self.iter().enumerate() {
789 if i > 0 {
790 write!(f, ", ")?;
791 }
792 write!(f, "{}", value)?;
793 }
794 write!(f, ")")
795 }
796}
797
798#[macro_export]
800macro_rules! row {
801 () => {
802 $crate::core::Row::new()
803 };
804 ($($value:expr),+ $(,)?) => {
805 $crate::core::Row::from_values(vec![$($crate::core::Value::from($value)),+])
806 };
807}
808
809#[cfg(test)]
810mod tests {
811 use super::*;
812 use crate::common::CompactArc;
813 use crate::core::schema::SchemaBuilder;
814
815 fn create_test_schema() -> Schema {
816 SchemaBuilder::new("test")
817 .add_primary_key("id", DataType::Integer)
818 .add("name", DataType::Text)
819 .add_nullable("email", DataType::Text)
820 .build()
821 }
822
823 #[test]
824 fn test_row_creation() {
825 let row = Row::new();
826 assert!(row.is_empty());
827 assert_eq!(row.len(), 0);
828
829 let row = Row::with_capacity(10);
830 assert!(row.is_empty());
831 }
832
833 #[test]
834 fn test_row_from_values() {
835 let values = vec![
836 Value::integer(1),
837 Value::text("hello"),
838 Value::null(DataType::Text),
839 ];
840 let row = Row::from_values(values);
841 assert_eq!(row.len(), 3);
842 assert!(row.is_owned());
843 }
844
845 #[test]
846 fn test_row_from_arc() {
847 let values: CompactArc<[Value]> =
848 CompactArc::from(vec![Value::integer(1), Value::text("hello")]);
849 let row = Row::from_arc(values);
850 assert_eq!(row.len(), 2);
851 assert!(row.is_shared());
852
853 let row2 = row.clone();
855 assert_eq!(row2.len(), 2);
856 assert_eq!(row, row2);
857 assert!(row2.is_shared());
858 }
859
860 #[test]
861 fn test_row_push_pop() {
862 let mut row = Row::new();
863 row.push(Value::integer(1));
864 row.push(Value::text("hello"));
865
866 assert_eq!(row.len(), 2);
867
868 let popped = row.pop();
869 assert_eq!(popped, Some(Value::text("hello")));
870 assert_eq!(row.len(), 1);
871 }
872
873 #[test]
874 fn test_row_copy_on_write() {
875 let values: CompactArc<[Value]> =
877 CompactArc::from(vec![Value::integer(1), Value::text("hello")]);
878 let mut row = Row::from_arc(values);
879 assert!(row.is_shared());
880
881 row.push(Value::integer(2));
883 assert_eq!(row.len(), 3);
884 assert!(row.is_owned()); }
886
887 #[test]
888 fn test_row_get_set() {
889 let mut row = Row::from_values(vec![Value::integer(1), Value::text("hello")]);
890
891 assert_eq!(row.get(0), Some(&Value::integer(1)));
892 assert_eq!(row.get(1), Some(&Value::text("hello")));
893 assert_eq!(row.get(2), None);
894
895 row.set(1, Value::text("world")).unwrap();
896 assert_eq!(row.get(1), Some(&Value::text("world")));
897
898 assert!(row.set(10, Value::integer(0)).is_err());
899 }
900
901 #[test]
902 fn test_row_index() {
903 let row = Row::from_values(vec![Value::integer(1), Value::text("hello")]);
904
905 assert_eq!(row[0], Value::integer(1));
906 assert_eq!(row[1], Value::text("hello"));
907 }
908
909 #[test]
910 fn test_row_iteration() {
911 let row = Row::from_values(vec![
912 Value::integer(1),
913 Value::integer(2),
914 Value::integer(3),
915 ]);
916
917 let sum: i64 = row.iter().filter_map(|v| v.as_int64()).sum();
918 assert_eq!(sum, 6);
919 }
920
921 #[test]
922 fn test_row_select_columns() {
923 let row = Row::from_values(vec![
924 Value::integer(1),
925 Value::text("hello"),
926 Value::float(3.5),
927 Value::boolean(true),
928 ]);
929
930 let selected = row.select_columns(&[0, 2]).unwrap();
931 assert_eq!(selected.len(), 2);
932 assert_eq!(selected[0], Value::integer(1));
933 assert_eq!(selected[1], Value::float(3.5));
934
935 assert!(row.select_columns(&[0, 10]).is_err());
936 }
937
938 #[test]
939 fn test_row_validate() {
940 let schema = create_test_schema();
941
942 let row = Row::from_values(vec![
944 Value::integer(1),
945 Value::text("Alice"),
946 Value::null(DataType::Text),
947 ]);
948 assert!(row.validate(&schema).is_ok());
949
950 let row = Row::from_values(vec![Value::integer(1)]);
952 assert!(row.validate(&schema).is_err());
953
954 let row = Row::from_values(vec![
956 Value::integer(1),
957 Value::null(DataType::Text), Value::null(DataType::Text),
959 ]);
960 let err = row.validate(&schema).unwrap_err();
961 assert!(matches!(err, Error::NotNullConstraint { .. }));
962 }
963
964 #[test]
965 fn test_row_null_row() {
966 let schema = create_test_schema();
967 let row = Row::null_row(&schema);
968
969 assert_eq!(row.len(), 3);
970 assert!(row[0].is_null());
971 assert!(row[1].is_null());
972 assert!(row[2].is_null());
973 }
974
975 #[test]
976 fn test_row_concat() {
977 let row1 = Row::from_values(vec![Value::integer(1), Value::integer(2)]);
978 let row2 = Row::from_values(vec![Value::integer(3), Value::integer(4)]);
979
980 let combined = row1.concat(&row2);
981 assert_eq!(combined.len(), 4);
982 assert_eq!(combined[0], Value::integer(1));
983 assert_eq!(combined[3], Value::integer(4));
984 }
985
986 #[test]
987 fn test_row_repeat() {
988 let row = Row::repeat(Value::integer(0), 5);
989 assert_eq!(row.len(), 5);
990 for v in row.iter() {
991 assert_eq!(*v, Value::integer(0));
992 }
993 }
994
995 #[test]
996 fn test_row_from_iterator() {
997 let row: Row = vec![Value::integer(1), Value::integer(2), Value::integer(3)]
998 .into_iter()
999 .collect();
1000 assert_eq!(row.len(), 3);
1001 }
1002
1003 #[test]
1004 fn test_row_display() {
1005 let row = Row::from_values(vec![
1006 Value::integer(1),
1007 Value::text("hello"),
1008 Value::null(DataType::Text),
1009 ]);
1010 assert_eq!(row.to_string(), "(1, hello, NULL)");
1011
1012 let empty = Row::new();
1013 assert_eq!(empty.to_string(), "()");
1014 }
1015
1016 #[test]
1017 fn test_row_clone_subset() {
1018 let row = Row::from_values(vec![
1019 Value::integer(1),
1020 Value::text("hello"),
1021 Value::float(3.5),
1022 ]);
1023
1024 let subset = row.clone_subset(&[2, 0]);
1025 assert_eq!(subset.len(), 2);
1026 assert_eq!(subset[0], Value::float(3.5));
1027 assert_eq!(subset[1], Value::integer(1));
1028 }
1029
1030 #[test]
1031 fn test_row_equality() {
1032 let row1 = Row::from_values(vec![Value::integer(1), Value::text("hello")]);
1033 let row2 = Row::from_values(vec![Value::integer(1), Value::text("hello")]);
1034 let row3 = Row::from_values(vec![Value::integer(1), Value::text("world")]);
1035
1036 assert_eq!(row1, row2);
1037 assert_ne!(row1, row3);
1038 }
1039
1040 #[test]
1041 fn test_row_into_values() {
1042 let row = Row::from_values(vec![Value::integer(1), Value::text("hello")]);
1043 let values = row.into_values();
1044
1045 assert_eq!(values.len(), 2);
1046 assert_eq!(values[0], Value::integer(1));
1047 }
1048
1049 #[test]
1050 fn test_row_into_arc() {
1051 let row = Row::from_values(vec![Value::integer(1), Value::text("hello")]);
1052 let arc = row.into_arc();
1053 assert_eq!(arc.len(), 2);
1054
1055 let row2 = Row::from_arc(CompactArc::clone(&arc));
1057 let arc2 = row2.into_arc();
1058 assert!(CompactArc::ptr_eq(&arc, &arc2));
1059 }
1060
1061 #[test]
1062 fn test_row_combined() {
1063 let left = Row::from_values(vec![Value::integer(1), Value::integer(2)]);
1064 let right = Row::from_values(vec![Value::integer(3), Value::integer(4)]);
1065
1066 let combined = Row::from_combined(&left, &right);
1067 assert_eq!(combined.len(), 4);
1068 assert_eq!(combined[0], Value::integer(1));
1069 assert_eq!(combined[3], Value::integer(4));
1070 }
1071
1072 #[test]
1073 fn test_shared_owned_equality() {
1074 let owned = Row::from_values(vec![Value::integer(1), Value::text("hello")]);
1075 let shared = Row::from_arc(CompactArc::from(vec![
1076 Value::integer(1),
1077 Value::text("hello"),
1078 ]));
1079
1080 assert_eq!(owned, shared);
1081 }
1082}