Computes `rem(left, right)` with divide-by-zero handling. In ANSI mode, any zero divisor causes an error. In legacy mode (ANSI off), zero divisors are replaced with NULL before computing the remainder, so those positions return NULL while others compute normally.
(
left: &arrow::array::ArrayRef,
right: &arrow::array::ArrayRef,
enable_ansi_mode: bool,
)
| 34 | /// computing the remainder, so those positions return NULL while others |
| 35 | /// compute normally. |
| 36 | fn try_rem( |
| 37 | left: &arrow::array::ArrayRef, |
| 38 | right: &arrow::array::ArrayRef, |
| 39 | enable_ansi_mode: bool, |
| 40 | ) -> Result<arrow::array::ArrayRef> { |
| 41 | if enable_ansi_mode { |
| 42 | Ok(rem(left, right)?) |
| 43 | } else { |
| 44 | // In legacy mode, null out zero divisors so that division by zero |
| 45 | // returns NULL instead of erroring (integers) or returning NaN (floats). |
| 46 | let zero = ScalarValue::new_zero(right.data_type())?.to_array()?; |
| 47 | let zero = Scalar::new(zero); |
| 48 | let null = Scalar::new(new_null_array(right.data_type(), 1)); |
| 49 | let is_zero = eq(right, &zero)?; |
| 50 | let safe_right = zip(&is_zero, &null, right)?; |
| 51 | Ok(rem(left, &safe_right)?) |
| 52 | } |
| 53 | } |
| 54 | |
| 55 | /// Spark-compatible `mod` function |
| 56 | /// In ANSI mode, division by zero throws an error. |