Attempts the scalar-needle fast path for `array_position`.
(args: &[ColumnarValue])
| 138 | |
| 139 | /// Attempts the scalar-needle fast path for `array_position`. |
| 140 | fn try_array_position_scalar(args: &[ColumnarValue]) -> Result<Option<ColumnarValue>> { |
| 141 | if args.len() < 2 || args.len() > 3 { |
| 142 | return exec_err!("array_position expects two or three arguments"); |
| 143 | } |
| 144 | |
| 145 | // Fallback to the generic code path if the needle is an array |
| 146 | let scalar_needle = match &args[1] { |
| 147 | ColumnarValue::Scalar(s) => s, |
| 148 | ColumnarValue::Array(_) => return Ok(None), |
| 149 | }; |
| 150 | |
| 151 | // `not_distinct` doesn't support nested types (List, Struct, etc.), |
| 152 | // so fall back to the generic code path for those. |
| 153 | if scalar_needle.data_type().is_nested() { |
| 154 | return Ok(None); |
| 155 | } |
| 156 | |
| 157 | // Determine batch length from whichever argument is columnar; |
| 158 | // if all inputs are scalar, batch length is 1. |
| 159 | let (num_rows, all_inputs_scalar) = match (&args[0], args.get(2)) { |
| 160 | (ColumnarValue::Array(a), _) => (a.len(), false), |
| 161 | (_, Some(ColumnarValue::Array(a))) => (a.len(), false), |
| 162 | _ => (1, true), |
| 163 | }; |
| 164 | |
| 165 | let needle = scalar_needle.to_array_of_size(1)?; |
| 166 | let haystack = args[0].to_array(num_rows)?; |
| 167 | let arr_from = resolve_start_from(args.get(2), num_rows)?; |
| 168 | |
| 169 | let result = match haystack.data_type() { |
| 170 | List(_) => { |
| 171 | let list = as_list_array(&haystack)?; |
| 172 | array_position_scalar::<i32>(list, &needle, &arr_from) |
| 173 | } |
| 174 | LargeList(_) => { |
| 175 | let list = as_large_list_array(&haystack)?; |
| 176 | array_position_scalar::<i64>(list, &needle, &arr_from) |
| 177 | } |
| 178 | t => exec_err!("array_position does not support type '{t}'"), |
| 179 | }?; |
| 180 | |
| 181 | if all_inputs_scalar { |
| 182 | Ok(Some(ColumnarValue::Scalar(ScalarValue::try_from_array( |
| 183 | &result, 0, |
| 184 | )?))) |
| 185 | } else { |
| 186 | Ok(Some(ColumnarValue::Array(result))) |
| 187 | } |
| 188 | } |
| 189 | |
| 190 | fn array_position_inner(args: &[ArrayRef]) -> Result<ArrayRef> { |
| 191 | if args.len() < 2 || args.len() > 3 { |
no test coverage detected
searching dependent graphs…