This function handles cases where an operation results in an overflow. Such results are converted to an *unbounded endpoint* if: - We are calculating an upper bound and we have a positive overflow. - We are calculating a lower bound and we have a negative overflow. Otherwise, the function sets the endpoint as: - The minimum representable number with the given datatype (`dt`) if we are calculating
(
dt: &DataType,
op: Operator,
lhs: &ScalarValue,
rhs: &ScalarValue,
)
| 1183 | /// interval library, and the following interval creation is standardized with |
| 1184 | /// `Interval::new`. |
| 1185 | fn handle_overflow<const UPPER: bool>( |
| 1186 | dt: &DataType, |
| 1187 | op: Operator, |
| 1188 | lhs: &ScalarValue, |
| 1189 | rhs: &ScalarValue, |
| 1190 | ) -> ScalarValue { |
| 1191 | let lhs_zero = ScalarValue::new_zero(&lhs.data_type()).unwrap(); |
| 1192 | let rhs_zero = ScalarValue::new_zero(&rhs.data_type()).unwrap(); |
| 1193 | let positive_sign = match op { |
| 1194 | Operator::Multiply | Operator::Divide => { |
| 1195 | lhs.lt(&lhs_zero) && rhs.lt(&rhs_zero) |
| 1196 | || lhs.gt(&lhs_zero) && rhs.gt(&rhs_zero) |
| 1197 | } |
| 1198 | Operator::Plus => lhs.ge(&lhs_zero), |
| 1199 | Operator::Minus => lhs.ge(rhs), |
| 1200 | _ => { |
| 1201 | unreachable!() |
| 1202 | } |
| 1203 | }; |
| 1204 | |
| 1205 | match (UPPER, positive_sign) { |
| 1206 | (true, true) | (false, false) => ScalarValue::try_from(dt).unwrap(), |
| 1207 | (true, false) => { |
| 1208 | get_extreme_value!( |
| 1209 | MIN, |
| 1210 | MIN_DECIMAL128_FOR_EACH_PRECISION, |
| 1211 | MIN_DECIMAL256_FOR_EACH_PRECISION, |
| 1212 | dt |
| 1213 | ) |
| 1214 | } |
| 1215 | (false, true) => { |
| 1216 | get_extreme_value!( |
| 1217 | MAX, |
| 1218 | MAX_DECIMAL128_FOR_EACH_PRECISION, |
| 1219 | MAX_DECIMAL256_FOR_EACH_PRECISION, |
| 1220 | dt |
| 1221 | ) |
| 1222 | } |
| 1223 | } |
| 1224 | } |
| 1225 | |
| 1226 | // This function should remain private since it may corrupt the an interval if |
| 1227 | // used without caution. |