reifydb_core/value/column/data/
extend.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 reifydb_type::{diagnostic::engine, return_error};
5
6use crate::value::{
7	column::ColumnData,
8	container::{BlobContainer, BoolContainer, NumberContainer, TemporalContainer, Utf8Container, UuidContainer},
9};
10
11impl ColumnData {
12	pub fn extend(&mut self, other: ColumnData) -> crate::Result<()> {
13		match (&mut *self, other) {
14			// Same type extensions - delegate to container extend
15			// method
16			(ColumnData::Bool(l), ColumnData::Bool(r)) => l.extend(&r)?,
17			(ColumnData::Float4(l), ColumnData::Float4(r)) => l.extend(&r)?,
18			(ColumnData::Float8(l), ColumnData::Float8(r)) => l.extend(&r)?,
19			(ColumnData::Int1(l), ColumnData::Int1(r)) => l.extend(&r)?,
20			(ColumnData::Int2(l), ColumnData::Int2(r)) => l.extend(&r)?,
21			(ColumnData::Int4(l), ColumnData::Int4(r)) => l.extend(&r)?,
22			(ColumnData::Int8(l), ColumnData::Int8(r)) => l.extend(&r)?,
23			(ColumnData::Int16(l), ColumnData::Int16(r)) => l.extend(&r)?,
24			(ColumnData::Uint1(l), ColumnData::Uint1(r)) => l.extend(&r)?,
25			(ColumnData::Uint2(l), ColumnData::Uint2(r)) => l.extend(&r)?,
26			(ColumnData::Uint4(l), ColumnData::Uint4(r)) => l.extend(&r)?,
27			(ColumnData::Uint8(l), ColumnData::Uint8(r)) => l.extend(&r)?,
28			(ColumnData::Uint16(l), ColumnData::Uint16(r)) => l.extend(&r)?,
29			(
30				ColumnData::Utf8 {
31					container: l,
32					..
33				},
34				ColumnData::Utf8 {
35					container: r,
36					..
37				},
38			) => l.extend(&r)?,
39			(ColumnData::Date(l), ColumnData::Date(r)) => l.extend(&r)?,
40			(ColumnData::DateTime(l), ColumnData::DateTime(r)) => l.extend(&r)?,
41			(ColumnData::Time(l), ColumnData::Time(r)) => l.extend(&r)?,
42			(ColumnData::Duration(l), ColumnData::Duration(r)) => l.extend(&r)?,
43			(ColumnData::RowNumber(l), ColumnData::RowNumber(r)) => l.extend(&r)?,
44			(ColumnData::IdentityId(l), ColumnData::IdentityId(r)) => l.extend(&r)?,
45			(ColumnData::Uuid4(l), ColumnData::Uuid4(r)) => l.extend(&r)?,
46			(ColumnData::Uuid7(l), ColumnData::Uuid7(r)) => l.extend(&r)?,
47			(
48				ColumnData::Blob {
49					container: l,
50					..
51				},
52				ColumnData::Blob {
53					container: r,
54					..
55				},
56			) => l.extend(&r)?,
57			(
58				ColumnData::Int {
59					container: l,
60					..
61				},
62				ColumnData::Int {
63					container: r,
64					..
65				},
66			) => l.extend(&r)?,
67			(
68				ColumnData::Uint {
69					container: l,
70					..
71				},
72				ColumnData::Uint {
73					container: r,
74					..
75				},
76			) => l.extend(&r)?,
77			(
78				ColumnData::Decimal {
79					container: l,
80					..
81				},
82				ColumnData::Decimal {
83					container: r,
84					..
85				},
86			) => l.extend(&r)?,
87			(ColumnData::Undefined(l), ColumnData::Undefined(r)) => l.extend(&r)?,
88
89			// Promote Undefined to typed
90			(ColumnData::Undefined(l_container), typed_r) => {
91				let l_len = l_container.len();
92				match typed_r {
93					ColumnData::Bool(r) => {
94						let mut new_container = BoolContainer::with_capacity(l_len + r.len());
95						new_container.extend_from_undefined(l_len);
96						new_container.extend(&r)?;
97						*self = ColumnData::Bool(new_container);
98					}
99					ColumnData::Float4(r) => {
100						let mut new_container = NumberContainer::with_capacity(l_len + r.len());
101						new_container.extend_from_undefined(l_len);
102						new_container.extend(&r)?;
103						*self = ColumnData::Float4(new_container);
104					}
105					ColumnData::Float8(r) => {
106						let mut new_container = NumberContainer::with_capacity(l_len + r.len());
107						new_container.extend_from_undefined(l_len);
108						new_container.extend(&r)?;
109						*self = ColumnData::Float8(new_container);
110					}
111					ColumnData::Int1(r) => {
112						let mut new_container = NumberContainer::with_capacity(l_len + r.len());
113						new_container.extend_from_undefined(l_len);
114						new_container.extend(&r)?;
115						*self = ColumnData::Int1(new_container);
116					}
117					ColumnData::Int2(r) => {
118						let mut new_container = NumberContainer::with_capacity(l_len + r.len());
119						new_container.extend_from_undefined(l_len);
120						new_container.extend(&r)?;
121						*self = ColumnData::Int2(new_container);
122					}
123					ColumnData::Int4(r) => {
124						let mut new_container = NumberContainer::with_capacity(l_len + r.len());
125						new_container.extend_from_undefined(l_len);
126						new_container.extend(&r)?;
127						*self = ColumnData::Int4(new_container);
128					}
129					ColumnData::Int8(r) => {
130						let mut new_container = NumberContainer::with_capacity(l_len + r.len());
131						new_container.extend_from_undefined(l_len);
132						new_container.extend(&r)?;
133						*self = ColumnData::Int8(new_container);
134					}
135					ColumnData::Int16(r) => {
136						let mut new_container = NumberContainer::with_capacity(l_len + r.len());
137						new_container.extend_from_undefined(l_len);
138						new_container.extend(&r)?;
139						*self = ColumnData::Int16(new_container);
140					}
141					ColumnData::Uint1(r) => {
142						let mut new_container = NumberContainer::with_capacity(l_len + r.len());
143						new_container.extend_from_undefined(l_len);
144						new_container.extend(&r)?;
145						*self = ColumnData::Uint1(new_container);
146					}
147					ColumnData::Uint2(r) => {
148						let mut new_container = NumberContainer::with_capacity(l_len + r.len());
149						new_container.extend_from_undefined(l_len);
150						new_container.extend(&r)?;
151						*self = ColumnData::Uint2(new_container);
152					}
153					ColumnData::Uint4(r) => {
154						let mut new_container = NumberContainer::with_capacity(l_len + r.len());
155						new_container.extend_from_undefined(l_len);
156						new_container.extend(&r)?;
157						*self = ColumnData::Uint4(new_container);
158					}
159					ColumnData::Uint8(r) => {
160						let mut new_container = NumberContainer::with_capacity(l_len + r.len());
161						new_container.extend_from_undefined(l_len);
162						new_container.extend(&r)?;
163						*self = ColumnData::Uint8(new_container);
164					}
165					ColumnData::Uint16(r) => {
166						let mut new_container = NumberContainer::with_capacity(l_len + r.len());
167						new_container.extend_from_undefined(l_len);
168						new_container.extend(&r)?;
169						*self = ColumnData::Uint16(new_container);
170					}
171					ColumnData::Utf8 {
172						container: r,
173						max_bytes,
174					} => {
175						let mut new_container = Utf8Container::with_capacity(l_len + r.len());
176						new_container.extend_from_undefined(l_len);
177						new_container.extend(&r)?;
178						*self = ColumnData::Utf8 {
179							container: new_container,
180							max_bytes,
181						};
182					}
183					ColumnData::Date(r) => {
184						let mut new_container =
185							TemporalContainer::with_capacity(l_len + r.len());
186						new_container.extend_from_undefined(l_len);
187						new_container.extend(&r)?;
188						*self = ColumnData::Date(new_container);
189					}
190					ColumnData::DateTime(r) => {
191						let mut new_container =
192							TemporalContainer::with_capacity(l_len + r.len());
193						new_container.extend_from_undefined(l_len);
194						new_container.extend(&r)?;
195						*self = ColumnData::DateTime(new_container);
196					}
197					ColumnData::Time(r) => {
198						let mut new_container =
199							TemporalContainer::with_capacity(l_len + r.len());
200						new_container.extend_from_undefined(l_len);
201						new_container.extend(&r)?;
202						*self = ColumnData::Time(new_container);
203					}
204					ColumnData::Duration(r) => {
205						let mut new_container =
206							TemporalContainer::with_capacity(l_len + r.len());
207						new_container.extend_from_undefined(l_len);
208						new_container.extend(&r)?;
209						*self = ColumnData::Duration(new_container);
210					}
211					ColumnData::Uuid4(r) => {
212						let mut new_container = UuidContainer::with_capacity(l_len + r.len());
213						new_container.extend_from_undefined(l_len);
214						new_container.extend(&r)?;
215						*self = ColumnData::Uuid4(new_container);
216					}
217					ColumnData::Uuid7(r) => {
218						let mut new_container = UuidContainer::with_capacity(l_len + r.len());
219						new_container.extend_from_undefined(l_len);
220						new_container.extend(&r)?;
221						*self = ColumnData::Uuid7(new_container);
222					}
223					ColumnData::Blob {
224						container: r,
225						max_bytes,
226					} => {
227						let mut new_container = BlobContainer::with_capacity(l_len + r.len());
228						new_container.extend_from_undefined(l_len);
229						new_container.extend(&r)?;
230						*self = ColumnData::Blob {
231							container: new_container,
232							max_bytes,
233						};
234					}
235					ColumnData::Int {
236						container: r,
237						max_bytes,
238					} => {
239						let mut new_container = NumberContainer::with_capacity(l_len + r.len());
240						new_container.extend_from_undefined(l_len);
241						new_container.extend(&r)?;
242						*self = ColumnData::Int {
243							container: new_container,
244							max_bytes,
245						};
246					}
247					ColumnData::Uint {
248						container: r,
249						max_bytes,
250					} => {
251						let mut new_container = NumberContainer::with_capacity(l_len + r.len());
252						new_container.extend_from_undefined(l_len);
253						new_container.extend(&r)?;
254						*self = ColumnData::Uint {
255							container: new_container,
256							max_bytes,
257						};
258					}
259					ColumnData::Decimal {
260						container: r,
261						precision,
262						scale,
263					} => {
264						let mut new_container = NumberContainer::with_capacity(l_len + r.len());
265						new_container.extend_from_undefined(l_len);
266						new_container.extend(&r)?;
267						*self = ColumnData::Decimal {
268							container: new_container,
269							precision,
270							scale,
271						};
272					}
273					ColumnData::RowNumber(_) => {
274						return_error!(engine::frame_error(
275							"Cannot extend RowNumber column from Undefined".to_string()
276						));
277					}
278					ColumnData::IdentityId(_) => {
279						return_error!(engine::frame_error(
280							"Cannot extend IdentityId column from Undefined".to_string()
281						));
282					}
283					ColumnData::Undefined(_) => {}
284					ColumnData::Any(_) => {
285						unreachable!("Any type not supported in extend operations");
286					}
287				}
288			}
289
290			// Extend typed with Undefined
291			(typed_l, ColumnData::Undefined(r_container)) => {
292				let r_len = r_container.len();
293				match typed_l {
294					ColumnData::Bool(l) => l.extend_from_undefined(r_len),
295					ColumnData::Float4(l) => l.extend_from_undefined(r_len),
296					ColumnData::Float8(l) => l.extend_from_undefined(r_len),
297					ColumnData::Int1(l) => l.extend_from_undefined(r_len),
298					ColumnData::Int2(l) => l.extend_from_undefined(r_len),
299					ColumnData::Int4(l) => l.extend_from_undefined(r_len),
300					ColumnData::Int8(l) => l.extend_from_undefined(r_len),
301					ColumnData::Int16(l) => l.extend_from_undefined(r_len),
302					ColumnData::Uint1(l) => l.extend_from_undefined(r_len),
303					ColumnData::Uint2(l) => l.extend_from_undefined(r_len),
304					ColumnData::Uint4(l) => l.extend_from_undefined(r_len),
305					ColumnData::Uint8(l) => l.extend_from_undefined(r_len),
306					ColumnData::Uint16(l) => l.extend_from_undefined(r_len),
307					ColumnData::Utf8 {
308						container: l,
309						..
310					} => l.extend_from_undefined(r_len),
311					ColumnData::Date(l) => l.extend_from_undefined(r_len),
312					ColumnData::DateTime(l) => l.extend_from_undefined(r_len),
313					ColumnData::Time(l) => l.extend_from_undefined(r_len),
314					ColumnData::Duration(l) => l.extend_from_undefined(r_len),
315					ColumnData::RowNumber(l) => l.extend_from_undefined(r_len),
316					ColumnData::IdentityId(l) => l.extend_from_undefined(r_len),
317					ColumnData::Uuid4(l) => l.extend_from_undefined(r_len),
318					ColumnData::Uuid7(l) => l.extend_from_undefined(r_len),
319					ColumnData::Blob {
320						container: l,
321						..
322					} => l.extend_from_undefined(r_len),
323					ColumnData::Int {
324						container: l,
325						..
326					} => l.extend_from_undefined(r_len),
327					ColumnData::Uint {
328						container: l,
329						..
330					} => l.extend_from_undefined(r_len),
331					ColumnData::Decimal {
332						container: l,
333						..
334					} => l.extend_from_undefined(r_len),
335					ColumnData::Undefined(_) => {
336						unreachable!()
337					}
338					&mut ColumnData::Any(_) => {
339						unreachable!("Any type not supported in extend operations");
340					}
341				}
342			}
343
344			// Type mismatch
345			(_, _) => {
346				return_error!(engine::frame_error("column type mismatch".to_string()));
347			}
348		}
349
350		Ok(())
351	}
352}