Skip to content

Commit 3245d28

Browse files
committed
minor improve
1 parent 465ee07 commit 3245d28

File tree

3 files changed

+22
-20
lines changed

3 files changed

+22
-20
lines changed

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ class Analyzer(
338338

339339
// When resolve `SortOrder`s in Sort based on child, don't report errors as
340340
// we still have chance to resolve it based on grandchild
341-
case s @ Sort(ordering, global, child) =>
341+
case s @ Sort(ordering, global, child) if child.resolved && !s.resolved =>
342342
val newOrdering = resolveSortOrders(ordering, child, throws = false)
343343
Sort(newOrdering, global, child)
344344

@@ -382,8 +382,9 @@ class Analyzer(
382382
private def resolveSortOrders(ordering: Seq[SortOrder], plan: LogicalPlan, throws: Boolean) = {
383383
ordering.map { order =>
384384
// Resolve SortOrder in one round.
385-
// if throws == false, fail and return the origin one.
386-
// else, throw exception.
385+
// If throws == false or the desired attribute doesn't exist
386+
// (like try to resolve `a.b` but `a` doesn't exist), fail and return the origin one.
387+
// Else, throw exception.
387388
try {
388389
val newOrder = order transformUp {
389390
case u @ UnresolvedAttribute(nameParts) =>
@@ -408,13 +409,13 @@ class Analyzer(
408409
def apply(plan: LogicalPlan): LogicalPlan = plan transformUp {
409410
case s @ Sort(ordering, global, p @ Project(projectList, child))
410411
if !s.resolved && p.resolved =>
411-
val (resolvedOrdering, missing) = resolveAndFindMissing(ordering, p, child)
412+
val (newOrdering, missing) = resolveAndFindMissing(ordering, p, child)
412413

413414
// If this rule was not a no-op, return the transformed plan, otherwise return the original.
414415
if (missing.nonEmpty) {
415416
// Add missing attributes and then project them away after the sort.
416417
Project(p.output,
417-
Sort(resolvedOrdering, global,
418+
Sort(newOrdering, global,
418419
Project(projectList ++ missing, child)))
419420
} else {
420421
logDebug(s"Failed to find $missing in ${p.output.mkString(", ")}")
@@ -429,35 +430,34 @@ class Analyzer(
429430
)
430431

431432
// Find sort attributes that are projected away so we can temporarily add them back in.
432-
val (resolvedOrdering, unresolved) = resolveAndFindMissing(ordering, a, groupingRelation)
433+
val (newOrdering, missingAttr) = resolveAndFindMissing(ordering, a, groupingRelation)
433434

434435
// Find aggregate expressions and evaluate them early, since they can't be evaluated in a
435436
// Sort.
436-
val (withAggsRemoved, aliasedAggregateList) = resolvedOrdering.map {
437+
val (withAggsRemoved, aliasedAggregateList) = newOrdering.filter(_.resolved).map {
437438
case aggOrdering if aggOrdering.collect { case a: AggregateExpression => a }.nonEmpty =>
438439
val aliased = Alias(aggOrdering.child, "_aggOrdering")()
439-
(aggOrdering.copy(child = aliased.toAttribute), aliased :: Nil)
440+
(aggOrdering.copy(child = aliased.toAttribute), Some(aliased))
440441

441-
case other => (other, Nil)
442+
case other => (other, None)
442443
}.unzip
443444

444-
val missing = unresolved ++ aliasedAggregateList.flatten
445+
val missing = missingAttr ++ aliasedAggregateList.flatten
445446

446447
if (missing.nonEmpty) {
447448
// Add missing grouping exprs and then project them away after the sort.
448449
Project(a.output,
449450
Sort(withAggsRemoved, global,
450451
Aggregate(grouping, aggs ++ missing, child)))
451452
} else {
452-
logDebug(s"Failed to find $missing in ${a.output.mkString(", ")}")
453453
s // Nothing we can do here. Return original plan.
454454
}
455455
}
456456

457457
/**
458-
* Given a child and a grandchild that are present beneath a sort operator, returns
459-
* a resolved sort ordering and a list of attributes that are missing from the child
460-
* but are present in the grandchild.
458+
* Given a child and a grandchild that are present beneath a sort operator, try to resolve
459+
* the sort ordering and returns it with a list of attributes that are missing from the
460+
* child but are present in the grandchild.
461461
*/
462462
def resolveAndFindMissing(
463463
ordering: Seq[SortOrder],

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/LogicalPlan.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,19 @@ abstract class LogicalPlan extends QueryPlan[LogicalPlan] with Logging {
5050
* [[org.apache.spark.sql.catalyst.analysis.UnresolvedRelation UnresolvedRelation]]
5151
* should return `false`).
5252
*/
53-
lazy val resolved: Boolean = !expressions.exists(!_.resolved) && childrenResolved
53+
lazy val resolved: Boolean = expressions.forall(_.resolved) && childrenResolved
5454

5555
override protected def statePrefix = if (!resolved) "'" else super.statePrefix
5656

5757
/**
5858
* Returns true if all its children of this query plan have been resolved.
5959
*/
60-
def childrenResolved: Boolean = !children.exists(!_.resolved)
60+
def childrenResolved: Boolean = children.forall(_.resolved)
6161

6262
/**
6363
* Returns true when the given logical plan will return the same results as this logical plan.
6464
*
65-
* Since its likely undecideable to generally determine if two given plans will produce the same
65+
* Since its likely undecidable to generally determine if two given plans will produce the same
6666
* results, it is okay for this function to return false, even if the results are actually
6767
* the same. Such behavior will not affect correctness, only the application of performance
6868
* enhancements like caching. However, it is not acceptable to return true if the results could

sql/core/src/test/scala/org/apache/spark/sql/SQLQuerySuite.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1432,8 +1432,10 @@ class SQLQuerySuite extends QueryTest with BeforeAndAfterAll with SQLTestUtils {
14321432
}
14331433

14341434
test("SPARK-7067: order by queries for complex ExtractValue chain") {
1435-
jsonRDD(sparkContext.makeRDD(
1436-
"""{"a": {"b": [{"c": 1}]}, "b": [{"d": 1}]}""" :: Nil)).registerTempTable("t")
1437-
checkAnswer(sql("SELECT a.b FROM t ORDER BY b[0].d"), Row(Seq(Row(1))))
1435+
withTable("t") {
1436+
read.json(sparkContext.makeRDD(
1437+
"""{"a": {"b": [{"c": 1}]}, "b": [{"d": 1}]}""" :: Nil)).registerTempTable("t")
1438+
checkAnswer(sql("SELECT a.b FROM t ORDER BY b[0].d"), Row(Seq(Row(1))))
1439+
}
14381440
}
14391441
}

0 commit comments

Comments
 (0)