| 125 | } |
| 126 | |
| 127 | fn simplify( |
| 128 | &self, |
| 129 | mut args: Vec<Expr>, |
| 130 | _info: &datafusion_expr::simplify::SimplifyContext, |
| 131 | ) -> Result<ExprSimplifyResult> { |
| 132 | let [haystack, needle] = take_function_args(self.name(), &mut args)?; |
| 133 | |
| 134 | // if the haystack is a constant list, we can use an inlist expression which is more |
| 135 | // efficient because the haystack is not varying per-row |
| 136 | match haystack { |
| 137 | Expr::Literal(scalar, _) if scalar.is_null() => { |
| 138 | return Ok(ExprSimplifyResult::Simplified(Expr::Literal( |
| 139 | ScalarValue::Boolean(None), |
| 140 | None, |
| 141 | ))); |
| 142 | } |
| 143 | Expr::Literal( |
| 144 | // FixedSizeList gets coerced to List |
| 145 | scalar @ ScalarValue::List(_) | scalar @ ScalarValue::LargeList(_), |
| 146 | _, |
| 147 | ) => { |
| 148 | if let Ok(scalar_values) = |
| 149 | ScalarValue::convert_array_to_scalar_vec(&scalar.to_array()?) |
| 150 | { |
| 151 | assert_eq!(scalar_values.len(), 1); |
| 152 | let list = scalar_values |
| 153 | .into_iter() |
| 154 | .flatten() |
| 155 | .flatten() |
| 156 | .map(|v| Expr::Literal(v, None)) |
| 157 | .collect(); |
| 158 | |
| 159 | return Ok(ExprSimplifyResult::Simplified(in_list( |
| 160 | std::mem::take(needle), |
| 161 | list, |
| 162 | false, |
| 163 | ))); |
| 164 | } |
| 165 | } |
| 166 | Expr::ScalarFunction(ScalarFunction { func, args }) |
| 167 | if func == &make_array_udf() => |
| 168 | { |
| 169 | // make_array has a static set of arguments, so we can pull the arguments out from it |
| 170 | return Ok(ExprSimplifyResult::Simplified(in_list( |
| 171 | std::mem::take(needle), |
| 172 | std::mem::take(args), |
| 173 | false, |
| 174 | ))); |
| 175 | } |
| 176 | _ => {} |
| 177 | }; |
| 178 | Ok(ExprSimplifyResult::Original(args)) |
| 179 | } |
| 180 | |
| 181 | fn invoke_with_args(&self, args: ScalarFunctionArgs) -> Result<ColumnarValue> { |
| 182 | let [first_arg, second_arg] = take_function_args(self.name(), &args.args)?; |