@@ -949,6 +949,24 @@ class Analyzer(
949949 }
950950 }
951951
952+ /**
953+ * Removes all still-need-evaluate ordering expressions from sort and use an inner project to
954+ * materialize them, finally use a outer project to project them away to keep the result same.
955+ * Then we can make sure we only sort by [[AttributeReference ]]s.
956+ *
957+ * As an example,
958+ * {{{
959+ * Sort('a, 'b + 1,
960+ * Relation('a, 'b))
961+ * }}}
962+ * will be turned into:
963+ * {{{
964+ * Project('a, 'b,
965+ * Sort('a, '_sortCondition,
966+ * Project('a, 'b, ('b + 1).as("_sortCondition"),
967+ * Relation('a, 'b))))
968+ * }}}
969+ */
952970 object RemoveEvaluationFromSort extends Rule [LogicalPlan ] {
953971 override def apply (plan : LogicalPlan ): LogicalPlan = plan transform {
954972 case s @ Sort (ordering, global, child)
@@ -958,13 +976,15 @@ class Analyzer(
958976
959977 val namedExpr = needEval.map(_.child match {
960978 case n : NamedExpression => n
961- case e => Alias (e, " sortCondition " )()
979+ case e => Alias (e, " _sortCondition " )()
962980 })
963981
964982 val newOrdering = ref ++ needEval.zip(namedExpr).map { case (order, ne) =>
965983 order.copy(child = ne.toAttribute)
966984 }
967985
986+ // Add still-need-evaluate ordering expressions into inner project and then project
987+ // them away after the sort.
968988 Project (child.output,
969989 Sort (newOrdering, global,
970990 Project (child.output ++ namedExpr, child)))
0 commit comments