1use 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}