Skip to main content

reifydb_core/value/column/push/
none.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4use std::mem;
5
6use reifydb_type::{storage::DataBitVec, util::bitvec::BitVec};
7
8use crate::value::column::data::{ColumnData, with_container};
9
10impl ColumnData {
11	pub fn push_none(&mut self) {
12		match self {
13			ColumnData::Option {
14				inner,
15				bitvec,
16			} => {
17				// Push a default value to the inner container (not recursive promotion)
18				with_container!(inner.as_mut(), |c| c.push_default());
19				DataBitVec::push(bitvec, false);
20			}
21			_ => {
22				// Promote bare container to Option-wrapped, then push none
23				let len = self.len();
24				let mut bitvec = BitVec::repeat(len, true);
25				let mut inner = mem::replace(self, ColumnData::bool(vec![]));
26				// Push a default value to the inner container directly (avoid recursion)
27				with_container!(&mut inner, |c| c.push_default());
28				DataBitVec::push(&mut bitvec, false);
29				*self = ColumnData::Option {
30					inner: Box::new(inner),
31					bitvec,
32				};
33			}
34		}
35	}
36}
37
38#[cfg(test)]
39pub mod tests {
40	use reifydb_runtime::context::{
41		clock::{Clock, MockClock},
42		rng::Rng,
43	};
44	use reifydb_type::value::{dictionary::DictionaryEntryId, identity::IdentityId, r#type::Type};
45
46	use crate::value::column::ColumnData;
47
48	fn test_clock_and_rng() -> (MockClock, Clock, Rng) {
49		let mock = MockClock::from_millis(1000);
50		let clock = Clock::Mock(mock.clone());
51		let rng = Rng::seeded(42);
52		(mock, clock, rng)
53	}
54
55	#[test]
56	fn test_bool() {
57		let mut col = ColumnData::bool(vec![true]);
58		col.push_none();
59		// push_none promotes a bare column to Option-wrapped
60		assert!(col.is_defined(0));
61		assert!(!col.is_defined(1));
62		assert_eq!(col.len(), 2);
63	}
64
65	#[test]
66	fn test_float4() {
67		let mut col = ColumnData::float4(vec![1.0]);
68		col.push_none();
69		assert!(col.is_defined(0));
70		assert!(!col.is_defined(1));
71		assert_eq!(col.len(), 2);
72	}
73
74	#[test]
75	fn test_float8() {
76		let mut col = ColumnData::float8(vec![1.0]);
77		col.push_none();
78		assert!(col.is_defined(0));
79		assert!(!col.is_defined(1));
80		assert_eq!(col.len(), 2);
81	}
82
83	#[test]
84	fn test_int1() {
85		let mut col = ColumnData::int1(vec![1]);
86		col.push_none();
87		assert!(col.is_defined(0));
88		assert!(!col.is_defined(1));
89		assert_eq!(col.len(), 2);
90	}
91
92	#[test]
93	fn test_int2() {
94		let mut col = ColumnData::int2(vec![1]);
95		col.push_none();
96		assert!(col.is_defined(0));
97		assert!(!col.is_defined(1));
98		assert_eq!(col.len(), 2);
99	}
100
101	#[test]
102	fn test_int4() {
103		let mut col = ColumnData::int4(vec![1]);
104		col.push_none();
105		assert!(col.is_defined(0));
106		assert!(!col.is_defined(1));
107		assert_eq!(col.len(), 2);
108	}
109
110	#[test]
111	fn test_int8() {
112		let mut col = ColumnData::int8(vec![1]);
113		col.push_none();
114		assert!(col.is_defined(0));
115		assert!(!col.is_defined(1));
116		assert_eq!(col.len(), 2);
117	}
118
119	#[test]
120	fn test_int16() {
121		let mut col = ColumnData::int16(vec![1]);
122		col.push_none();
123		assert!(col.is_defined(0));
124		assert!(!col.is_defined(1));
125		assert_eq!(col.len(), 2);
126	}
127
128	#[test]
129	fn test_string() {
130		let mut col = ColumnData::utf8(vec!["a"]);
131		col.push_none();
132		assert!(col.is_defined(0));
133		assert!(!col.is_defined(1));
134		assert_eq!(col.len(), 2);
135	}
136
137	#[test]
138	fn test_uint1() {
139		let mut col = ColumnData::uint1(vec![1]);
140		col.push_none();
141		assert!(col.is_defined(0));
142		assert!(!col.is_defined(1));
143		assert_eq!(col.len(), 2);
144	}
145
146	#[test]
147	fn test_uint2() {
148		let mut col = ColumnData::uint2(vec![1]);
149		col.push_none();
150		assert!(col.is_defined(0));
151		assert!(!col.is_defined(1));
152		assert_eq!(col.len(), 2);
153	}
154
155	#[test]
156	fn test_uint4() {
157		let mut col = ColumnData::uint4(vec![1]);
158		col.push_none();
159		assert!(col.is_defined(0));
160		assert!(!col.is_defined(1));
161		assert_eq!(col.len(), 2);
162	}
163
164	#[test]
165	fn test_uint8() {
166		let mut col = ColumnData::uint8(vec![1]);
167		col.push_none();
168		assert!(col.is_defined(0));
169		assert!(!col.is_defined(1));
170		assert_eq!(col.len(), 2);
171	}
172
173	#[test]
174	fn test_uint16() {
175		let mut col = ColumnData::uint16(vec![1]);
176		col.push_none();
177		assert!(col.is_defined(0));
178		assert!(!col.is_defined(1));
179		assert_eq!(col.len(), 2);
180	}
181
182	#[test]
183	fn test_identity_id() {
184		let (_, clock, rng) = test_clock_and_rng();
185		let mut col = ColumnData::identity_id(vec![IdentityId::generate(&clock, &rng)]);
186		col.push_none();
187		assert!(col.is_defined(0));
188		assert!(!col.is_defined(1));
189		assert_eq!(col.len(), 2);
190	}
191
192	#[test]
193	fn test_dictionary_id() {
194		let mut col = ColumnData::dictionary_id(vec![DictionaryEntryId::U4(10)]);
195		col.push_none();
196		assert!(col.is_defined(0));
197		assert!(!col.is_defined(1));
198		assert_eq!(col.len(), 2);
199	}
200
201	#[test]
202	fn test_none_on_option() {
203		let mut col = ColumnData::none_typed(Type::Boolean, 5);
204		col.push_none();
205		assert_eq!(col.len(), 6);
206		assert!(!col.is_defined(0));
207		assert!(!col.is_defined(5));
208	}
209}