Implements NULLIF(expr1, expr2) Args: 0 - left expr is any array 1 - if the left is equal to this expr2, then the result is NULL, otherwise left value is passed.
(args: &[ColumnarValue])
| 110 | /// Args: 0 - left expr is any array |
| 111 | /// 1 - if the left is equal to this expr2, then the result is NULL, otherwise left value is passed. |
| 112 | fn nullif_func(args: &[ColumnarValue]) -> Result<ColumnarValue> { |
| 113 | let [lhs, rhs] = take_function_args("nullif", args)?; |
| 114 | let is_nested = lhs.data_type().is_nested(); |
| 115 | |
| 116 | match (lhs, rhs) { |
| 117 | (ColumnarValue::Array(lhs), ColumnarValue::Scalar(rhs)) => { |
| 118 | let rhs = rhs.to_scalar()?; |
| 119 | let eq_array = compare_with_eq(lhs, &rhs, is_nested)?; |
| 120 | let array = nullif(lhs, &eq_array)?; |
| 121 | |
| 122 | Ok(ColumnarValue::Array(array)) |
| 123 | } |
| 124 | (ColumnarValue::Array(lhs), ColumnarValue::Array(rhs)) => { |
| 125 | let eq_array = compare_with_eq(lhs, rhs, is_nested)?; |
| 126 | let array = nullif(lhs, &eq_array)?; |
| 127 | Ok(ColumnarValue::Array(array)) |
| 128 | } |
| 129 | (ColumnarValue::Scalar(lhs), ColumnarValue::Array(rhs)) => { |
| 130 | let lhs_s = lhs.to_scalar()?; |
| 131 | let lhs_a = lhs.to_array_of_size(rhs.len())?; |
| 132 | let eq_array = compare_with_eq(&lhs_s, rhs, is_nested)?; |
| 133 | let array = nullif( |
| 134 | // nullif in arrow-select does not support Datum, so we need to convert to array |
| 135 | lhs_a.as_ref(), |
| 136 | &eq_array, |
| 137 | )?; |
| 138 | Ok(ColumnarValue::Array(array)) |
| 139 | } |
| 140 | (ColumnarValue::Scalar(lhs), ColumnarValue::Scalar(rhs)) => { |
| 141 | let val: ScalarValue = match lhs.eq(rhs) { |
| 142 | true => lhs.data_type().try_into()?, |
| 143 | false => lhs.clone(), |
| 144 | }; |
| 145 | |
| 146 | Ok(ColumnarValue::Scalar(val)) |
| 147 | } |
| 148 | } |
| 149 | } |
| 150 | |
| 151 | #[cfg(test)] |
| 152 | mod tests { |
searching dependent graphs…