MCPcopy Create free account
hub / github.com/MaterializeInc/materialize / array_index

Function array_index

src/expr/src/scalar/func/variadic.rs:357–398  ·  view source on GitHub ↗
(
    &self,
    array: Array<'a, T>,
    indices: Variadic<i64>,
)

Source from the content-addressed store, hash-verified

355}
356#[sqlfunc(ArrayIndex, sqlname = "array_index", introduces_nulls = true)]
357fn array_index<'a, T: FromDatum<'a>>(
358 &self,
359 array: Array<'a, T>,
360 indices: Variadic<i64>,
361) -> Option<T> {
362 mz_ore::soft_assert_no_log!(
363 self.offset == 0 || self.offset == 1,
364 "offset must be either 0 or 1"
365 );
366
367 let dims = array.dims();
368 if dims.len() != indices.len() {
369 // You missed the datums "layer"
370 return None;
371 }
372
373 let mut final_idx = 0;
374
375 for (d, idx) in dims.into_iter().zip_eq(indices.iter()) {
376 // Lower bound is written in terms of 1-based indexing, which offset accounts for.
377 let idx = isize::cast_from(*idx + self.offset);
378
379 let (lower, upper) = d.dimension_bounds();
380
381 // This index missed all of the data at this layer. The dimension bounds are inclusive,
382 // while range checks are exclusive, so adjust.
383 if !(lower..upper + 1).contains(&idx) {
384 return None;
385 }
386
387 // We discover how many indices our last index represents physically.
388 final_idx *= d.length;
389
390 // Because both index and lower bound are handled in 1-based indexing, taking their
391 // difference moves us back into 0-based indexing. Similarly, if the lower bound is
392 // negative, subtracting a negative value >= to itself ensures its non-negativity.
393 final_idx += usize::try_from(idx - d.lower_bound)
394 .expect("previous bounds check ensures physical index is at least 0");
395 }
396
397 array.elements().typed_iter().nth(final_idx)
398}
399
400#[sqlfunc]
401fn array_position<'a>(

Callers

nothing calls this directly

Calls 9

dimsMethod · 0.80
dimension_boundsMethod · 0.80
expectMethod · 0.80
typed_iterMethod · 0.80
elementsMethod · 0.80
lenMethod · 0.45
into_iterMethod · 0.45
iterMethod · 0.45
containsMethod · 0.45

Tested by

no test coverage detected