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