reifydb_engine/function/math/scalar/
power.rs1use reifydb_core::value::column::ColumnData;
5
6use crate::function::{ScalarFunction, ScalarFunctionContext};
7
8pub struct Power;
9
10impl Power {
11 pub fn new() -> Self {
12 Self {}
13 }
14}
15
16impl ScalarFunction for Power {
17 fn scalar(&self, ctx: ScalarFunctionContext) -> crate::Result<ColumnData> {
18 let columns = ctx.columns;
19 let row_count = ctx.row_count;
20
21 if columns.len() < 2 {
22 return Ok(ColumnData::int4(Vec::<i32>::new()));
23 }
24
25 let base_column = columns.get(0).unwrap();
26 let exponent_column = columns.get(1).unwrap();
27
28 match (base_column.data(), exponent_column.data()) {
29 (ColumnData::Int1(base_container), ColumnData::Int1(exp_container)) => {
30 let mut result = Vec::with_capacity(row_count);
31
32 for row_idx in 0..row_count {
33 let base = base_container.get(row_idx);
34 let exp = exp_container.get(row_idx);
35
36 let power_result = match (base, exp) {
37 (Some(&base_val), Some(&exp_val)) => {
38 if exp_val < 0 {
39 0 } else {
41 (base_val as i32).pow(exp_val as u32)
42 }
43 }
44 _ => 0, };
46
47 result.push(power_result);
48 }
49
50 Ok(ColumnData::int4(result))
51 }
52 (ColumnData::Int2(base_container), ColumnData::Int2(exp_container)) => {
53 let mut result = Vec::with_capacity(row_count);
54
55 for row_idx in 0..row_count {
56 let base = base_container.get(row_idx);
57 let exp = exp_container.get(row_idx);
58
59 let power_result = match (base, exp) {
60 (Some(&base_val), Some(&exp_val)) => {
61 if exp_val < 0 {
62 0 } else {
64 (base_val as i32).pow(exp_val as u32)
65 }
66 }
67 _ => 0, };
69
70 result.push(power_result);
71 }
72
73 Ok(ColumnData::int4(result))
74 }
75 (ColumnData::Int4(base_container), ColumnData::Int4(exp_container)) => {
76 let mut result = Vec::with_capacity(row_count);
77
78 for row_idx in 0..row_count {
79 let base = base_container.get(row_idx);
80 let exp = exp_container.get(row_idx);
81
82 let power_result = match (base, exp) {
83 (Some(&base_val), Some(&exp_val)) => {
84 if exp_val < 0 {
85 0 } else {
87 base_val.saturating_pow(exp_val as u32)
88 }
89 }
90 _ => 0, };
92
93 result.push(power_result);
94 }
95
96 Ok(ColumnData::int4(result))
97 }
98 (ColumnData::Int8(base_container), ColumnData::Int8(exp_container)) => {
99 let mut result = Vec::with_capacity(row_count);
100
101 for row_idx in 0..row_count {
102 let base = base_container.get(row_idx);
103 let exp = exp_container.get(row_idx);
104
105 let power_result = match (base, exp) {
106 (Some(&base_val), Some(&exp_val)) => {
107 if exp_val < 0 {
108 0 } else {
110 base_val.saturating_pow(exp_val as u32)
111 }
112 }
113 _ => 0, };
115
116 result.push(power_result);
117 }
118
119 Ok(ColumnData::int8(result))
120 }
121 _ => unimplemented!("Power function currently supports matching integer types only"),
122 }
123 }
124}