Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@ object NormalizePlan extends PredicateHelper {
case project @ Project(_, innerAggregate: Aggregate) =>
project.copy(child = normalizeAggregateListOrder(innerAggregate))

case project @ Project(_, filter @ Filter(_, innerProject: Project)) =>
Copy link
Contributor

@cloud-fan cloud-fan Mar 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we make it more general? we can turn transformUpWithSubqueries into a manual top-down recursion. When we hit a project, we set a bool flag projectListOrderSensitive to false when invoking the recursive method, and we do not set projectListOrderSensitive back to true for a whitelist of plan nodes: Filter, Sample, Sort, etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about that. It's not just Filter, Sort, Sample and some small set of operators but all the operators that have override def output: Seq[Attribute] = child.output. I don't think that it's robust in a way that you can easily miss some and besides that if someone adds another operator there is 99% chance that they will forget to add it to the list. So I propose to go with this approach and think of a better solution in a background in order to avoid polluting NormalizePlan too much.

project.copy(child = filter.copy(child = normalizeProjectListOrder(innerProject)))

/**
* ORDER BY covered by an output-retaining project on top of GROUP BY
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,22 @@ class NormalizePlanSuite extends SparkFunSuite with SQLConfHelper {
assert(NormalizePlan(baselinePlan) == NormalizePlan(testPlan))
}

test("Normalize ordering in a project list of an inner Project under Project and Filter") {
val baselinePlan =
LocalRelation($"col1".int, $"col2".string)
.select($"col1", $"col2")
.where($"col1" === 1)
.select($"col1")
val testPlan =
LocalRelation($"col1".int, $"col2".string)
.select($"col2", $"col1")
.where($"col1" === 1)
.select($"col1")

assert(baselinePlan != testPlan)
assert(NormalizePlan(baselinePlan) == NormalizePlan(testPlan))
}

test("Normalize InheritAnalysisRules expressions") {
val castWithoutTimezone =
Cast(child = Literal(1), dataType = BooleanType, ansiEnabled = conf.ansiEnabled)
Expand Down