@@ -32,21 +32,18 @@ use datafusion_expr::{Expr, LogicalPlanContext, ScanOrdering, SortExpr};
3232/// Optimization rule that pushes sort expressions down to table scans
3333/// when the sort can potentially be optimized by the table provider.
3434///
35- /// This rule looks for `Sort -> TableScan` patterns and moves the sort
36- /// expressions into the `TableScan.preferred_ordering` field, allowing
37- /// table providers to potentially optimize the scan based on sort requirements.
35+ /// This rule carries sort expressions down through nodes that we know are safe to push
36+ /// sorts though such as `Projection`, `Filter`, `Repartition` and `Limit`.
37+ /// It stops when it hits a `TableScan` (where it attaches the sort expressions to the scan)
38+ /// or any other node type that cannot pass down sort expressions (e.g. `Aggregate`, `Join`, `Union`, etc).
3839///
39- /// # Behavior
40- ///
41- /// The optimizer preserves the original `Sort` node as a fallback while passing
42- /// the ordering preference to the `TableScan` as an optimization hint. This ensures
43- /// correctness even if the table provider cannot satisfy the requested ordering.
44- ///
45- /// # Supported Sort Expressions
46- ///
47- /// Currently, only simple column references are supported for pushdown because
48- /// table providers typically cannot optimize complex expressions in sort operations.
49- /// Complex expressions like `col("a") + col("b")` or function calls are not pushed down.
40+ /// The optimizer preserves the original `Sort` node; this optimizer does not remove any sorts.
41+ /// This means that the [`TableProvider`] can choose to ignore the preferred ordering
42+ /// or only partially satisfy it. The original `Sort` node ensures that the final output
43+ /// ordering is always correct.
44+ ///
45+ /// Physical optimizer rules can later remove redundant sorts if they can prove
46+ /// that the output is already sorted as required.
5047///
5148/// # Examples
5249///
@@ -56,8 +53,8 @@ use datafusion_expr::{Expr, LogicalPlanContext, ScanOrdering, SortExpr};
5653/// TableScan: test
5754///
5855/// After optimization:
59- /// Sort: test.a ASC NULLS LAST -- Preserved as fallback
60- /// TableScan: test -- Now includes preferred_ordering hint
56+ /// Sort: test.a ASC NULLS LAST
57+ /// TableScan: test preferred_ordering=[test.a ASC NULLS LAST]
6158/// ```
6259#[ derive( Default , Debug ) ]
6360pub struct PushDownSort { }
@@ -68,14 +65,6 @@ impl PushDownSort {
6865 /// # Returns
6966 ///
7067 /// A new `PushDownSort` optimizer rule that can be added to the optimization pipeline.
71- ///
72- /// # Examples
73- ///
74- /// ```rust
75- /// use datafusion_optimizer::push_down_sort::PushDownSort;
76- ///
77- /// let rule = PushDownSort::new();
78- /// ```
7968 pub fn new ( ) -> Self {
8069 Self { }
8170 }
0 commit comments