Build a new tile carrying only the projected attribute columns. `proj` is validated against `tile.attr_cols.len()` (the tile's own attribute count, not a schema), so the operator is schema-free.
(tile: &SparseTile, proj: &Projection)
| 29 | /// `proj` is validated against `tile.attr_cols.len()` (the tile's own |
| 30 | /// attribute count, not a schema), so the operator is schema-free. |
| 31 | pub fn project_sparse(tile: &SparseTile, proj: &Projection) -> ArrayResult<SparseTile> { |
| 32 | for &i in &proj.attr_indices { |
| 33 | if i >= tile.attr_cols.len() { |
| 34 | return Err(ArrayError::InvalidAttr { |
| 35 | array: String::new(), |
| 36 | attr: format!("idx {i}"), |
| 37 | detail: format!("attr index out of range (have {})", tile.attr_cols.len()), |
| 38 | }); |
| 39 | } |
| 40 | } |
| 41 | let attr_cols = proj |
| 42 | .attr_indices |
| 43 | .iter() |
| 44 | .map(|&i| tile.attr_cols[i].clone()) |
| 45 | .collect(); |
| 46 | let attr_stats = proj |
| 47 | .attr_indices |
| 48 | .iter() |
| 49 | .map(|&i| tile.mbr.attr_stats[i].clone()) |
| 50 | .collect(); |
| 51 | let mut mbr = tile.mbr.clone(); |
| 52 | mbr.attr_stats = attr_stats; |
| 53 | Ok(SparseTile { |
| 54 | dim_dicts: tile.dim_dicts.clone(), |
| 55 | attr_cols, |
| 56 | surrogates: tile.surrogates.clone(), |
| 57 | valid_from_ms: tile.valid_from_ms.clone(), |
| 58 | valid_until_ms: tile.valid_until_ms.clone(), |
| 59 | row_kinds: tile.row_kinds.clone(), |
| 60 | mbr, |
| 61 | }) |
| 62 | } |
| 63 | |
| 64 | #[cfg(test)] |
| 65 | mod tests { |