diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/unresolved.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/unresolved.scala index 62000ac0efbb..581ffafa361c 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/unresolved.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/unresolved.scala @@ -255,7 +255,6 @@ case class UnresolvedFunction( override def children: Seq[Expression] = arguments ++ filter.toSeq override def dataType: DataType = throw new UnresolvedException(this, "dataType") - override def foldable: Boolean = throw new UnresolvedException(this, "foldable") override def nullable: Boolean = throw new UnresolvedException(this, "nullable") override lazy val resolved = false @@ -443,7 +442,6 @@ case class UnresolvedExtractValue(child: Expression, extraction: Expression) override def right: Expression = extraction override def dataType: DataType = throw new UnresolvedException(this, "dataType") - override def foldable: Boolean = throw new UnresolvedException(this, "foldable") override def nullable: Boolean = throw new UnresolvedException(this, "nullable") override lazy val resolved = false @@ -513,14 +511,12 @@ case class UnresolvedDeserializer(deserializer: Expression, inputAttributes: Seq override def child: Expression = deserializer override def dataType: DataType = throw new UnresolvedException(this, "dataType") - override def foldable: Boolean = throw new UnresolvedException(this, "foldable") override def nullable: Boolean = throw new UnresolvedException(this, "nullable") override lazy val resolved = false } case class GetColumnByOrdinal(ordinal: Int, dataType: DataType) extends LeafExpression with Unevaluable with NonSQLExpression { - override def foldable: Boolean = throw new UnresolvedException(this, "foldable") override def nullable: Boolean = throw new UnresolvedException(this, "nullable") override lazy val resolved = false } @@ -538,7 +534,6 @@ case class GetColumnByOrdinal(ordinal: Int, dataType: DataType) extends LeafExpr case class UnresolvedOrdinal(ordinal: Int) extends LeafExpression with Unevaluable with NonSQLExpression { override def dataType: DataType = throw new UnresolvedException(this, "dataType") - override def foldable: Boolean = throw new UnresolvedException(this, "foldable") override def nullable: Boolean = throw new UnresolvedException(this, "nullable") override lazy val resolved = false } diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Expression.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Expression.scala index 18cc648e57d7..ce4aa1c2b7c2 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Expression.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Expression.scala @@ -298,6 +298,9 @@ abstract class Expression extends TreeNode[Expression] { */ trait Unevaluable extends Expression { + /** Unevaluable is not foldable because we don't have an eval for it. */ + final override def foldable: Boolean = false + final override def eval(input: InternalRow = null): Any = throw new UnsupportedOperationException(s"Cannot evaluate expression: $this") @@ -318,7 +321,6 @@ trait Unevaluable extends Expression { */ trait RuntimeReplaceable extends UnaryExpression with Unevaluable { override def nullable: Boolean = child.nullable - override def foldable: Boolean = child.foldable override def dataType: DataType = child.dataType // As this expression gets replaced at optimization with its `child" expression, // two `RuntimeReplaceable` are considered to be semantically equal if their "child" expressions diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/SortOrder.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/SortOrder.scala index 536276b5cb29..54259e713acc 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/SortOrder.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/SortOrder.scala @@ -66,9 +66,6 @@ case class SortOrder( sameOrderExpressions: Set[Expression]) extends UnaryExpression with Unevaluable { - /** Sort order is not foldable because we don't have an eval for it. */ - override def foldable: Boolean = false - override def checkInputDataTypes(): TypeCheckResult = { if (RowOrdering.isOrderable(dataType)) { TypeCheckResult.TypeCheckSuccess diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/aggregate/interfaces.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/aggregate/interfaces.scala index 26367cc058bf..421b8ee2a25b 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/aggregate/interfaces.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/aggregate/interfaces.scala @@ -20,7 +20,7 @@ package org.apache.spark.sql.catalyst.expressions.aggregate import org.apache.spark.sql.catalyst.InternalRow import org.apache.spark.sql.catalyst.analysis.UnresolvedAttribute import org.apache.spark.sql.catalyst.expressions._ -import org.apache.spark.sql.catalyst.expressions.codegen.CodegenFallback +import org.apache.spark.sql.catalyst.expressions.codegen.{CodegenContext, CodegenFallback, ExprCode} import org.apache.spark.sql.types._ /** The mode of an [[AggregateFunction]]. */ @@ -133,7 +133,6 @@ case class AggregateExpression( override def children: Seq[Expression] = aggregateFunction +: filter.toSeq override def dataType: DataType = aggregateFunction.dataType - override def foldable: Boolean = false override def nullable: Boolean = aggregateFunction.nullable @transient @@ -374,8 +373,7 @@ abstract class ImperativeAggregate extends AggregateFunction with CodegenFallbac */ abstract class DeclarativeAggregate extends AggregateFunction - with Serializable - with Unevaluable { + with Serializable { /** * Expressions for initializing empty aggregation buffers. @@ -421,6 +419,12 @@ abstract class DeclarativeAggregate /** Represents this attribute at the input buffer side (the data value is read-only). */ def right: AttributeReference = inputAggBufferAttributes(aggBufferAttributes.indexOf(a)) } + + final override def eval(input: InternalRow = null): Any = + throw new UnsupportedOperationException(s"Cannot evaluate expression: $this") + + final override protected def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = + throw new UnsupportedOperationException(s"Cannot generate code for expression: $this") } diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/complexTypeCreator.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/complexTypeCreator.scala index 563ce7133a3d..36236c8e9c8f 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/complexTypeCreator.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/complexTypeCreator.scala @@ -301,7 +301,6 @@ case class MapFromArrays(left: Expression, right: Expression) */ case object NamePlaceholder extends LeafExpression with Unevaluable { override lazy val resolved: Boolean = false - override def foldable: Boolean = false override def nullable: Boolean = false override def dataType: DataType = StringType override def prettyName: String = "NamePlaceholder" diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/misc.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/misc.scala index 617ddcb69eab..a286a9c294f6 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/misc.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/misc.scala @@ -111,7 +111,6 @@ case class AssertTrue(child: Expression) extends UnaryExpression with ImplicitCa """) case class CurrentDatabase() extends LeafExpression with Unevaluable { override def dataType: DataType = StringType - override def foldable: Boolean = true override def nullable: Boolean = false override def prettyName: String = "current_database" } @@ -129,7 +128,6 @@ case class CurrentDatabase() extends LeafExpression with Unevaluable { since = "3.1.0") case class CurrentCatalog() extends LeafExpression with Unevaluable { override def dataType: DataType = StringType - override def foldable: Boolean = true override def nullable: Boolean = false override def prettyName: String = "current_catalog" } diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/predicates.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/predicates.scala index 03066fb34cf2..06a11f763f6c 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/predicates.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/predicates.scala @@ -327,7 +327,6 @@ case class InSubquery(values: Seq[Expression], query: ListQuery) override def children: Seq[Expression] = values :+ query override def nullable: Boolean = children.exists(_.nullable) - override def foldable: Boolean = children.forall(_.foldable) override def toString: String = s"$value IN ($query)" override def sql: String = s"(${value.sql} IN (${query.sql}))" } diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/windowExpressions.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/windowExpressions.scala index c8b643320735..e9e7b071a26f 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/windowExpressions.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/windowExpressions.scala @@ -50,7 +50,6 @@ case class WindowSpecDefinition( frameSpecification.isInstanceOf[SpecifiedWindowFrame] override def nullable: Boolean = true - override def foldable: Boolean = false override def dataType: DataType = throw new UnsupportedOperationException("dataType") override def checkInputDataTypes(): TypeCheckResult = { @@ -144,7 +143,6 @@ case object RangeFrame extends FrameType { sealed trait SpecialFrameBoundary extends Expression with Unevaluable { override def children: Seq[Expression] = Nil override def dataType: DataType = NullType - override def foldable: Boolean = false override def nullable: Boolean = false } @@ -168,7 +166,6 @@ case object CurrentRow extends SpecialFrameBoundary { sealed trait WindowFrame extends Expression with Unevaluable { override def children: Seq[Expression] = Nil override def dataType: DataType = throw new UnsupportedOperationException("dataType") - override def foldable: Boolean = false override def nullable: Boolean = false } @@ -275,7 +272,6 @@ case class UnresolvedWindowExpression( windowSpec: WindowSpecReference) extends UnaryExpression with Unevaluable { override def dataType: DataType = throw new UnresolvedException(this, "dataType") - override def foldable: Boolean = throw new UnresolvedException(this, "foldable") override def nullable: Boolean = throw new UnresolvedException(this, "nullable") override lazy val resolved = false } @@ -287,7 +283,6 @@ case class WindowExpression( override def children: Seq[Expression] = windowFunction :: windowSpec :: Nil override def dataType: DataType = windowFunction.dataType - override def foldable: Boolean = windowFunction.foldable override def nullable: Boolean = windowFunction.nullable override def toString: String = s"$windowFunction $windowSpec" @@ -370,8 +365,11 @@ abstract class OffsetWindowFunction * OffsetWindowFunction is executed, the input expression and the default expression. Even when * both the input and the default expression are foldable, the result is still not foldable due to * the frame. + * + * Note, the value of foldable is set to false in the trait Unevaluable + * + * override def foldable: Boolean = false */ - override def foldable: Boolean = false override def nullable: Boolean = default == null || default.nullable || input.nullable diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/v2Commands.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/v2Commands.scala index 70e03c23fd11..3b51761abde4 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/v2Commands.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/v2Commands.scala @@ -348,7 +348,6 @@ case class MergeIntoTable( sealed abstract class MergeAction extends Expression with Unevaluable { def condition: Option[Expression] - override def foldable: Boolean = false override def nullable: Boolean = false override def dataType: DataType = throw new UnresolvedException(this, "nullable") override def children: Seq[Expression] = condition.toSeq @@ -369,7 +368,6 @@ case class InsertAction( } case class Assignment(key: Expression, value: Expression) extends Expression with Unevaluable { - override def foldable: Boolean = false override def nullable: Boolean = false override def dataType: DataType = throw new UnresolvedException(this, "nullable") override def children: Seq[Expression] = key :: value :: Nil