reifydb_core/value/encoded/
undefined.rs

1// Copyright (c) reifydb.com 2025
2// This file is licensed under the AGPL-3.0-or-later, see license.md file
3
4use crate::value::encoded::{EncodedValues, EncodedValuesLayout};
5
6impl EncodedValuesLayout {
7	/// Set a field as undefined (not set)
8	pub fn set_undefined(&self, row: &mut EncodedValues, index: usize) {
9		row.set_valid(index, false);
10	}
11}
12
13#[cfg(test)]
14mod tests {
15	use reifydb_type::Type;
16
17	use crate::value::encoded::EncodedValuesLayout;
18
19	#[test]
20	fn test_set_bool() {
21		let layout = EncodedValuesLayout::new(&[Type::Boolean]);
22		let mut row = layout.allocate();
23
24		// Set a value
25		layout.set_bool(&mut row, 0, true);
26		assert!(row.is_defined(0));
27		assert_eq!(layout.try_get_bool(&row, 0), Some(true));
28
29		// Set as undefined
30		layout.set_undefined(&mut row, 0);
31		assert!(!row.is_defined(0));
32		assert_eq!(layout.try_get_bool(&row, 0), None);
33	}
34
35	#[test]
36	fn test_set_integer() {
37		let layout = EncodedValuesLayout::new(&[Type::Int4]);
38		let mut row = layout.allocate();
39
40		// Set a value
41		layout.set_i32(&mut row, 0, 12345);
42		assert!(row.is_defined(0));
43		assert_eq!(layout.try_get_i32(&row, 0), Some(12345));
44
45		// Set as undefined
46		layout.set_undefined(&mut row, 0);
47		assert!(!row.is_defined(0));
48		assert_eq!(layout.try_get_i32(&row, 0), None);
49	}
50
51	#[test]
52	fn test_set_dynamic_type() {
53		let layout = EncodedValuesLayout::new(&[Type::Utf8]);
54		let mut row = layout.allocate();
55
56		// Set a string value
57		layout.set_utf8(&mut row, 0, "hello world");
58		assert!(row.is_defined(0));
59		assert_eq!(layout.try_get_utf8(&row, 0), Some("hello world"));
60
61		// Set as undefined
62		layout.set_undefined(&mut row, 0);
63		assert!(!row.is_defined(0));
64		assert_eq!(layout.try_get_utf8(&row, 0), None);
65	}
66
67	#[test]
68	fn test_set_multiple_fields() {
69		let layout = EncodedValuesLayout::new(&[Type::Boolean, Type::Int4, Type::Utf8]);
70		let mut row = layout.allocate();
71
72		// Set all fields
73		layout.set_bool(&mut row, 0, true);
74		layout.set_i32(&mut row, 1, 42);
75		layout.set_utf8(&mut row, 2, "test");
76
77		assert!(row.is_defined(0));
78		assert!(row.is_defined(1));
79		assert!(row.is_defined(2));
80
81		// Set middle field as undefined
82		layout.set_undefined(&mut row, 1);
83
84		assert!(row.is_defined(0));
85		assert!(!row.is_defined(1));
86		assert!(row.is_defined(2));
87
88		assert_eq!(layout.try_get_bool(&row, 0), Some(true));
89		assert_eq!(layout.try_get_i32(&row, 1), None);
90		assert_eq!(layout.try_get_utf8(&row, 2), Some("test"));
91	}
92
93	#[test]
94	fn test_set_all_fields() {
95		let layout = EncodedValuesLayout::new(&[Type::Boolean, Type::Int4, Type::Float8]);
96		let mut row = layout.allocate();
97
98		// Set all fields
99		layout.set_bool(&mut row, 0, false);
100		layout.set_i32(&mut row, 1, -999);
101		layout.set_f64(&mut row, 2, 3.14159);
102
103		assert!(row.is_defined(0));
104		assert!(row.is_defined(1));
105		assert!(row.is_defined(2));
106
107		// Set all as undefined
108		layout.set_undefined(&mut row, 0);
109		layout.set_undefined(&mut row, 1);
110		layout.set_undefined(&mut row, 2);
111
112		assert!(!row.is_defined(0));
113		assert!(!row.is_defined(1));
114		assert!(!row.is_defined(2));
115		assert!(!layout.all_defined(&row));
116	}
117
118	#[test]
119	fn test_set_reuse_field() {
120		let layout = EncodedValuesLayout::new(&[Type::Int8]);
121		let mut row = layout.allocate();
122
123		// Set, unset, then set again
124		layout.set_i64(&mut row, 0, 100);
125		assert_eq!(layout.try_get_i64(&row, 0), Some(100));
126
127		layout.set_undefined(&mut row, 0);
128		assert_eq!(layout.try_get_i64(&row, 0), None);
129
130		layout.set_i64(&mut row, 0, 200);
131		assert_eq!(layout.try_get_i64(&row, 0), Some(200));
132	}
133
134	#[test]
135	fn test_set_temporal_types() {
136		use reifydb_type::{Date, DateTime, Duration, Time};
137
138		let layout = EncodedValuesLayout::new(&[Type::Date, Type::DateTime, Type::Time, Type::Duration]);
139		let mut row = layout.allocate();
140
141		// Set temporal values
142		let date = Date::new(2025, 1, 15).unwrap();
143		let datetime = DateTime::from_timestamp(1642694400).unwrap();
144		let time = Time::from_hms(14, 30, 45).unwrap();
145		let duration = Duration::from_days(7);
146
147		layout.set_date(&mut row, 0, date.clone());
148		layout.set_datetime(&mut row, 1, datetime.clone());
149		layout.set_time(&mut row, 2, time.clone());
150		layout.set_duration(&mut row, 3, duration.clone());
151
152		// Verify all are defined
153		assert!(row.is_defined(0));
154		assert!(row.is_defined(1));
155		assert!(row.is_defined(2));
156		assert!(row.is_defined(3));
157
158		// Set some as undefined
159		layout.set_undefined(&mut row, 0);
160		layout.set_undefined(&mut row, 2);
161
162		// Check results
163		assert!(!row.is_defined(0));
164		assert!(row.is_defined(1));
165		assert!(!row.is_defined(2));
166		assert!(row.is_defined(3));
167
168		assert_eq!(layout.try_get_date(&row, 0), None);
169		assert_eq!(layout.try_get_datetime(&row, 1), Some(datetime));
170		assert_eq!(layout.try_get_time(&row, 2), None);
171		assert_eq!(layout.try_get_duration(&row, 3), Some(duration));
172	}
173
174	#[test]
175	fn test_set_uuid_types() {
176		use reifydb_type::{IdentityId, Uuid4, Uuid7};
177
178		let layout = EncodedValuesLayout::new(&[Type::Uuid4, Type::Uuid7, Type::IdentityId]);
179		let mut row = layout.allocate();
180
181		// Set UUID values
182		let uuid4 = Uuid4::generate();
183		let uuid7 = Uuid7::generate();
184		let identity_id = IdentityId::generate();
185
186		layout.set_uuid4(&mut row, 0, uuid4.clone());
187		layout.set_uuid7(&mut row, 1, uuid7.clone());
188		layout.set_identity_id(&mut row, 2, identity_id.clone());
189
190		// All should be defined
191		assert!(row.is_defined(0));
192		assert!(row.is_defined(1));
193		assert!(row.is_defined(2));
194
195		// Set UUID7 as undefined
196		layout.set_undefined(&mut row, 1);
197
198		// Check results
199		assert!(row.is_defined(0));
200		assert!(!row.is_defined(1));
201		assert!(row.is_defined(2));
202
203		assert_eq!(layout.try_get_uuid4(&row, 0), Some(uuid4));
204		assert_eq!(layout.try_get_uuid7(&row, 1), None);
205		assert_eq!(layout.try_get_identity_id(&row, 2), Some(identity_id));
206	}
207
208	#[test]
209	fn test_set_decimal_int_uint() {
210		use std::str::FromStr;
211
212		use reifydb_type::{Decimal, Int, Uint};
213
214		let layout = EncodedValuesLayout::new(&[Type::Decimal, Type::Int, Type::Uint]);
215		let mut row = layout.allocate();
216
217		// Set values
218		let decimal = Decimal::from_str("123.45").unwrap();
219		let int = Int::from(i64::MAX);
220		let uint = Uint::from(u64::MAX);
221
222		layout.set_decimal(&mut row, 0, &decimal);
223		layout.set_int(&mut row, 1, &int);
224		layout.set_uint(&mut row, 2, &uint);
225
226		// All should be defined
227		assert!(row.is_defined(0));
228		assert!(row.is_defined(1));
229		assert!(row.is_defined(2));
230
231		// Set some as undefined
232		layout.set_undefined(&mut row, 0);
233		layout.set_undefined(&mut row, 2);
234
235		// Check results
236		assert!(!row.is_defined(0));
237		assert!(row.is_defined(1));
238		assert!(!row.is_defined(2));
239
240		assert_eq!(layout.try_get_decimal(&row, 0), None);
241		assert_eq!(layout.try_get_int(&row, 1), Some(int));
242		assert_eq!(layout.try_get_uint(&row, 2), None);
243	}
244
245	#[test]
246	fn test_set_blob() {
247		use reifydb_type::Blob;
248
249		let layout = EncodedValuesLayout::new(&[Type::Blob]);
250		let mut row = layout.allocate();
251
252		// Set a blob value
253		let blob = Blob::from_slice(&[1, 2, 3, 4, 5]);
254		layout.set_blob(&mut row, 0, &blob);
255		assert!(row.is_defined(0));
256		assert_eq!(layout.try_get_blob(&row, 0), Some(blob.clone()));
257
258		// Set as undefined
259		layout.set_undefined(&mut row, 0);
260		assert!(!row.is_defined(0));
261		assert_eq!(layout.try_get_blob(&row, 0), None);
262
263		// Set again with different value
264		let blob2 = Blob::from_slice(&[10, 20, 30]);
265		layout.set_blob(&mut row, 0, &blob2);
266		assert!(row.is_defined(0));
267		assert_eq!(layout.try_get_blob(&row, 0), Some(blob2));
268	}
269
270	#[test]
271	fn test_set_pattern() {
272		let layout = EncodedValuesLayout::new(&[
273			Type::Boolean,
274			Type::Boolean,
275			Type::Boolean,
276			Type::Boolean,
277			Type::Boolean,
278		]);
279		let mut row = layout.allocate();
280
281		// Set all as true
282		for i in 0..5 {
283			layout.set_bool(&mut row, i, true);
284		}
285
286		// Set every other field as undefined
287		for i in (0..5).step_by(2) {
288			layout.set_undefined(&mut row, i);
289		}
290
291		// Check pattern: undefined, defined, undefined, defined,
292		// undefined
293		assert!(!row.is_defined(0));
294		assert!(row.is_defined(1));
295		assert!(!row.is_defined(2));
296		assert!(row.is_defined(3));
297		assert!(!row.is_defined(4));
298
299		assert_eq!(layout.try_get_bool(&row, 0), None);
300		assert_eq!(layout.try_get_bool(&row, 1), Some(true));
301		assert_eq!(layout.try_get_bool(&row, 2), None);
302		assert_eq!(layout.try_get_bool(&row, 3), Some(true));
303		assert_eq!(layout.try_get_bool(&row, 4), None);
304	}
305}