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