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