Skip to main content

reifydb_routine/function/math/
power.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4use num_traits::ToPrimitive;
5use reifydb_core::value::column::{ColumnWithName, buffer::ColumnBuffer, columns::Columns};
6use reifydb_type::{
7	fragment::Fragment,
8	value::{
9		container::number::NumberContainer,
10		decimal::Decimal,
11		int::Int,
12		r#type::{Type, input_types::InputTypes},
13		uint::Uint,
14	},
15};
16
17use crate::routine::{Function, FunctionKind, Routine, RoutineInfo, context::FunctionContext, error::RoutineError};
18
19pub struct Power {
20	info: RoutineInfo,
21}
22
23impl Default for Power {
24	fn default() -> Self {
25		Self::new()
26	}
27}
28
29impl Power {
30	pub fn new() -> Self {
31		Self {
32			info: RoutineInfo::new("math::power"),
33		}
34	}
35}
36
37fn convert_column_to_type(data: &ColumnBuffer, target: Type, row_count: usize) -> ColumnBuffer {
38	match target {
39		Type::Int1 => {
40			let mut result = Vec::with_capacity(row_count);
41			let mut bitvec = Vec::with_capacity(row_count);
42			for i in 0..row_count {
43				if data.is_defined(i) {
44					result.push(get_as_i8(data, i));
45					bitvec.push(true);
46				} else {
47					result.push(0);
48					bitvec.push(false);
49				}
50			}
51			ColumnBuffer::int1_with_bitvec(result, bitvec)
52		}
53		Type::Int2 => {
54			let mut result = Vec::with_capacity(row_count);
55			let mut bitvec = Vec::with_capacity(row_count);
56			for i in 0..row_count {
57				if data.is_defined(i) {
58					result.push(get_as_i16(data, i));
59					bitvec.push(true);
60				} else {
61					result.push(0);
62					bitvec.push(false);
63				}
64			}
65			ColumnBuffer::int2_with_bitvec(result, bitvec)
66		}
67		Type::Int4 => {
68			let mut result = Vec::with_capacity(row_count);
69			let mut bitvec = Vec::with_capacity(row_count);
70			for i in 0..row_count {
71				if data.is_defined(i) {
72					result.push(get_as_i32(data, i));
73					bitvec.push(true);
74				} else {
75					result.push(0);
76					bitvec.push(false);
77				}
78			}
79			ColumnBuffer::int4_with_bitvec(result, bitvec)
80		}
81		Type::Int8 => {
82			let mut result = Vec::with_capacity(row_count);
83			let mut bitvec = Vec::with_capacity(row_count);
84			for i in 0..row_count {
85				if data.is_defined(i) {
86					result.push(get_as_i64(data, i));
87					bitvec.push(true);
88				} else {
89					result.push(0);
90					bitvec.push(false);
91				}
92			}
93			ColumnBuffer::int8_with_bitvec(result, bitvec)
94		}
95		Type::Int16 => {
96			let mut result = Vec::with_capacity(row_count);
97			let mut bitvec = Vec::with_capacity(row_count);
98			for i in 0..row_count {
99				if data.is_defined(i) {
100					result.push(get_as_i128(data, i));
101					bitvec.push(true);
102				} else {
103					result.push(0);
104					bitvec.push(false);
105				}
106			}
107			ColumnBuffer::int16_with_bitvec(result, bitvec)
108		}
109		Type::Uint1 => {
110			let mut result = Vec::with_capacity(row_count);
111			let mut bitvec = Vec::with_capacity(row_count);
112			for i in 0..row_count {
113				if data.is_defined(i) {
114					result.push(get_as_u8(data, i));
115					bitvec.push(true);
116				} else {
117					result.push(0);
118					bitvec.push(false);
119				}
120			}
121			ColumnBuffer::uint1_with_bitvec(result, bitvec)
122		}
123		Type::Uint2 => {
124			let mut result = Vec::with_capacity(row_count);
125			let mut bitvec = Vec::with_capacity(row_count);
126			for i in 0..row_count {
127				if data.is_defined(i) {
128					result.push(get_as_u16(data, i));
129					bitvec.push(true);
130				} else {
131					result.push(0);
132					bitvec.push(false);
133				}
134			}
135			ColumnBuffer::uint2_with_bitvec(result, bitvec)
136		}
137		Type::Uint4 => {
138			let mut result = Vec::with_capacity(row_count);
139			let mut bitvec = Vec::with_capacity(row_count);
140			for i in 0..row_count {
141				if data.is_defined(i) {
142					result.push(get_as_u32(data, i));
143					bitvec.push(true);
144				} else {
145					result.push(0);
146					bitvec.push(false);
147				}
148			}
149			ColumnBuffer::uint4_with_bitvec(result, bitvec)
150		}
151		Type::Uint8 => {
152			let mut result = Vec::with_capacity(row_count);
153			let mut bitvec = Vec::with_capacity(row_count);
154			for i in 0..row_count {
155				if data.is_defined(i) {
156					result.push(get_as_u64(data, i));
157					bitvec.push(true);
158				} else {
159					result.push(0);
160					bitvec.push(false);
161				}
162			}
163			ColumnBuffer::uint8_with_bitvec(result, bitvec)
164		}
165		Type::Uint16 => {
166			let mut result = Vec::with_capacity(row_count);
167			let mut bitvec = Vec::with_capacity(row_count);
168			for i in 0..row_count {
169				if data.is_defined(i) {
170					result.push(get_as_u128(data, i));
171					bitvec.push(true);
172				} else {
173					result.push(0);
174					bitvec.push(false);
175				}
176			}
177			ColumnBuffer::uint16_with_bitvec(result, bitvec)
178		}
179		Type::Float4 => {
180			let mut result = Vec::with_capacity(row_count);
181			let mut bitvec = Vec::with_capacity(row_count);
182			for i in 0..row_count {
183				if data.is_defined(i) {
184					result.push(get_as_f32(data, i));
185					bitvec.push(true);
186				} else {
187					result.push(0.0);
188					bitvec.push(false);
189				}
190			}
191			ColumnBuffer::float4_with_bitvec(result, bitvec)
192		}
193		Type::Float8 => {
194			let mut result = Vec::with_capacity(row_count);
195			let mut bitvec = Vec::with_capacity(row_count);
196			for i in 0..row_count {
197				if data.is_defined(i) {
198					result.push(get_as_f64(data, i));
199					bitvec.push(true);
200				} else {
201					result.push(0.0);
202					bitvec.push(false);
203				}
204			}
205			ColumnBuffer::float8_with_bitvec(result, bitvec)
206		}
207		Type::Int => {
208			let mut result = Vec::with_capacity(row_count);
209			let mut bitvec = Vec::with_capacity(row_count);
210			for i in 0..row_count {
211				if data.is_defined(i) {
212					result.push(Int::from(get_as_i128(data, i)));
213					bitvec.push(true);
214				} else {
215					result.push(Int::default());
216					bitvec.push(false);
217				}
218			}
219			ColumnBuffer::int_with_bitvec(result, bitvec)
220		}
221		Type::Uint => {
222			let mut result = Vec::with_capacity(row_count);
223			let mut bitvec = Vec::with_capacity(row_count);
224			for i in 0..row_count {
225				if data.is_defined(i) {
226					result.push(Uint::from(get_as_u128(data, i)));
227					bitvec.push(true);
228				} else {
229					result.push(Uint::default());
230					bitvec.push(false);
231				}
232			}
233			ColumnBuffer::uint_with_bitvec(result, bitvec)
234		}
235		Type::Decimal => {
236			let mut result = Vec::with_capacity(row_count);
237			let mut bitvec = Vec::with_capacity(row_count);
238			for i in 0..row_count {
239				if data.is_defined(i) {
240					result.push(Decimal::from(get_as_f64(data, i)));
241					bitvec.push(true);
242				} else {
243					result.push(Decimal::default());
244					bitvec.push(false);
245				}
246			}
247			ColumnBuffer::decimal_with_bitvec(result, bitvec)
248		}
249		_ => data.clone(),
250	}
251}
252
253fn get_as_i8(data: &ColumnBuffer, i: usize) -> i8 {
254	match data {
255		ColumnBuffer::Int1(c) => c.get(i).copied().unwrap_or(0),
256		ColumnBuffer::Uint1(c) => c.get(i).map(|&v| v as i8).unwrap_or(0),
257		_ => 0,
258	}
259}
260
261fn get_as_u8(data: &ColumnBuffer, i: usize) -> u8 {
262	match data {
263		ColumnBuffer::Uint1(c) => c.get(i).copied().unwrap_or(0),
264		ColumnBuffer::Int1(c) => c.get(i).map(|&v| v as u8).unwrap_or(0),
265		_ => 0,
266	}
267}
268
269fn get_as_i16(data: &ColumnBuffer, i: usize) -> i16 {
270	match data {
271		ColumnBuffer::Int1(c) => c.get(i).map(|&v| v as i16).unwrap_or(0),
272		ColumnBuffer::Int2(c) => c.get(i).copied().unwrap_or(0),
273		ColumnBuffer::Uint1(c) => c.get(i).map(|&v| v as i16).unwrap_or(0),
274		_ => 0,
275	}
276}
277
278fn get_as_i32(data: &ColumnBuffer, i: usize) -> i32 {
279	match data {
280		ColumnBuffer::Int1(c) => c.get(i).map(|&v| v as i32).unwrap_or(0),
281		ColumnBuffer::Int2(c) => c.get(i).map(|&v| v as i32).unwrap_or(0),
282		ColumnBuffer::Int4(c) => c.get(i).copied().unwrap_or(0),
283		ColumnBuffer::Uint1(c) => c.get(i).map(|&v| v as i32).unwrap_or(0),
284		ColumnBuffer::Uint2(c) => c.get(i).map(|&v| v as i32).unwrap_or(0),
285		_ => 0,
286	}
287}
288
289fn get_as_i64(data: &ColumnBuffer, i: usize) -> i64 {
290	match data {
291		ColumnBuffer::Int1(c) => c.get(i).map(|&v| v as i64).unwrap_or(0),
292		ColumnBuffer::Int2(c) => c.get(i).map(|&v| v as i64).unwrap_or(0),
293		ColumnBuffer::Int4(c) => c.get(i).map(|&v| v as i64).unwrap_or(0),
294		ColumnBuffer::Int8(c) => c.get(i).copied().unwrap_or(0),
295		ColumnBuffer::Uint1(c) => c.get(i).map(|&v| v as i64).unwrap_or(0),
296		ColumnBuffer::Uint2(c) => c.get(i).map(|&v| v as i64).unwrap_or(0),
297		ColumnBuffer::Uint4(c) => c.get(i).map(|&v| v as i64).unwrap_or(0),
298		_ => 0,
299	}
300}
301
302fn get_as_i128(data: &ColumnBuffer, i: usize) -> i128 {
303	match data {
304		ColumnBuffer::Int1(c) => c.get(i).map(|&v| v as i128).unwrap_or(0),
305		ColumnBuffer::Int2(c) => c.get(i).map(|&v| v as i128).unwrap_or(0),
306		ColumnBuffer::Int4(c) => c.get(i).map(|&v| v as i128).unwrap_or(0),
307		ColumnBuffer::Int8(c) => c.get(i).map(|&v| v as i128).unwrap_or(0),
308		ColumnBuffer::Int16(c) => c.get(i).copied().unwrap_or(0),
309		ColumnBuffer::Uint1(c) => c.get(i).map(|&v| v as i128).unwrap_or(0),
310		ColumnBuffer::Uint2(c) => c.get(i).map(|&v| v as i128).unwrap_or(0),
311		ColumnBuffer::Uint4(c) => c.get(i).map(|&v| v as i128).unwrap_or(0),
312		ColumnBuffer::Uint8(c) => c.get(i).map(|&v| v as i128).unwrap_or(0),
313		_ => 0,
314	}
315}
316
317fn get_as_u16(data: &ColumnBuffer, i: usize) -> u16 {
318	match data {
319		ColumnBuffer::Uint1(c) => c.get(i).map(|&v| v as u16).unwrap_or(0),
320		ColumnBuffer::Uint2(c) => c.get(i).copied().unwrap_or(0),
321		_ => 0,
322	}
323}
324
325fn get_as_u32(data: &ColumnBuffer, i: usize) -> u32 {
326	match data {
327		ColumnBuffer::Uint1(c) => c.get(i).map(|&v| v as u32).unwrap_or(0),
328		ColumnBuffer::Uint2(c) => c.get(i).map(|&v| v as u32).unwrap_or(0),
329		ColumnBuffer::Uint4(c) => c.get(i).copied().unwrap_or(0),
330		_ => 0,
331	}
332}
333
334fn get_as_u64(data: &ColumnBuffer, i: usize) -> u64 {
335	match data {
336		ColumnBuffer::Uint1(c) => c.get(i).map(|&v| v as u64).unwrap_or(0),
337		ColumnBuffer::Uint2(c) => c.get(i).map(|&v| v as u64).unwrap_or(0),
338		ColumnBuffer::Uint4(c) => c.get(i).map(|&v| v as u64).unwrap_or(0),
339		ColumnBuffer::Uint8(c) => c.get(i).copied().unwrap_or(0),
340		_ => 0,
341	}
342}
343
344fn get_as_u128(data: &ColumnBuffer, i: usize) -> u128 {
345	match data {
346		ColumnBuffer::Uint1(c) => c.get(i).map(|&v| v as u128).unwrap_or(0),
347		ColumnBuffer::Uint2(c) => c.get(i).map(|&v| v as u128).unwrap_or(0),
348		ColumnBuffer::Uint4(c) => c.get(i).map(|&v| v as u128).unwrap_or(0),
349		ColumnBuffer::Uint8(c) => c.get(i).map(|&v| v as u128).unwrap_or(0),
350		ColumnBuffer::Uint16(c) => c.get(i).copied().unwrap_or(0),
351		_ => 0,
352	}
353}
354
355fn get_as_f32(data: &ColumnBuffer, i: usize) -> f32 {
356	match data {
357		ColumnBuffer::Int1(c) => c.get(i).map(|&v| v as f32).unwrap_or(0.0),
358		ColumnBuffer::Int2(c) => c.get(i).map(|&v| v as f32).unwrap_or(0.0),
359		ColumnBuffer::Int4(c) => c.get(i).map(|&v| v as f32).unwrap_or(0.0),
360		ColumnBuffer::Int8(c) => c.get(i).map(|&v| v as f32).unwrap_or(0.0),
361		ColumnBuffer::Int16(c) => c.get(i).map(|&v| v as f32).unwrap_or(0.0),
362		ColumnBuffer::Uint1(c) => c.get(i).map(|&v| v as f32).unwrap_or(0.0),
363		ColumnBuffer::Uint2(c) => c.get(i).map(|&v| v as f32).unwrap_or(0.0),
364		ColumnBuffer::Uint4(c) => c.get(i).map(|&v| v as f32).unwrap_or(0.0),
365		ColumnBuffer::Uint8(c) => c.get(i).map(|&v| v as f32).unwrap_or(0.0),
366		ColumnBuffer::Uint16(c) => c.get(i).map(|&v| v as f32).unwrap_or(0.0),
367		ColumnBuffer::Float4(c) => c.get(i).copied().unwrap_or(0.0),
368		ColumnBuffer::Float8(c) => c.get(i).map(|&v| v as f32).unwrap_or(0.0),
369		ColumnBuffer::Int {
370			container,
371			..
372		} => container.get(i).map(|v| v.0.to_f32().unwrap_or(0.0)).unwrap_or(0.0),
373		ColumnBuffer::Uint {
374			container,
375			..
376		} => container.get(i).map(|v| v.0.to_f32().unwrap_or(0.0)).unwrap_or(0.0),
377		ColumnBuffer::Decimal {
378			container,
379			..
380		} => container.get(i).map(|v| v.0.to_f32().unwrap_or(0.0)).unwrap_or(0.0),
381		_ => 0.0,
382	}
383}
384
385fn get_as_f64(data: &ColumnBuffer, i: usize) -> f64 {
386	match data {
387		ColumnBuffer::Int1(c) => c.get(i).map(|&v| v as f64).unwrap_or(0.0),
388		ColumnBuffer::Int2(c) => c.get(i).map(|&v| v as f64).unwrap_or(0.0),
389		ColumnBuffer::Int4(c) => c.get(i).map(|&v| v as f64).unwrap_or(0.0),
390		ColumnBuffer::Int8(c) => c.get(i).map(|&v| v as f64).unwrap_or(0.0),
391		ColumnBuffer::Int16(c) => c.get(i).map(|&v| v as f64).unwrap_or(0.0),
392		ColumnBuffer::Uint1(c) => c.get(i).map(|&v| v as f64).unwrap_or(0.0),
393		ColumnBuffer::Uint2(c) => c.get(i).map(|&v| v as f64).unwrap_or(0.0),
394		ColumnBuffer::Uint4(c) => c.get(i).map(|&v| v as f64).unwrap_or(0.0),
395		ColumnBuffer::Uint8(c) => c.get(i).map(|&v| v as f64).unwrap_or(0.0),
396		ColumnBuffer::Uint16(c) => c.get(i).map(|&v| v as f64).unwrap_or(0.0),
397		ColumnBuffer::Float4(c) => c.get(i).map(|&v| v as f64).unwrap_or(0.0),
398		ColumnBuffer::Float8(c) => c.get(i).copied().unwrap_or(0.0),
399		ColumnBuffer::Int {
400			container,
401			..
402		} => container.get(i).map(|v| v.0.to_f64().unwrap_or(0.0)).unwrap_or(0.0),
403		ColumnBuffer::Uint {
404			container,
405			..
406		} => container.get(i).map(|v| v.0.to_f64().unwrap_or(0.0)).unwrap_or(0.0),
407		ColumnBuffer::Decimal {
408			container,
409			..
410		} => container.get(i).map(|v| v.0.to_f64().unwrap_or(0.0)).unwrap_or(0.0),
411		_ => 0.0,
412	}
413}
414
415fn promote_two(left: Type, right: Type) -> Type {
416	if matches!(left, Type::Any) && matches!(right, Type::Any) {
417		return Type::Any;
418	}
419	if matches!(left, Type::Any) && right.is_number() {
420		return right;
421	}
422	if left.is_number() && matches!(right, Type::Any) {
423		return left;
424	}
425	if matches!(left, Type::Float4 | Type::Float8 | Type::Decimal)
426		|| matches!(right, Type::Float4 | Type::Float8 | Type::Decimal)
427	{
428		return Type::Decimal;
429	}
430	if left == Type::Int || right == Type::Int {
431		return Type::Int16;
432	}
433	if left == Type::Uint || right == Type::Uint {
434		if matches!(left, Type::Int1 | Type::Int2 | Type::Int4 | Type::Int8 | Type::Int16)
435			|| matches!(right, Type::Int1 | Type::Int2 | Type::Int4 | Type::Int8 | Type::Int16)
436		{
437			return Type::Int16;
438		}
439		return Type::Uint16;
440	}
441	Type::promote(left, right)
442}
443
444impl<'a> Routine<FunctionContext<'a>> for Power {
445	fn info(&self) -> &RoutineInfo {
446		&self.info
447	}
448
449	fn return_type(&self, input_types: &[Type]) -> Type {
450		if input_types.len() >= 2 {
451			promote_two(input_types[0].clone(), input_types[1].clone())
452		} else {
453			Type::Float8
454		}
455	}
456
457	fn execute(&self, ctx: &mut FunctionContext<'a>, args: &Columns) -> Result<Columns, RoutineError> {
458		if args.len() != 2 {
459			return Err(RoutineError::FunctionArityMismatch {
460				function: ctx.fragment.clone(),
461				expected: 2,
462				actual: args.len(),
463			});
464		}
465
466		let base_column = &args[0];
467		let exponent_column = &args[1];
468
469		let (base_data, base_bv) = base_column.unwrap_option();
470		let (exp_data, exp_bv) = exponent_column.unwrap_option();
471		let row_count = base_data.len();
472
473		let result_data = match (base_data, exp_data) {
474			(ColumnBuffer::Int1(base), ColumnBuffer::Int1(exp)) => {
475				let mut result = Vec::with_capacity(row_count);
476				let mut res_bitvec = Vec::with_capacity(row_count);
477				for i in 0..row_count {
478					match (base.get(i), exp.get(i)) {
479						(Some(&b), Some(&e)) => {
480							result.push(if e < 0 {
481								0
482							} else {
483								(b as i32).pow(e as u32)
484							});
485							res_bitvec.push(true);
486						}
487						_ => {
488							result.push(0);
489							res_bitvec.push(false);
490						}
491					}
492				}
493				ColumnBuffer::int4_with_bitvec(result, res_bitvec)
494			}
495			(ColumnBuffer::Int2(base), ColumnBuffer::Int2(exp)) => {
496				let mut result = Vec::with_capacity(row_count);
497				let mut res_bitvec = Vec::with_capacity(row_count);
498				for i in 0..row_count {
499					match (base.get(i), exp.get(i)) {
500						(Some(&b), Some(&e)) => {
501							result.push(if e < 0 {
502								0
503							} else {
504								(b as i32).pow(e as u32)
505							});
506							res_bitvec.push(true);
507						}
508						_ => {
509							result.push(0);
510							res_bitvec.push(false);
511						}
512					}
513				}
514				ColumnBuffer::int4_with_bitvec(result, res_bitvec)
515			}
516			(ColumnBuffer::Int4(base), ColumnBuffer::Int4(exp)) => {
517				let mut result = Vec::with_capacity(row_count);
518				let mut res_bitvec = Vec::with_capacity(row_count);
519				for i in 0..row_count {
520					match (base.get(i), exp.get(i)) {
521						(Some(&b), Some(&e)) => {
522							result.push(if e < 0 {
523								0
524							} else {
525								b.saturating_pow(e as u32)
526							});
527							res_bitvec.push(true);
528						}
529						_ => {
530							result.push(0);
531							res_bitvec.push(false);
532						}
533					}
534				}
535				ColumnBuffer::int4_with_bitvec(result, res_bitvec)
536			}
537			(ColumnBuffer::Int8(base), ColumnBuffer::Int8(exp)) => {
538				let mut result = Vec::with_capacity(row_count);
539				let mut res_bitvec = Vec::with_capacity(row_count);
540				for i in 0..row_count {
541					match (base.get(i), exp.get(i)) {
542						(Some(&b), Some(&e)) => {
543							result.push(if e < 0 {
544								0
545							} else {
546								b.saturating_pow(e as u32)
547							});
548							res_bitvec.push(true);
549						}
550						_ => {
551							result.push(0);
552							res_bitvec.push(false);
553						}
554					}
555				}
556				ColumnBuffer::int8_with_bitvec(result, res_bitvec)
557			}
558			(ColumnBuffer::Int16(base), ColumnBuffer::Int16(exp)) => {
559				let mut result = Vec::with_capacity(row_count);
560				let mut res_bitvec = Vec::with_capacity(row_count);
561				for i in 0..row_count {
562					match (base.get(i), exp.get(i)) {
563						(Some(&b), Some(&e)) => {
564							result.push(if e < 0 {
565								0
566							} else {
567								b.saturating_pow(e as u32)
568							});
569							res_bitvec.push(true);
570						}
571						_ => {
572							result.push(0);
573							res_bitvec.push(false);
574						}
575					}
576				}
577				ColumnBuffer::int16_with_bitvec(result, res_bitvec)
578			}
579			(ColumnBuffer::Float4(base), ColumnBuffer::Float4(exp)) => {
580				let mut result = Vec::with_capacity(row_count);
581				let mut res_bitvec = Vec::with_capacity(row_count);
582				for i in 0..row_count {
583					match (base.get(i), exp.get(i)) {
584						(Some(&b), Some(&e)) => {
585							result.push(b.powf(e));
586							res_bitvec.push(true);
587						}
588						_ => {
589							result.push(0.0);
590							res_bitvec.push(false);
591						}
592					}
593				}
594				ColumnBuffer::float4_with_bitvec(result, res_bitvec)
595			}
596			(ColumnBuffer::Float8(base), ColumnBuffer::Float8(exp)) => {
597				let mut result = Vec::with_capacity(row_count);
598				let mut res_bitvec = Vec::with_capacity(row_count);
599				for i in 0..row_count {
600					match (base.get(i), exp.get(i)) {
601						(Some(&b), Some(&e)) => {
602							result.push(b.powf(e));
603							res_bitvec.push(true);
604						}
605						_ => {
606							result.push(0.0);
607							res_bitvec.push(false);
608						}
609					}
610				}
611				ColumnBuffer::float8_with_bitvec(result, res_bitvec)
612			}
613			(ColumnBuffer::Uint1(base), ColumnBuffer::Uint1(exp)) => {
614				let mut result = Vec::with_capacity(row_count);
615				let mut res_bitvec = Vec::with_capacity(row_count);
616				for i in 0..row_count {
617					match (base.get(i), exp.get(i)) {
618						(Some(&b), Some(&e)) => {
619							result.push((b as u32).saturating_pow(e as u32));
620							res_bitvec.push(true);
621						}
622						_ => {
623							result.push(0);
624							res_bitvec.push(false);
625						}
626					}
627				}
628				ColumnBuffer::uint4_with_bitvec(result, res_bitvec)
629			}
630			(ColumnBuffer::Uint2(base), ColumnBuffer::Uint2(exp)) => {
631				let mut result = Vec::with_capacity(row_count);
632				let mut res_bitvec = Vec::with_capacity(row_count);
633				for i in 0..row_count {
634					match (base.get(i), exp.get(i)) {
635						(Some(&b), Some(&e)) => {
636							result.push((b as u32).saturating_pow(e as u32));
637							res_bitvec.push(true);
638						}
639						_ => {
640							result.push(0);
641							res_bitvec.push(false);
642						}
643					}
644				}
645				ColumnBuffer::uint4_with_bitvec(result, res_bitvec)
646			}
647			(ColumnBuffer::Uint4(base), ColumnBuffer::Uint4(exp)) => {
648				let mut result = Vec::with_capacity(row_count);
649				let mut res_bitvec = Vec::with_capacity(row_count);
650				for i in 0..row_count {
651					match (base.get(i), exp.get(i)) {
652						(Some(&b), Some(&e)) => {
653							result.push(b.saturating_pow(e));
654							res_bitvec.push(true);
655						}
656						_ => {
657							result.push(0);
658							res_bitvec.push(false);
659						}
660					}
661				}
662				ColumnBuffer::uint4_with_bitvec(result, res_bitvec)
663			}
664			(ColumnBuffer::Uint8(base), ColumnBuffer::Uint8(exp)) => {
665				let mut result = Vec::with_capacity(row_count);
666				let mut res_bitvec = Vec::with_capacity(row_count);
667				for i in 0..row_count {
668					match (base.get(i), exp.get(i)) {
669						(Some(&b), Some(&e)) => {
670							result.push(b.saturating_pow(e as u32));
671							res_bitvec.push(true);
672						}
673						_ => {
674							result.push(0);
675							res_bitvec.push(false);
676						}
677					}
678				}
679				ColumnBuffer::uint8_with_bitvec(result, res_bitvec)
680			}
681			(ColumnBuffer::Uint16(base), ColumnBuffer::Uint16(exp)) => {
682				let mut result = Vec::with_capacity(row_count);
683				let mut res_bitvec = Vec::with_capacity(row_count);
684				for i in 0..row_count {
685					match (base.get(i), exp.get(i)) {
686						(Some(&b), Some(&e)) => {
687							result.push(b.saturating_pow(e as u32));
688							res_bitvec.push(true);
689						}
690						_ => {
691							result.push(0);
692							res_bitvec.push(false);
693						}
694					}
695				}
696				ColumnBuffer::uint16_with_bitvec(result, res_bitvec)
697			}
698			(
699				ColumnBuffer::Int {
700					container: base,
701					max_bytes,
702				},
703				ColumnBuffer::Int {
704					container: exp,
705					..
706				},
707			) => {
708				let mut result = Vec::with_capacity(row_count);
709				let mut res_bitvec = Vec::with_capacity(row_count);
710				for i in 0..row_count {
711					match (base.get(i), exp.get(i)) {
712						(Some(b), Some(e)) => {
713							let b_val = b.0.to_f64().unwrap_or(0.0);
714							let e_val = e.0.to_f64().unwrap_or(0.0);
715							result.push(Int::from(b_val.powf(e_val) as i64));
716							res_bitvec.push(true);
717						}
718						_ => {
719							result.push(Int::default());
720							res_bitvec.push(false);
721						}
722					}
723				}
724				ColumnBuffer::Int {
725					container: NumberContainer::new(result),
726					max_bytes: *max_bytes,
727				}
728			}
729			(
730				ColumnBuffer::Uint {
731					container: base,
732					max_bytes,
733				},
734				ColumnBuffer::Uint {
735					container: exp,
736					..
737				},
738			) => {
739				let mut result = Vec::with_capacity(row_count);
740				let mut res_bitvec = Vec::with_capacity(row_count);
741				for i in 0..row_count {
742					match (base.get(i), exp.get(i)) {
743						(Some(b), Some(e)) => {
744							let b_val = b.0.to_f64().unwrap_or(0.0);
745							let e_val = e.0.to_f64().unwrap_or(0.0);
746							result.push(Uint::from(b_val.powf(e_val) as u64));
747							res_bitvec.push(true);
748						}
749						_ => {
750							result.push(Uint::default());
751							res_bitvec.push(false);
752						}
753					}
754				}
755				ColumnBuffer::Uint {
756					container: NumberContainer::new(result),
757					max_bytes: *max_bytes,
758				}
759			}
760			(
761				ColumnBuffer::Decimal {
762					container: base,
763					precision,
764					scale,
765				},
766				ColumnBuffer::Decimal {
767					container: exp,
768					..
769				},
770			) => {
771				let mut result = Vec::with_capacity(row_count);
772				let mut res_bitvec = Vec::with_capacity(row_count);
773				for i in 0..row_count {
774					match (base.get(i), exp.get(i)) {
775						(Some(b), Some(e)) => {
776							let b_val = b.0.to_f64().unwrap_or(0.0);
777							let e_val = e.0.to_f64().unwrap_or(0.0);
778							result.push(Decimal::from(b_val.powf(e_val)));
779							res_bitvec.push(true);
780						}
781						_ => {
782							result.push(Decimal::default());
783							res_bitvec.push(false);
784						}
785					}
786				}
787				ColumnBuffer::Decimal {
788					container: NumberContainer::new(result),
789					precision: *precision,
790					scale: *scale,
791				}
792			}
793
794			_ => {
795				let base_type = base_data.get_type();
796				let exp_type = exp_data.get_type();
797
798				if !base_type.is_number() || !exp_type.is_number() {
799					return Err(RoutineError::FunctionInvalidArgumentType {
800						function: ctx.fragment.clone(),
801						argument_index: 0,
802						expected: InputTypes::numeric().expected_at(0).to_vec(),
803						actual: base_type,
804					});
805				}
806
807				let promoted_type = promote_two(base_type, exp_type);
808				let promoted_base = convert_column_to_type(base_data, promoted_type.clone(), row_count);
809				let promoted_exp = convert_column_to_type(exp_data, promoted_type, row_count);
810
811				let base_col = ColumnWithName::new(Fragment::internal("base"), promoted_base);
812				let exp_col = ColumnWithName::new(Fragment::internal("exp"), promoted_exp);
813				let promoted_columns = Columns::new(vec![base_col, exp_col]);
814
815				return self.call(ctx, &promoted_columns);
816			}
817		};
818
819		let combined_bitvec = match (base_bv, exp_bv) {
820			(Some(b), Some(e)) => Some(b.and(e)),
821			(Some(b), None) => Some(b.clone()),
822			(None, Some(e)) => Some(e.clone()),
823			(None, None) => None,
824		};
825
826		let final_data = if let Some(bv) = combined_bitvec {
827			ColumnBuffer::Option {
828				inner: Box::new(result_data),
829				bitvec: bv,
830			}
831		} else {
832			result_data
833		};
834
835		Ok(Columns::new(vec![ColumnWithName::new(ctx.fragment.clone(), final_data)]))
836	}
837}
838
839impl Function for Power {
840	fn kinds(&self) -> &[FunctionKind] {
841		&[FunctionKind::Scalar]
842	}
843}