diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/LogicalPlan.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/LogicalPlan.scala index ec9bf90247f88..39514ddaf4548 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/LogicalPlan.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/LogicalPlan.scala @@ -176,10 +176,16 @@ abstract class UnaryNode extends LogicalPlan { allConstraints += EqualNullSafe(a.toAttribute, l) case a @ Alias(e, _) => // For every alias in `projectList`, replace the reference in constraints by its attribute. - allConstraints ++= allConstraints.map(_ transform { - case expr: Expression if expr.semanticEquals(e) => - a.toAttribute - }) + allConstraints ++= allConstraints.map { + // To Avoid generating too many constraints, for example, + // SELECT a AS a1, b AS b1, ab AS ab1 FROM (SELECT a, b, a + b AS ab FROM tbl) t + // Avoid generating ((a#4 + b1#2) <=> ab#0) for ((a#4 + b#5) <=> ab#0). + case e @ EqualNullSafe(l, _: AttributeReference) if l.references.size > 1 => e + case other => other transform { + case expr: Expression if expr.semanticEquals(e) => + a.toAttribute + } + } allConstraints += EqualNullSafe(e, a.toAttribute) case _ => // Don't change. } diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/plans/ConstraintPropagationSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/plans/ConstraintPropagationSuite.scala index 5ad748b6113d6..22bd6f78cbd3f 100644 --- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/plans/ConstraintPropagationSuite.scala +++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/plans/ConstraintPropagationSuite.scala @@ -422,4 +422,12 @@ class ConstraintPropagationSuite extends SparkFunSuite with PlanTest { assert(aliasedRelation.analyze.constraints.isEmpty) } } + + test("SPARK-29606 Avoid generating too many constraints") { + val aliasedRelation = LocalRelation('a.int, 'b.int, 'c.int) + .select('a, 'b, 'c, ('a + 'b + 'c).as("abc")) + .select('a.as("a1"), 'b.as("b1"), 'c.as("c1"), 'abc.as("abc1")) + assert(aliasedRelation.analyze.isInstanceOf[Project]) + assert(aliasedRelation.analyze.asInstanceOf[Project].validConstraints.size === 5) + } }