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 Clamp {
20 info: RoutineInfo,
21}
22
23impl Default for Clamp {
24 fn default() -> Self {
25 Self::new()
26 }
27}
28
29impl Clamp {
30 pub fn new() -> Self {
31 Self {
32 info: RoutineInfo::new("math::clamp"),
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::Float4 | Type::Float8 | Type::Decimal)
417 || matches!(right, Type::Float4 | Type::Float8 | Type::Decimal)
418 {
419 return Type::Decimal;
420 }
421 if left == Type::Int || right == Type::Int {
422 return Type::Int16;
423 }
424 if left == Type::Uint || right == Type::Uint {
425 if matches!(left, Type::Int1 | Type::Int2 | Type::Int4 | Type::Int8 | Type::Int16)
426 || matches!(right, Type::Int1 | Type::Int2 | Type::Int4 | Type::Int8 | Type::Int16)
427 {
428 return Type::Int16;
429 }
430 return Type::Uint16;
431 }
432 Type::promote(left, right)
433}
434
435fn promote_numeric_types(a: Type, b: Type, c: Type) -> Type {
436 promote_two(promote_two(a, b), c)
437}
438
439impl<'a> Routine<FunctionContext<'a>> for Clamp {
440 fn info(&self) -> &RoutineInfo {
441 &self.info
442 }
443
444 fn return_type(&self, input_types: &[Type]) -> Type {
445 if input_types.len() >= 3
446 && input_types[0].is_number()
447 && input_types[1].is_number()
448 && input_types[2].is_number()
449 {
450 promote_numeric_types(input_types[0].clone(), input_types[1].clone(), input_types[2].clone())
451 } else {
452 Type::Float8
453 }
454 }
455
456 fn execute(&self, ctx: &mut FunctionContext<'a>, args: &Columns) -> Result<Columns, RoutineError> {
457 if args.len() != 3 {
458 return Err(RoutineError::FunctionArityMismatch {
459 function: ctx.fragment.clone(),
460 expected: 3,
461 actual: args.len(),
462 });
463 }
464
465 let val_col = &args[0];
466 let min_col = &args[1];
467 let max_col = &args[2];
468
469 let (v_data, v_bv) = val_col.unwrap_option();
470 let (lo_data, lo_bv) = min_col.unwrap_option();
471 let (hi_data, hi_bv) = max_col.unwrap_option();
472 let row_count = v_data.len();
473
474 let result_data = match (v_data, lo_data, hi_data) {
475 (ColumnBuffer::Int1(v), ColumnBuffer::Int1(lo), ColumnBuffer::Int1(hi)) => {
476 let mut result = Vec::with_capacity(row_count);
477 let mut res_bitvec = Vec::with_capacity(row_count);
478 for i in 0..row_count {
479 match (v.get(i), lo.get(i), hi.get(i)) {
480 (Some(&val), Some(&min), Some(&max)) => {
481 result.push(val.clamp(min, max));
482 res_bitvec.push(true);
483 }
484 _ => {
485 result.push(0);
486 res_bitvec.push(false);
487 }
488 }
489 }
490 ColumnBuffer::int1_with_bitvec(result, res_bitvec)
491 }
492 (ColumnBuffer::Int2(v), ColumnBuffer::Int2(lo), ColumnBuffer::Int2(hi)) => {
493 let mut result = Vec::with_capacity(row_count);
494 let mut res_bitvec = Vec::with_capacity(row_count);
495 for i in 0..row_count {
496 match (v.get(i), lo.get(i), hi.get(i)) {
497 (Some(&val), Some(&min), Some(&max)) => {
498 result.push(val.clamp(min, max));
499 res_bitvec.push(true);
500 }
501 _ => {
502 result.push(0);
503 res_bitvec.push(false);
504 }
505 }
506 }
507 ColumnBuffer::int2_with_bitvec(result, res_bitvec)
508 }
509 (ColumnBuffer::Int4(v), ColumnBuffer::Int4(lo), ColumnBuffer::Int4(hi)) => {
510 let mut result = Vec::with_capacity(row_count);
511 let mut res_bitvec = Vec::with_capacity(row_count);
512 for i in 0..row_count {
513 match (v.get(i), lo.get(i), hi.get(i)) {
514 (Some(&val), Some(&min), Some(&max)) => {
515 result.push(val.clamp(min, max));
516 res_bitvec.push(true);
517 }
518 _ => {
519 result.push(0);
520 res_bitvec.push(false);
521 }
522 }
523 }
524 ColumnBuffer::int4_with_bitvec(result, res_bitvec)
525 }
526 (ColumnBuffer::Int8(v), ColumnBuffer::Int8(lo), ColumnBuffer::Int8(hi)) => {
527 let mut result = Vec::with_capacity(row_count);
528 let mut res_bitvec = Vec::with_capacity(row_count);
529 for i in 0..row_count {
530 match (v.get(i), lo.get(i), hi.get(i)) {
531 (Some(&val), Some(&min), Some(&max)) => {
532 result.push(val.clamp(min, max));
533 res_bitvec.push(true);
534 }
535 _ => {
536 result.push(0);
537 res_bitvec.push(false);
538 }
539 }
540 }
541 ColumnBuffer::int8_with_bitvec(result, res_bitvec)
542 }
543 (ColumnBuffer::Int16(v), ColumnBuffer::Int16(lo), ColumnBuffer::Int16(hi)) => {
544 let mut result = Vec::with_capacity(row_count);
545 let mut res_bitvec = Vec::with_capacity(row_count);
546 for i in 0..row_count {
547 match (v.get(i), lo.get(i), hi.get(i)) {
548 (Some(&val), Some(&min), Some(&max)) => {
549 result.push(val.clamp(min, max));
550 res_bitvec.push(true);
551 }
552 _ => {
553 result.push(0);
554 res_bitvec.push(false);
555 }
556 }
557 }
558 ColumnBuffer::int16_with_bitvec(result, res_bitvec)
559 }
560 (ColumnBuffer::Uint1(v), ColumnBuffer::Uint1(lo), ColumnBuffer::Uint1(hi)) => {
561 let mut result = Vec::with_capacity(row_count);
562 let mut res_bitvec = Vec::with_capacity(row_count);
563 for i in 0..row_count {
564 match (v.get(i), lo.get(i), hi.get(i)) {
565 (Some(&val), Some(&min), Some(&max)) => {
566 result.push(val.clamp(min, max));
567 res_bitvec.push(true);
568 }
569 _ => {
570 result.push(0);
571 res_bitvec.push(false);
572 }
573 }
574 }
575 ColumnBuffer::uint1_with_bitvec(result, res_bitvec)
576 }
577 (ColumnBuffer::Uint2(v), ColumnBuffer::Uint2(lo), ColumnBuffer::Uint2(hi)) => {
578 let mut result = Vec::with_capacity(row_count);
579 let mut res_bitvec = Vec::with_capacity(row_count);
580 for i in 0..row_count {
581 match (v.get(i), lo.get(i), hi.get(i)) {
582 (Some(&val), Some(&min), Some(&max)) => {
583 result.push(val.clamp(min, max));
584 res_bitvec.push(true);
585 }
586 _ => {
587 result.push(0);
588 res_bitvec.push(false);
589 }
590 }
591 }
592 ColumnBuffer::uint2_with_bitvec(result, res_bitvec)
593 }
594 (ColumnBuffer::Uint4(v), ColumnBuffer::Uint4(lo), ColumnBuffer::Uint4(hi)) => {
595 let mut result = Vec::with_capacity(row_count);
596 let mut res_bitvec = Vec::with_capacity(row_count);
597 for i in 0..row_count {
598 match (v.get(i), lo.get(i), hi.get(i)) {
599 (Some(&val), Some(&min), Some(&max)) => {
600 result.push(val.clamp(min, max));
601 res_bitvec.push(true);
602 }
603 _ => {
604 result.push(0);
605 res_bitvec.push(false);
606 }
607 }
608 }
609 ColumnBuffer::uint4_with_bitvec(result, res_bitvec)
610 }
611 (ColumnBuffer::Uint8(v), ColumnBuffer::Uint8(lo), ColumnBuffer::Uint8(hi)) => {
612 let mut result = Vec::with_capacity(row_count);
613 let mut res_bitvec = Vec::with_capacity(row_count);
614 for i in 0..row_count {
615 match (v.get(i), lo.get(i), hi.get(i)) {
616 (Some(&val), Some(&min), Some(&max)) => {
617 result.push(val.clamp(min, max));
618 res_bitvec.push(true);
619 }
620 _ => {
621 result.push(0);
622 res_bitvec.push(false);
623 }
624 }
625 }
626 ColumnBuffer::uint8_with_bitvec(result, res_bitvec)
627 }
628 (ColumnBuffer::Uint16(v), ColumnBuffer::Uint16(lo), ColumnBuffer::Uint16(hi)) => {
629 let mut result = Vec::with_capacity(row_count);
630 let mut res_bitvec = Vec::with_capacity(row_count);
631 for i in 0..row_count {
632 match (v.get(i), lo.get(i), hi.get(i)) {
633 (Some(&val), Some(&min), Some(&max)) => {
634 result.push(val.clamp(min, max));
635 res_bitvec.push(true);
636 }
637 _ => {
638 result.push(0);
639 res_bitvec.push(false);
640 }
641 }
642 }
643 ColumnBuffer::uint16_with_bitvec(result, res_bitvec)
644 }
645 (ColumnBuffer::Float4(v), ColumnBuffer::Float4(lo), ColumnBuffer::Float4(hi)) => {
646 let mut result = Vec::with_capacity(row_count);
647 let mut res_bitvec = Vec::with_capacity(row_count);
648 for i in 0..row_count {
649 match (v.get(i), lo.get(i), hi.get(i)) {
650 (Some(&val), Some(&min), Some(&max)) => {
651 result.push(val.clamp(min, max));
652 res_bitvec.push(true);
653 }
654 _ => {
655 result.push(0.0);
656 res_bitvec.push(false);
657 }
658 }
659 }
660 ColumnBuffer::float4_with_bitvec(result, res_bitvec)
661 }
662 (ColumnBuffer::Float8(v), ColumnBuffer::Float8(lo), ColumnBuffer::Float8(hi)) => {
663 let mut result = Vec::with_capacity(row_count);
664 let mut res_bitvec = Vec::with_capacity(row_count);
665 for i in 0..row_count {
666 match (v.get(i), lo.get(i), hi.get(i)) {
667 (Some(&val), Some(&min), Some(&max)) => {
668 result.push(val.clamp(min, max));
669 res_bitvec.push(true);
670 }
671 _ => {
672 result.push(0.0);
673 res_bitvec.push(false);
674 }
675 }
676 }
677 ColumnBuffer::float8_with_bitvec(result, res_bitvec)
678 }
679 (
680 ColumnBuffer::Int {
681 container: v_container,
682 max_bytes,
683 },
684 ColumnBuffer::Int {
685 container: lo_container,
686 ..
687 },
688 ColumnBuffer::Int {
689 container: hi_container,
690 ..
691 },
692 ) => {
693 let mut result = Vec::with_capacity(row_count);
694 let mut res_bitvec = Vec::with_capacity(row_count);
695 for i in 0..row_count {
696 match (v_container.get(i), lo_container.get(i), hi_container.get(i)) {
697 (Some(val), Some(lo), Some(hi)) => {
698 let v = val.0.to_f64().unwrap_or(0.0);
699 let l = lo.0.to_f64().unwrap_or(0.0);
700 let h = hi.0.to_f64().unwrap_or(0.0);
701 result.push(Int::from(v.clamp(l, h) as i64));
702 res_bitvec.push(true);
703 }
704 _ => {
705 result.push(Int::default());
706 res_bitvec.push(false);
707 }
708 }
709 }
710 ColumnBuffer::Int {
711 container: NumberContainer::new(result),
712 max_bytes: *max_bytes,
713 }
714 }
715 (
716 ColumnBuffer::Uint {
717 container: v_container,
718 max_bytes,
719 },
720 ColumnBuffer::Uint {
721 container: lo_container,
722 ..
723 },
724 ColumnBuffer::Uint {
725 container: hi_container,
726 ..
727 },
728 ) => {
729 let mut result = Vec::with_capacity(row_count);
730 let mut res_bitvec = Vec::with_capacity(row_count);
731 for i in 0..row_count {
732 match (v_container.get(i), lo_container.get(i), hi_container.get(i)) {
733 (Some(val), Some(lo), Some(hi)) => {
734 let v = val.0.to_f64().unwrap_or(0.0);
735 let l = lo.0.to_f64().unwrap_or(0.0);
736 let h = hi.0.to_f64().unwrap_or(0.0);
737 result.push(Uint::from(v.clamp(l, h) as u64));
738 res_bitvec.push(true);
739 }
740 _ => {
741 result.push(Uint::default());
742 res_bitvec.push(false);
743 }
744 }
745 }
746 ColumnBuffer::Uint {
747 container: NumberContainer::new(result),
748 max_bytes: *max_bytes,
749 }
750 }
751 (
752 ColumnBuffer::Decimal {
753 container: v_container,
754 precision,
755 scale,
756 },
757 ColumnBuffer::Decimal {
758 container: lo_container,
759 ..
760 },
761 ColumnBuffer::Decimal {
762 container: hi_container,
763 ..
764 },
765 ) => {
766 let mut result = Vec::with_capacity(row_count);
767 let mut res_bitvec = Vec::with_capacity(row_count);
768 for i in 0..row_count {
769 match (v_container.get(i), lo_container.get(i), hi_container.get(i)) {
770 (Some(val), Some(lo), Some(hi)) => {
771 let v = val.0.to_f64().unwrap_or(0.0);
772 let l = lo.0.to_f64().unwrap_or(0.0);
773 let h = hi.0.to_f64().unwrap_or(0.0);
774 result.push(Decimal::from(v.clamp(l, h)));
775 res_bitvec.push(true);
776 }
777 _ => {
778 result.push(Decimal::default());
779 res_bitvec.push(false);
780 }
781 }
782 }
783 ColumnBuffer::Decimal {
784 container: NumberContainer::new(result),
785 precision: *precision,
786 scale: *scale,
787 }
788 }
789 _ => {
791 let v_type = v_data.get_type();
792 let lo_type = lo_data.get_type();
793 let hi_type = hi_data.get_type();
794
795 if !v_type.is_number() {
796 return Err(RoutineError::FunctionInvalidArgumentType {
797 function: ctx.fragment.clone(),
798 argument_index: 0,
799 expected: InputTypes::numeric().expected_at(0).to_vec(),
800 actual: v_type,
801 });
802 }
803 if !lo_type.is_number() {
804 return Err(RoutineError::FunctionInvalidArgumentType {
805 function: ctx.fragment.clone(),
806 argument_index: 1,
807 expected: InputTypes::numeric().expected_at(0).to_vec(),
808 actual: lo_type,
809 });
810 }
811 if !hi_type.is_number() {
812 return Err(RoutineError::FunctionInvalidArgumentType {
813 function: ctx.fragment.clone(),
814 argument_index: 2,
815 expected: InputTypes::numeric().expected_at(0).to_vec(),
816 actual: hi_type,
817 });
818 }
819
820 let promoted = promote_numeric_types(v_type, lo_type, hi_type);
821 let pv = convert_column_to_type(v_data, promoted.clone(), row_count);
822 let plo = convert_column_to_type(lo_data, promoted.clone(), row_count);
823 let phi = convert_column_to_type(hi_data, promoted, row_count);
824
825 let val_col = ColumnWithName::new(Fragment::internal("val"), pv);
826 let min_col = ColumnWithName::new(Fragment::internal("min"), plo);
827 let max_col = ColumnWithName::new(Fragment::internal("max"), phi);
828 let promoted_columns = Columns::new(vec![val_col, min_col, max_col]);
829
830 return self.call(ctx, &promoted_columns);
831 }
832 };
833
834 let combined_bitvec = match (v_bv, lo_bv, hi_bv) {
835 (Some(v), Some(lo), Some(hi)) => Some(v.and(lo).and(hi)),
836 (Some(v), Some(lo), None) => Some(v.and(lo)),
837 (Some(v), None, Some(hi)) => Some(v.and(hi)),
838 (None, Some(lo), Some(hi)) => Some(lo.and(hi)),
839 (Some(v), None, None) => Some(v.clone()),
840 (None, Some(lo), None) => Some(lo.clone()),
841 (None, None, Some(hi)) => Some(hi.clone()),
842 (None, None, None) => None,
843 };
844
845 let final_data = if let Some(bv) = combined_bitvec {
846 ColumnBuffer::Option {
847 inner: Box::new(result_data),
848 bitvec: bv,
849 }
850 } else {
851 result_data
852 };
853
854 Ok(Columns::new(vec![ColumnWithName::new(ctx.fragment.clone(), final_data)]))
855 }
856}
857
858impl Function for Clamp {
859 fn kinds(&self) -> &[FunctionKind] {
860 &[FunctionKind::Scalar]
861 }
862}