@@ -766,12 +766,14 @@ public RelNode visit(RelNode other) {
766766 RelNode visitedBarrier = super .visit (other );
767767 return LogicalSort .create (visitedBarrier , reversedCollation , null , null );
768768 }
769- // Found a collation Sort - insert reversed sort on top of it
769+ // Found a collation Sort - replace in-place with reversed collation.
770+ // Stacking a reversed sort on top would create consecutive sorts, and
771+ // Calcite's SortRemoveRule would merge them keeping the original direction.
770772 if (sort .getCollation () != null
771773 && !sort .getCollation ().getFieldCollations ().isEmpty ()) {
772774 sortFound = true ;
773- RelNode visitedSort = super . visit ( other );
774- return LogicalSort .create (visitedSort , reversedCollation , null , null );
775+ RelNode visitedInput = sort . getInput (). accept ( this );
776+ return LogicalSort .create (visitedInput , reversedCollation , null , null );
775777 }
776778 }
777779 // For all other nodes, continue traversal
@@ -801,8 +803,9 @@ public RelNode visitReverse(
801803 && existingSort .fetch == null
802804 && existingSort .offset == null ) {
803805 // Pure collation sort (no fetch/offset) - replace in-place to avoid consecutive
804- // sorts. Calcite's physical optimizer merges consecutive LogicalSort nodes and may
805- // discard the reversed direction. Replacing in-place avoids this issue.
806+ // sorts. Calcite's SortRemoveRule merges consecutive LogicalSort nodes and keeps
807+ // the lower sort's direction, which discards the reversed direction.
808+ // Replacing in-place avoids this issue.
806809 RelCollation reversedFromSort = PlanUtils .reverseCollation (existingSort .getCollation ());
807810 RelNode replacedSort =
808811 LogicalSort .create (existingSort .getInput (), reversedFromSort , null , null );
0 commit comments