(
sort_order: &LexOrdering,
schema: &SchemaRef,
min_values: RecordBatch,
max_values: RecordBatch,
)
| 172 | |
| 173 | #[expect(clippy::needless_pass_by_value)] |
| 174 | pub fn new( |
| 175 | sort_order: &LexOrdering, |
| 176 | schema: &SchemaRef, |
| 177 | min_values: RecordBatch, |
| 178 | max_values: RecordBatch, |
| 179 | ) -> Result<Self> { |
| 180 | use arrow::row::*; |
| 181 | |
| 182 | let sort_fields = sort_order |
| 183 | .iter() |
| 184 | .map(|expr| { |
| 185 | expr.expr |
| 186 | .data_type(schema) |
| 187 | .map(|data_type| SortField::new_with_options(data_type, expr.options)) |
| 188 | }) |
| 189 | .collect::<Result<Vec<_>>>() |
| 190 | .map_err(|e| e.context("create sort fields"))?; |
| 191 | let converter = RowConverter::new(sort_fields)?; |
| 192 | |
| 193 | let Some(sort_columns) = sort_columns_from_physical_sort_exprs(sort_order) else { |
| 194 | return plan_err!("sort expression must be on column"); |
| 195 | }; |
| 196 | |
| 197 | // swap min/max if they're reversed in the ordering |
| 198 | let (new_min_cols, new_max_cols): (Vec<_>, Vec<_>) = sort_order |
| 199 | .iter() |
| 200 | .zip(sort_columns.iter().copied()) |
| 201 | .map(|(sort_expr, column)| { |
| 202 | let maxes = max_values.column_by_name(column.name()); |
| 203 | let mins = min_values.column_by_name(column.name()); |
| 204 | let opt_value = if sort_expr.options.descending { |
| 205 | maxes.zip(mins) |
| 206 | } else { |
| 207 | mins.zip(maxes) |
| 208 | }; |
| 209 | opt_value.ok_or_else(|| { |
| 210 | plan_datafusion_err!( |
| 211 | "missing column in MinMaxStatistics::new: '{}'", |
| 212 | column.name() |
| 213 | ) |
| 214 | }) |
| 215 | }) |
| 216 | .collect::<Result<Vec<_>>>()? |
| 217 | .into_iter() |
| 218 | .unzip(); |
| 219 | |
| 220 | let [min, max] = [new_min_cols, new_max_cols].map(|cols| { |
| 221 | let values = RecordBatch::try_new( |
| 222 | min_values.schema(), |
| 223 | cols.into_iter().cloned().collect(), |
| 224 | )?; |
| 225 | let sorting_columns = sort_order |
| 226 | .iter() |
| 227 | .zip(sort_columns.iter().copied()) |
| 228 | .map(|(sort_expr, column)| { |
| 229 | let schema = values.schema(); |
| 230 | let idx = schema.index_of(column.name())?; |
| 231 |
nothing calls this directly
no test coverage detected