Execute in-memory sort operation
(
&self,
sort_expressions: &[SortItem],
mut input_rows: Vec<Row>,
context: &ExecutionContext,
)
| 6697 | |
| 6698 | /// Execute in-memory sort operation |
| 6699 | fn execute_in_memory_sort( |
| 6700 | &self, |
| 6701 | sort_expressions: &[SortItem], |
| 6702 | mut input_rows: Vec<Row>, |
| 6703 | context: &ExecutionContext, |
| 6704 | ) -> Result<Vec<Row>, ExecutionError> { |
| 6705 | // Sort the rows based on the sort expressions |
| 6706 | input_rows.sort_by(|a, b| { |
| 6707 | for sort_item in sort_expressions { |
| 6708 | // Pre-extract PropertyAccess once per sort item (not per row value) |
| 6709 | let prop_access = match &sort_item.expression { |
| 6710 | Expression::PropertyAccess(p) => Some(p), |
| 6711 | _ => None, |
| 6712 | }; |
| 6713 | |
| 6714 | let val_a = self.eval_order_by_expression( |
| 6715 | &sort_item.expression, |
| 6716 | &a.values, |
| 6717 | context, |
| 6718 | prop_access, |
| 6719 | ); |
| 6720 | let val_b = self.eval_order_by_expression( |
| 6721 | &sort_item.expression, |
| 6722 | &b.values, |
| 6723 | context, |
| 6724 | prop_access, |
| 6725 | ); |
| 6726 | |
| 6727 | match (val_a, val_b) { |
| 6728 | (Ok(a_val), Ok(b_val)) => { |
| 6729 | let cmp = self.compare_values(&a_val, &b_val, sort_item.nulls_first); |
| 6730 | match cmp { |
| 6731 | Some(std::cmp::Ordering::Equal) => continue, // Try next sort key |
| 6732 | Some(ordering) => { |
| 6733 | return if sort_item.ascending { |
| 6734 | ordering |
| 6735 | } else { |
| 6736 | ordering.reverse() |
| 6737 | }; |
| 6738 | } |
| 6739 | None => continue, // Values not comparable, try next sort key |
| 6740 | } |
| 6741 | } |
| 6742 | _ => continue, // Error evaluating, try next sort key |
| 6743 | } |
| 6744 | } |
| 6745 | std::cmp::Ordering::Equal // All sort keys were equal or failed |
| 6746 | }); |
| 6747 | |
| 6748 | Ok(input_rows) |
| 6749 | } |
| 6750 | |
| 6751 | /// Compare two values for sorting with NULLS ordering support |
| 6752 | fn compare_values( |
no test coverage detected