| 399 | |
| 400 | #[sqlfunc] |
| 401 | fn array_position<'a>( |
| 402 | array: Array<'a>, |
| 403 | search: Datum<'a>, |
| 404 | initial_pos: OptionalArg<Option<i32>>, |
| 405 | ) -> Result<Option<i32>, EvalError> { |
| 406 | if array.dims().len() > 1 { |
| 407 | return Err(EvalError::MultiDimensionalArraySearch); |
| 408 | } |
| 409 | |
| 410 | if search == Datum::Null { |
| 411 | return Ok(None); |
| 412 | } |
| 413 | |
| 414 | let skip = match initial_pos.0 { |
| 415 | None => 0, |
| 416 | Some(None) => return Err(EvalError::MustNotBeNull("initial position".into())), |
| 417 | Some(Some(o)) => usize::try_from(o).unwrap_or(0).saturating_sub(1), |
| 418 | }; |
| 419 | |
| 420 | let Some(r) = array.elements().iter().skip(skip).position(|d| d == search) else { |
| 421 | return Ok(None); |
| 422 | }; |
| 423 | |
| 424 | // Adjust count for the amount we skipped, plus 1 for adjusting to PG indexing scheme. |
| 425 | let p = i32::try_from(r + skip + 1).expect("fewer than i32::MAX elements in array"); |
| 426 | Ok(Some(p)) |
| 427 | } |
| 428 | |
| 429 | #[derive( |
| 430 | Ord, |