1use reifydb_type::value::{
5 Value,
6 identity::IdentityId,
7 ordered_f32::OrderedF32,
8 ordered_f64::OrderedF64,
9 r#type::Type,
10 uuid::{Uuid4, Uuid7},
11};
12
13use super::schema::Schema;
14use crate::encoded::encoded::EncodedValues;
15
16impl Schema {
17 pub fn set_values(&self, row: &mut EncodedValues, values: &[Value]) {
18 debug_assert!(values.len() == self.fields().len());
19 for (idx, value) in values.iter().enumerate() {
20 self.set_value(row, idx, value)
21 }
22 }
23
24 pub fn set_value(&self, row: &mut EncodedValues, index: usize, val: &Value) {
25 let field = &self.fields()[index];
26 debug_assert!(row.len() >= self.total_static_size());
27
28 let field_type = match field.constraint.get_type() {
29 Type::Option(inner) => *inner,
30 other => other,
31 };
32
33 match (field_type, val) {
34 (Type::Boolean, Value::Boolean(v)) => self.set_bool(row, index, *v),
35 (
36 Type::Boolean,
37 Value::None {
38 ..
39 },
40 ) => self.set_undefined(row, index),
41
42 (Type::Float4, Value::Float4(v)) => self.set_f32(row, index, v.value()),
43 (
44 Type::Float4,
45 Value::None {
46 ..
47 },
48 ) => self.set_undefined(row, index),
49
50 (Type::Float8, Value::Float8(v)) => self.set_f64(row, index, v.value()),
51 (
52 Type::Float8,
53 Value::None {
54 ..
55 },
56 ) => self.set_undefined(row, index),
57
58 (Type::Int1, Value::Int1(v)) => self.set_i8(row, index, *v),
59 (
60 Type::Int1,
61 Value::None {
62 ..
63 },
64 ) => self.set_undefined(row, index),
65
66 (Type::Int2, Value::Int2(v)) => self.set_i16(row, index, *v),
67 (
68 Type::Int2,
69 Value::None {
70 ..
71 },
72 ) => self.set_undefined(row, index),
73
74 (Type::Int4, Value::Int4(v)) => self.set_i32(row, index, *v),
75 (
76 Type::Int4,
77 Value::None {
78 ..
79 },
80 ) => self.set_undefined(row, index),
81
82 (Type::Int8, Value::Int8(v)) => self.set_i64(row, index, *v),
83 (
84 Type::Int8,
85 Value::None {
86 ..
87 },
88 ) => self.set_undefined(row, index),
89
90 (Type::Int16, Value::Int16(v)) => self.set_i128(row, index, *v),
91 (
92 Type::Int16,
93 Value::None {
94 ..
95 },
96 ) => self.set_undefined(row, index),
97
98 (Type::Utf8, Value::Utf8(v)) => self.set_utf8(row, index, v),
99 (
100 Type::Utf8,
101 Value::None {
102 ..
103 },
104 ) => self.set_undefined(row, index),
105
106 (Type::Uint1, Value::Uint1(v)) => self.set_u8(row, index, *v),
107 (
108 Type::Uint1,
109 Value::None {
110 ..
111 },
112 ) => self.set_undefined(row, index),
113
114 (Type::Uint2, Value::Uint2(v)) => self.set_u16(row, index, *v),
115 (
116 Type::Uint2,
117 Value::None {
118 ..
119 },
120 ) => self.set_undefined(row, index),
121
122 (Type::Uint4, Value::Uint4(v)) => self.set_u32(row, index, *v),
123 (
124 Type::Uint4,
125 Value::None {
126 ..
127 },
128 ) => self.set_undefined(row, index),
129
130 (Type::Uint8, Value::Uint8(v)) => self.set_u64(row, index, *v),
131 (
132 Type::Uint8,
133 Value::None {
134 ..
135 },
136 ) => self.set_undefined(row, index),
137
138 (Type::Uint16, Value::Uint16(v)) => self.set_u128(row, index, *v),
139 (
140 Type::Uint16,
141 Value::None {
142 ..
143 },
144 ) => self.set_undefined(row, index),
145
146 (Type::Date, Value::Date(v)) => self.set_date(row, index, v.clone()),
147 (
148 Type::Date,
149 Value::None {
150 ..
151 },
152 ) => self.set_undefined(row, index),
153
154 (Type::DateTime, Value::DateTime(v)) => self.set_datetime(row, index, v.clone()),
155 (
156 Type::DateTime,
157 Value::None {
158 ..
159 },
160 ) => self.set_undefined(row, index),
161
162 (Type::Time, Value::Time(v)) => self.set_time(row, index, v.clone()),
163 (
164 Type::Time,
165 Value::None {
166 ..
167 },
168 ) => self.set_undefined(row, index),
169
170 (Type::Duration, Value::Duration(v)) => self.set_duration(row, index, v.clone()),
171 (
172 Type::Duration,
173 Value::None {
174 ..
175 },
176 ) => self.set_undefined(row, index),
177
178 (Type::Uuid4, Value::Uuid4(v)) => self.set_uuid4(row, index, v.clone()),
179 (
180 Type::Uuid4,
181 Value::None {
182 ..
183 },
184 ) => self.set_undefined(row, index),
185
186 (Type::Uuid7, Value::Uuid7(v)) => self.set_uuid7(row, index, v.clone()),
187 (
188 Type::Uuid7,
189 Value::None {
190 ..
191 },
192 ) => self.set_undefined(row, index),
193
194 (Type::Blob, Value::Blob(v)) => self.set_blob(row, index, v),
195 (
196 Type::Blob,
197 Value::None {
198 ..
199 },
200 ) => self.set_undefined(row, index),
201
202 (Type::Int, Value::Int(v)) => self.set_int(row, index, v),
203 (Type::Uint, Value::Uint(v)) => self.set_uint(row, index, v),
204 (
205 Type::Int,
206 Value::None {
207 ..
208 },
209 ) => self.set_undefined(row, index),
210 (
211 Type::Uint,
212 Value::None {
213 ..
214 },
215 ) => self.set_undefined(row, index),
216
217 (
218 Type::Decimal {
219 ..
220 },
221 Value::Decimal(v),
222 ) => self.set_decimal(row, index, v),
223 (
224 Type::Decimal {
225 ..
226 },
227 Value::None {
228 ..
229 },
230 ) => self.set_undefined(row, index),
231 (Type::DictionaryId, Value::DictionaryId(id)) => self.set_dictionary_id(row, index, id),
232
233 (
234 Type::DictionaryId,
235 Value::None {
236 ..
237 },
238 ) => self.set_undefined(row, index),
239
240 (Type::Any, Value::Any(_)) => unreachable!("Any type cannot be stored in database"),
241 (
242 Type::Any,
243 Value::None {
244 ..
245 },
246 ) => self.set_undefined(row, index),
247 (ty, val) => unreachable!("{ty:?}, {val:?}"),
248 }
249 }
250
251 pub fn get_value(&self, row: &EncodedValues, index: usize) -> Value {
252 let field = &self.fields()[index];
253 if !row.is_defined(index) {
254 return Value::none();
255 }
256 let field_type = match field.constraint.get_type() {
257 Type::Option(inner) => *inner,
258 other => other,
259 };
260
261 match field_type {
262 Type::Boolean => Value::Boolean(self.get_bool(row, index)),
263 Type::Float4 => OrderedF32::try_from(self.get_f32(row, index))
264 .map(Value::Float4)
265 .unwrap_or(Value::none()),
266 Type::Float8 => OrderedF64::try_from(self.get_f64(row, index))
267 .map(Value::Float8)
268 .unwrap_or(Value::none()),
269 Type::Int1 => Value::Int1(self.get_i8(row, index)),
270 Type::Int2 => Value::Int2(self.get_i16(row, index)),
271 Type::Int4 => Value::Int4(self.get_i32(row, index)),
272 Type::Int8 => Value::Int8(self.get_i64(row, index)),
273 Type::Int16 => Value::Int16(self.get_i128(row, index)),
274 Type::Utf8 => Value::Utf8(self.get_utf8(row, index).to_string()),
275 Type::Uint1 => Value::Uint1(self.get_u8(row, index)),
276 Type::Uint2 => Value::Uint2(self.get_u16(row, index)),
277 Type::Uint4 => Value::Uint4(self.get_u32(row, index)),
278 Type::Uint8 => Value::Uint8(self.get_u64(row, index)),
279 Type::Uint16 => Value::Uint16(self.get_u128(row, index)),
280 Type::Date => Value::Date(self.get_date(row, index)),
281 Type::DateTime => Value::DateTime(self.get_datetime(row, index)),
282 Type::Time => Value::Time(self.get_time(row, index)),
283 Type::Duration => Value::Duration(self.get_duration(row, index)),
284 Type::IdentityId => {
285 Value::IdentityId(IdentityId::from(Uuid7::from(self.get_uuid7(row, index))))
286 }
287 Type::Uuid4 => Value::Uuid4(Uuid4::from(self.get_uuid4(row, index))),
288 Type::Uuid7 => Value::Uuid7(Uuid7::from(self.get_uuid7(row, index))),
289 Type::Blob => Value::Blob(self.get_blob(row, index)),
290 Type::Int => Value::Int(self.get_int(row, index)),
291 Type::Uint => Value::Uint(self.get_uint(row, index)),
292 Type::Decimal {
293 ..
294 } => Value::Decimal(self.get_decimal(row, index)),
295 Type::DictionaryId => Value::DictionaryId(self.get_dictionary_id(row, index)),
296 Type::Option(_) => unreachable!("Option type already unwrapped"),
297 Type::Any => unreachable!("Any type cannot be stored in database"),
298 }
299 }
300}
301
302#[cfg(test)]
303#[allow(clippy::approx_constant)]
304pub mod tests {
305 use reifydb_type::value::{
306 Value,
307 blob::Blob,
308 constraint::TypeConstraint,
309 date::Date,
310 datetime::DateTime,
311 dictionary::{DictionaryEntryId, DictionaryId},
312 duration::Duration,
313 ordered_f32::OrderedF32,
314 ordered_f64::OrderedF64,
315 time::Time,
316 r#type::Type,
317 uuid::{Uuid4, Uuid7},
318 };
319
320 use crate::encoded::schema::{Schema, SchemaField};
321
322 #[test]
323 fn test_set_utf8_with_dynamic_content() {
324 let schema = Schema::testing(&[Type::Utf8, Type::Int4, Type::Utf8]);
325 let mut row = schema.allocate();
326
327 let value1 = Value::Utf8("hello".to_string());
328 let value2 = Value::Int4(42);
329 let value3 = Value::Utf8("world".to_string());
330
331 schema.set_value(&mut row, 0, &value1);
332 schema.set_value(&mut row, 1, &value2);
333 schema.set_value(&mut row, 2, &value3);
334
335 assert_eq!(schema.get_utf8(&row, 0), "hello");
336 assert_eq!(schema.get_i32(&row, 1), 42);
337 assert_eq!(schema.get_utf8(&row, 2), "world");
338 }
339
340 #[test]
341 fn test_set_values_with_mixed_dynamic_content() {
342 let schema = Schema::testing(&[Type::Boolean, Type::Utf8, Type::Float4, Type::Utf8, Type::Int2]);
343 let mut row = schema.allocate();
344
345 let values = vec![
346 Value::Boolean(true),
347 Value::Utf8("first_string".to_string()),
348 Value::Float4(OrderedF32::try_from(3.14f32).unwrap()),
349 Value::Utf8("second_string".to_string()),
350 Value::Int2(-100),
351 ];
352
353 schema.set_values(&mut row, &values);
354
355 assert_eq!(schema.get_bool(&row, 0), true);
356 assert_eq!(schema.get_utf8(&row, 1), "first_string");
357 assert_eq!(schema.get_f32(&row, 2), 3.14f32);
358 assert_eq!(schema.get_utf8(&row, 3), "second_string");
359 assert_eq!(schema.get_i16(&row, 4), -100);
360 }
361
362 #[test]
363 fn test_set_with_empty_and_large_utf8() {
364 let schema = Schema::testing(&[Type::Utf8, Type::Utf8, Type::Utf8]);
365 let mut row = schema.allocate();
366
367 let large_string = "X".repeat(2000);
368 let values = vec![
369 Value::Utf8("".to_string()),
370 Value::Utf8(large_string.clone()),
371 Value::Utf8("small".to_string()),
372 ];
373
374 schema.set_values(&mut row, &values);
375
376 assert_eq!(schema.get_utf8(&row, 0), "");
377 assert_eq!(schema.get_utf8(&row, 1), large_string);
378 assert_eq!(schema.get_utf8(&row, 2), "small");
379 assert_eq!(schema.dynamic_section_size(&row), 2005); }
381
382 #[test]
383 fn test_get_from_dynamic_content() {
384 let schema = Schema::testing(&[Type::Utf8, Type::Int8, Type::Utf8]);
385 let mut row = schema.allocate();
386
387 schema.set_utf8(&mut row, 0, "test_string");
388 schema.set_i64(&mut row, 1, 9876543210i64);
389 schema.set_utf8(&mut row, 2, "another_string");
390
391 let value0 = schema.get_value(&row, 0);
392 let value1 = schema.get_value(&row, 1);
393 let value2 = schema.get_value(&row, 2);
394
395 match value0 {
396 Value::Utf8(s) => assert_eq!(s, "test_string"),
397 _ => panic!("Expected UTF8 value"),
398 }
399
400 match value1 {
401 Value::Int8(i) => assert_eq!(i, 9876543210),
402 _ => panic!("Expected Int8 value"),
403 }
404
405 match value2 {
406 Value::Utf8(s) => assert_eq!(s, "another_string"),
407 _ => panic!("Expected UTF8 value"),
408 }
409 }
410
411 #[test]
412 fn test_set_undefined_with_utf8_fields() {
413 let schema = Schema::testing(&[Type::Utf8, Type::Boolean, Type::Utf8]);
414 let mut row = schema.allocate();
415
416 schema.set_value(&mut row, 0, &Value::Utf8("hello".to_string()));
418 schema.set_value(&mut row, 1, &Value::Boolean(true));
419 schema.set_value(&mut row, 2, &Value::Utf8("world".to_string()));
420
421 assert!(row.is_defined(0));
422 assert!(row.is_defined(1));
423 assert!(row.is_defined(2));
424
425 schema.set_value(&mut row, 0, &Value::none());
427 schema.set_value(&mut row, 2, &Value::none());
428
429 assert!(!row.is_defined(0));
430 assert!(row.is_defined(1));
431 assert!(!row.is_defined(2));
432
433 assert_eq!(schema.get_bool(&row, 1), true);
434 }
435
436 #[test]
437 fn test_get_all_types_including_utf8() {
438 let schema = Schema::testing(&[
439 Type::Boolean,
440 Type::Int1,
441 Type::Int2,
442 Type::Int4,
443 Type::Int8,
444 Type::Uint1,
445 Type::Uint2,
446 Type::Uint4,
447 Type::Uint8,
448 Type::Float4,
449 Type::Float8,
450 Type::Utf8,
451 ]);
452 let mut row = schema.allocate();
453
454 schema.set_bool(&mut row, 0, true);
455 schema.set_i8(&mut row, 1, -42);
456 schema.set_i16(&mut row, 2, -1000i16);
457 schema.set_i32(&mut row, 3, -50000i32);
458 schema.set_i64(&mut row, 4, -3000000000i64);
459 schema.set_u8(&mut row, 5, 200u8);
460 schema.set_u16(&mut row, 6, 50000u16);
461 schema.set_u32(&mut row, 7, 3000000000u32);
462 schema.set_u64(&mut row, 8, 15000000000000000000u64);
463 schema.set_f32(&mut row, 9, 2.5);
464 schema.set_f64(&mut row, 10, 123.456789);
465 schema.set_utf8(&mut row, 11, "dynamic_string");
466
467 let values: Vec<Value> = (0..12).map(|i| schema.get_value(&row, i)).collect();
468
469 assert_eq!(values[0], Value::Boolean(true));
470 assert_eq!(values[1], Value::Int1(-42));
471 assert_eq!(values[2], Value::Int2(-1000));
472 assert_eq!(values[3], Value::Int4(-50000));
473 assert_eq!(values[4], Value::Int8(-3000000000));
474 assert_eq!(values[5], Value::Uint1(200));
475 assert_eq!(values[6], Value::Uint2(50000));
476 assert_eq!(values[7], Value::Uint4(3000000000));
477 assert_eq!(values[8], Value::Uint8(15000000000000000000));
478 assert_eq!(values[9], Value::Float4(OrderedF32::try_from(2.5f32).unwrap()));
479 assert_eq!(values[10], Value::Float8(OrderedF64::try_from(123.456789f64).unwrap()));
480 assert_eq!(values[11], Value::Utf8("dynamic_string".to_string()));
481 }
482
483 #[test]
484 fn test_set_values_sparse_with_utf8() {
485 let schema = Schema::testing(&[Type::Utf8, Type::Utf8, Type::Utf8, Type::Utf8]);
486 let mut row = schema.allocate();
487
488 let values = vec![
490 Value::Utf8("first".to_string()),
491 Value::none(),
492 Value::Utf8("third".to_string()),
493 Value::none(),
494 ];
495
496 schema.set_values(&mut row, &values);
497
498 assert!(row.is_defined(0));
499 assert!(!row.is_defined(1));
500 assert!(row.is_defined(2));
501 assert!(!row.is_defined(3));
502
503 assert_eq!(schema.get_utf8(&row, 0), "first");
504 assert_eq!(schema.get_utf8(&row, 2), "third");
505 }
506
507 #[test]
508 fn test_set_values_unicode_strings() {
509 let schema = Schema::testing(&[Type::Utf8, Type::Int4, Type::Utf8]);
510 let mut row = schema.allocate();
511
512 let values = vec![
513 Value::Utf8("ππβ¨".to_string()),
514 Value::Int4(123),
515 Value::Utf8("Hello δΈη".to_string()),
516 ];
517
518 schema.set_values(&mut row, &values);
519
520 assert_eq!(schema.get_utf8(&row, 0), "ππβ¨");
521 assert_eq!(schema.get_i32(&row, 1), 123);
522 assert_eq!(schema.get_utf8(&row, 2), "Hello δΈη");
523 }
524
525 #[test]
526 fn test_static_fields_only_no_dynamic_with_values() {
527 let schema = Schema::testing(&[Type::Boolean, Type::Int4, Type::Float8]);
528 let mut row = schema.allocate();
529
530 let values = vec![
531 Value::Boolean(false),
532 Value::Int4(999),
533 Value::Float8(OrderedF64::try_from(std::f64::consts::E).unwrap()),
534 ];
535
536 schema.set_values(&mut row, &values);
537
538 assert_eq!(schema.dynamic_section_size(&row), 0);
540 assert_eq!(row.len(), schema.total_static_size());
541
542 assert_eq!(schema.get_bool(&row, 0), false);
543 assert_eq!(schema.get_i32(&row, 1), 999);
544 assert_eq!(schema.get_f64(&row, 2), std::f64::consts::E);
545 }
546
547 #[test]
548 fn test_temporal_types_roundtrip() {
549 let schema = Schema::testing(&[Type::Date, Type::DateTime, Type::Time, Type::Duration]);
550 let mut row = schema.allocate();
551
552 let original_values = vec![
553 Value::Date(Date::new(2025, 7, 15).unwrap()),
554 Value::DateTime(DateTime::from_ymd_hms(2025, 7, 15, 14, 30, 45).unwrap()),
555 Value::Time(Time::new(14, 30, 45, 123456789).unwrap()),
556 Value::Duration(Duration::from_seconds(3600)),
557 ];
558
559 schema.set_values(&mut row, &original_values);
560
561 let retrieved_values: Vec<Value> = (0..4).map(|i| schema.get_value(&row, i)).collect();
562
563 assert_eq!(retrieved_values, original_values);
564 }
565
566 #[test]
567 fn test_temporal_types_with_undefined() {
568 let schema = Schema::testing(&[Type::Date, Type::DateTime, Type::Time, Type::Duration]);
569 let mut row = schema.allocate();
570
571 let values = vec![
572 Value::Date(Date::new(2000, 1, 1).unwrap()),
573 Value::none(),
574 Value::Time(Time::default()),
575 Value::none(),
576 ];
577
578 schema.set_values(&mut row, &values);
579
580 assert!(row.is_defined(0));
581 assert!(!row.is_defined(1));
582 assert!(row.is_defined(2));
583 assert!(!row.is_defined(3));
584
585 let retrieved_values: Vec<Value> = (0..4).map(|i| schema.get_value(&row, i)).collect();
586
587 assert_eq!(retrieved_values[0], values[0]);
588 assert_eq!(retrieved_values[1], Value::none());
589 assert_eq!(retrieved_values[2], values[2]);
590 assert_eq!(retrieved_values[3], Value::none());
591 }
592
593 #[test]
594 fn test_mixed_temporal_and_regular_types() {
595 let schema = Schema::testing(&[
596 Type::Boolean,
597 Type::Date,
598 Type::Utf8,
599 Type::DateTime,
600 Type::Int4,
601 Type::Time,
602 Type::Duration,
603 ]);
604 let mut row = schema.allocate();
605
606 let values = vec![
607 Value::Boolean(true),
608 Value::Date(Date::new(1985, 10, 26).unwrap()),
609 Value::Utf8("time travel".to_string()),
610 Value::DateTime(DateTime::new(2015, 10, 21, 16, 29, 0, 0).unwrap()),
611 Value::Int4(88),
612 Value::Time(Time::new(12, 0, 0, 0).unwrap()),
613 Value::Duration(Duration::from_minutes(30)),
614 ];
615
616 schema.set_values(&mut row, &values);
617
618 let retrieved_values: Vec<Value> = (0..7).map(|i| schema.get_value(&row, i)).collect();
619
620 assert_eq!(retrieved_values, values);
621 }
622
623 #[test]
624 fn test_roundtrip_with_dynamic_content() {
625 let schema = Schema::testing(&[Type::Utf8, Type::Int2, Type::Utf8, Type::Float4]);
626 let mut row = schema.allocate();
627
628 let original_values = vec![
629 Value::Utf8("roundtrip_test".to_string()),
630 Value::Int2(32000),
631 Value::Utf8("".to_string()),
632 Value::Float4(OrderedF32::try_from(1.5f32).unwrap()),
633 ];
634
635 schema.set_values(&mut row, &original_values);
637
638 let retrieved_values: Vec<Value> = (0..4).map(|i| schema.get_value(&row, i)).collect();
640
641 assert_eq!(retrieved_values, original_values);
642 }
643
644 #[test]
645 fn test_blob_roundtrip() {
646 let schema = Schema::testing(&[Type::Blob, Type::Int4, Type::Blob]);
647 let mut row = schema.allocate();
648
649 let blob1 = Blob::new(vec![0xDE, 0xAD, 0xBE, 0xEF]);
650 let blob2 = Blob::new(vec![]);
651 let values = vec![Value::Blob(blob1.clone()), Value::Int4(42), Value::Blob(blob2.clone())];
652
653 schema.set_values(&mut row, &values);
654
655 let retrieved_values: Vec<Value> = (0..3).map(|i| schema.get_value(&row, i)).collect();
656
657 assert_eq!(retrieved_values, values);
658
659 match &retrieved_values[0] {
661 Value::Blob(b) => assert_eq!(b.as_bytes(), &[0xDE, 0xAD, 0xBE, 0xEF]),
662 _ => panic!("Expected Blob value"),
663 }
664
665 match &retrieved_values[2] {
666 Value::Blob(b) => assert!(b.is_empty()),
667 _ => panic!("Expected Blob value"),
668 }
669 }
670
671 #[test]
672 fn test_blob_with_undefined() {
673 let schema = Schema::testing(&[Type::Blob, Type::Blob, Type::Blob]);
674 let mut row = schema.allocate();
675
676 let values = vec![
677 Value::Blob(Blob::new(vec![0x00, 0x01, 0x02])),
678 Value::none(),
679 Value::Blob(Blob::new(vec![0xFF, 0xFE])),
680 ];
681
682 schema.set_values(&mut row, &values);
683
684 assert!(row.is_defined(0));
685 assert!(!row.is_defined(1));
686 assert!(row.is_defined(2));
687
688 let retrieved_values: Vec<Value> = (0..3).map(|i| schema.get_value(&row, i)).collect();
689
690 assert_eq!(retrieved_values[0], values[0]);
691 assert_eq!(retrieved_values[1], Value::none());
692 assert_eq!(retrieved_values[2], values[2]);
693 }
694
695 #[test]
696 fn test_uuid_roundtrip() {
697 let schema = Schema::testing(&[Type::Uuid4, Type::Uuid7, Type::Int4]);
698 let mut row = schema.allocate();
699
700 let uuid4 = Uuid4::generate();
701 let uuid7 = Uuid7::generate();
702 let values = vec![Value::Uuid4(uuid4), Value::Uuid7(uuid7), Value::Int4(123)];
703
704 schema.set_values(&mut row, &values);
705
706 let retrieved_values: Vec<Value> = (0..3).map(|i| schema.get_value(&row, i)).collect();
707
708 assert_eq!(retrieved_values, values);
709 }
710
711 #[test]
712 fn test_uuid_with_undefined() {
713 let schema = Schema::testing(&[Type::Uuid4, Type::Uuid7]);
714 let mut row = schema.allocate();
715
716 let values = vec![Value::none(), Value::Uuid7(Uuid7::generate())];
717
718 schema.set_values(&mut row, &values);
719
720 assert!(!row.is_defined(0));
721 assert!(row.is_defined(1));
722
723 let retrieved_values: Vec<Value> = (0..2).map(|i| schema.get_value(&row, i)).collect();
724
725 assert_eq!(retrieved_values[0], Value::none());
726 assert_eq!(retrieved_values[1], values[1]);
727 }
728
729 #[test]
730 fn test_mixed_blob_row_number_uuid_types() {
731 let schema =
732 Schema::testing(&[Type::Blob, Type::Int16, Type::Uuid4, Type::Utf8, Type::Uuid7, Type::Int4]);
733 let mut row = schema.allocate();
734
735 let values = vec![
736 Value::Blob(Blob::new(vec![0xCA, 0xFE, 0xBA, 0xBE])),
737 Value::Int16(42424242i128),
738 Value::Uuid4(Uuid4::generate()),
739 Value::Utf8("mixed types test".to_string()),
740 Value::Uuid7(Uuid7::generate()),
741 Value::Int4(-999),
742 ];
743
744 schema.set_values(&mut row, &values);
745
746 let retrieved_values: Vec<Value> = (0..6).map(|i| schema.get_value(&row, i)).collect();
747
748 assert_eq!(retrieved_values, values);
749
750 assert!(schema.dynamic_section_size(&row) > 0);
752 }
753
754 #[test]
755 fn test_all_types_comprehensive() {
756 let schema = Schema::testing(&[
759 Type::Boolean,
760 Type::Int1,
761 Type::Int2,
762 Type::Int4,
763 Type::Int8,
764 Type::Int16,
765 Type::Uint1,
766 Type::Uint2,
767 Type::Uint4,
768 Type::Uint8,
769 Type::Uint16,
770 Type::Float4,
771 Type::Float8,
772 Type::Utf8,
773 Type::Date,
774 Type::DateTime,
775 Type::Time,
776 Type::Duration,
777 Type::Uuid4,
778 Type::Uuid7,
779 Type::Blob,
780 ]);
781 let mut row = schema.allocate();
782
783 let values = vec![
784 Value::Boolean(true),
785 Value::Int1(-128),
786 Value::Int2(-32768),
787 Value::Int4(-2147483648),
788 Value::Int8(-9223372036854775808),
789 Value::Int16(-170141183460469231731687303715884105728),
790 Value::Uint1(255),
791 Value::Uint2(65535),
792 Value::Uint4(4294967295),
793 Value::Uint8(18446744073709551615),
794 Value::Uint16(340282366920938463463374607431768211455),
795 Value::Float4(OrderedF32::try_from(3.14159f32).unwrap()),
796 Value::Float8(OrderedF64::try_from(2.718281828459045).unwrap()),
797 Value::Utf8("comprehensive test".to_string()),
798 Value::Date(Date::new(2025, 12, 31).unwrap()),
799 Value::DateTime(DateTime::new(2025, 1, 1, 0, 0, 0, 0).unwrap()),
800 Value::Time(Time::new(23, 59, 59, 999999999).unwrap()),
801 Value::Duration(Duration::from_hours(24)),
802 Value::Uuid4(Uuid4::generate()),
803 Value::Uuid7(Uuid7::generate()),
804 Value::Blob(Blob::new(vec![
805 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD,
806 0xEE, 0xFF,
807 ])),
808 ];
809
810 schema.set_values(&mut row, &values);
811
812 let retrieved_values: Vec<Value> = (0..21).map(|i| schema.get_value(&row, i)).collect();
813
814 assert_eq!(retrieved_values, values);
815
816 for i in 0..21 {
818 assert!(row.is_defined(i), "Field {} should be defined", i);
819 }
820 }
821
822 #[test]
823 fn test_dictionary_id_roundtrip_u4() {
824 let constraint = TypeConstraint::dictionary(DictionaryId::from(42u64), Type::Uint4);
825 let schema = Schema::new(vec![SchemaField::new("status", constraint)]);
826
827 let mut row = schema.allocate();
828 let entry = DictionaryEntryId::U4(7);
829 schema.set_value(&mut row, 0, &Value::DictionaryId(entry));
830
831 assert!(row.is_defined(0));
832 let retrieved = schema.get_value(&row, 0);
833 assert_eq!(retrieved, Value::DictionaryId(DictionaryEntryId::U4(7)));
834 }
835
836 #[test]
837 fn test_dictionary_id_roundtrip_u2() {
838 let constraint = TypeConstraint::dictionary(DictionaryId::from(10u64), Type::Uint2);
839 let schema = Schema::new(vec![SchemaField::new("category", constraint)]);
840
841 let mut row = schema.allocate();
842 let entry = DictionaryEntryId::U2(500);
843 schema.set_value(&mut row, 0, &Value::DictionaryId(entry));
844
845 assert!(row.is_defined(0));
846 let retrieved = schema.get_value(&row, 0);
847 assert_eq!(retrieved, Value::DictionaryId(DictionaryEntryId::U2(500)));
848 }
849
850 #[test]
851 fn test_dictionary_id_roundtrip_u8() {
852 let constraint = TypeConstraint::dictionary(DictionaryId::from(99u64), Type::Uint8);
853 let schema = Schema::new(vec![SchemaField::new("tag", constraint)]);
854
855 let mut row = schema.allocate();
856 let entry = DictionaryEntryId::U8(123456789);
857 schema.set_value(&mut row, 0, &Value::DictionaryId(entry));
858
859 assert!(row.is_defined(0));
860 let retrieved = schema.get_value(&row, 0);
861 assert_eq!(retrieved, Value::DictionaryId(DictionaryEntryId::U8(123456789)));
862 }
863
864 #[test]
865 fn test_dictionary_id_with_undefined() {
866 let constraint = TypeConstraint::dictionary(DictionaryId::from(1u64), Type::Uint4);
867 let schema = Schema::new(vec![
868 SchemaField::new("dict_col", constraint),
869 SchemaField::unconstrained("int_col", Type::Int4),
870 ]);
871
872 let mut row = schema.allocate();
873 schema.set_value(&mut row, 0, &Value::none());
874 schema.set_value(&mut row, 1, &Value::Int4(42));
875
876 assert!(!row.is_defined(0));
877 assert!(row.is_defined(1));
878
879 assert_eq!(schema.get_value(&row, 0), Value::none());
880 assert_eq!(schema.get_value(&row, 1), Value::Int4(42));
881 }
882
883 #[test]
884 fn test_dictionary_id_mixed_with_other_types() {
885 let dict_constraint = TypeConstraint::dictionary(DictionaryId::from(5u64), Type::Uint4);
886 let schema = Schema::new(vec![
887 SchemaField::unconstrained("id", Type::Int4),
888 SchemaField::new("status", dict_constraint),
889 SchemaField::unconstrained("name", Type::Utf8),
890 ]);
891
892 let mut row = schema.allocate();
893 let values = vec![
894 Value::Int4(100),
895 Value::DictionaryId(DictionaryEntryId::U4(3)),
896 Value::Utf8("test".to_string()),
897 ];
898 schema.set_values(&mut row, &values);
899
900 let retrieved: Vec<Value> = (0..3).map(|i| schema.get_value(&row, i)).collect();
901 assert_eq!(retrieved, values);
902 }
903}