Skip to content

Commit 0731b49

Browse files
committed
[SQL] Preserve incoming relations when deduplicating unions
1 parent 76997e0 commit 0731b49

2 files changed

Lines changed: 23 additions & 1 deletion

File tree

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,12 +243,20 @@ object DeduplicateRelations extends Rule[LogicalPlan] {
243243
private def deduplicate(
244244
existingRelations: ExprIdMap,
245245
plan: LogicalPlan): (LogicalPlan, Boolean) = {
246+
def copyExistingRelations(): ExprIdMap = {
247+
val copied = mutable.HashMap.empty[Class[_], mutable.HashSet[Long]]
248+
existingRelations.foreach { case (relationClass, exprIds) =>
249+
copied.put(relationClass, exprIds.clone())
250+
}
251+
copied
252+
}
253+
246254
var planChanged = false
247255
val newPlan = if (plan.children.nonEmpty) {
248256
val newChildren = mutable.ArrayBuffer.empty[LogicalPlan]
249257
for (c <- plan.children) {
250258
val relations = plan match {
251-
case _: Union => mutable.HashMap.empty[Class[_], mutable.HashSet[Long]]
259+
case _: Union => copyExistingRelations()
252260
case _ => existingRelations
253261
}
254262
val (renewed, changed) = renewDuplicatedRelations(relations, c)

sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/AnalysisSuite.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,20 @@ class AnalysisSuite extends AnalysisTest with Matchers {
728728
s"direct path allocated $directLarge bytes, fake self-join allocated $throughJoinLarge bytes")
729729
}
730730

731+
test("deduplicateRight renews union branches against the left side") {
732+
val conflicting = LocalRelation(AttributeReference("a", IntegerType)())
733+
val shared = LocalRelation(AttributeReference("b", IntegerType)())
734+
val right = Union(Seq(
735+
Join(conflicting, shared, Inner, None, JoinHint.NONE),
736+
Join(conflicting, shared, Inner, None, JoinHint.NONE)))
737+
738+
val result = DeduplicateRelations.deduplicateRight(conflicting, right).asInstanceOf[Union]
739+
val relations = result.children.map(_.collect { case r: LocalRelation => r })
740+
741+
assert(relations.forall(_.head.output != conflicting.output))
742+
assert(relations.flatMap(_(1).output).map(_.exprId).distinct.length == shared.output.length)
743+
}
744+
731745
test("resolve as with an already existed alias") {
732746
checkAnalysis(
733747
Project(Seq(UnresolvedAttribute("tbl2.a")),

0 commit comments

Comments
 (0)