Skip to main content

reifydb_codec/encoded/
undefined.rs

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